揪出那个无主键的表

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 在 MySQL 中,建表时一般都会要求有主键。若要求不规范难免会出现几张无主键的表,本篇文章让我们一起揪出那个无主键的表。

1.无主键表的危害


以 InnoDB 表为例,我们都知道,在 InnoDB 中,表都是根据主键顺序以索引的形式存放的,这种存储方式的表称为索引组织表。一张 InnoDB 表必须有一个聚簇索引,当有主键时,会以主键作为聚簇索引;如果没有显式定义主键,InnoDB 会选择一个唯一的非空索引代替。如果没有这样的索引,则 MySQL 自动为 InnoDB 表生成一个隐含字段作为主键。


也就是说,最好我们可以显式定义主键,那么无主键表可能会产生哪些危害呢?首先没有主键就意味着无法用到主键索引,可能影响查询效率。其次是对维护不友好,比如想升级为 MGR 集群或使用某些开源工具时,都会要求表要有主键。还有一点,对于无主键的表批量更新或删除,极易引起很长时间的主从延迟。


这里也顺便提下,当主库对于无主键表(特别是既无主键又无索引的表)大量更新或删除时,从库会发生极大的主从延迟,甚至会一直卡着执行不下去,别问我怎么知道的,前段时间遇到过。发生这种情况的现象是从库延迟不断增大,且正在执行的主库 binlog pos 位点一直不变,这个时候需要去主库解析下从库卡着的 binlog pos 位点,发现是对某个无主键表的操作,这时若想从库尽快赶上,可以手动设置下忽略该表的同步,处理 SQL 如下:

# 假设检查发现是 testtb 表导致了主从延迟 可以再从库忽略该表的同步
mysql> STOP SLAVE SQL_THREAD;
Query OK, 0 rows affected (0.00 sec)
mysql> CHANGE REPLICATION FILTER REPLICATE_IGNORE_TABLE = (db.testtb);
Query OK, 0 rows affected (0.00 sec)
mysql> START SLAVE SQL_THREAD;
Query OK, 0 rows affected (0.01 sec)

忽略掉该表的同步后,从库很快就会追上主库了。后续可以为该表增加主键,然后再手动同步下并解除忽略即可。


2.找到无主键的表


言归正传,当我们的数据库实例中有好多好多张表时,又应该如何查找是否有无主键的表呢?总不能一个个找吧,聪明的你可能想到了,可以从 MySQL 自带的系统表中查找,因为我们的所有建表信息都存储在系统库 information_schema 中。下面 SQL 可以查找出无主键的表:

# 查找某个库中无主键的表(有唯一键无主键的表也会被查出)
SELECT
    t1.table_schema,
    t1.table_name
FROM
    information_schema.TABLES t1
LEFT OUTER JOIN information_schema.TABLE_CONSTRAINTS t2 ON t1.table_schema = t2.TABLE_SCHEMA
AND t1.table_name = t2.TABLE_NAME
AND t2.CONSTRAINT_NAME IN ('PRIMARY')
WHERE
    t2.table_name IS NULL
AND t1.table_type = 'BASE TABLE'
AND t1.TABLE_SCHEMA = 'testdb';
# 查找整个实例中无主键的表
SELECT
    t1.table_schema,
    t1.table_name
FROM
    information_schema.TABLES t1
LEFT OUTER JOIN information_schema.TABLE_CONSTRAINTS t2 ON t1.table_schema = t2.TABLE_SCHEMA
AND t1.table_name = t2.TABLE_NAME
AND t2.CONSTRAINT_NAME IN ('PRIMARY')
WHERE
    t2.table_name IS NULL
AND t1.table_type = 'BASE TABLE'
AND t1.TABLE_SCHEMA NOT IN (
    'information_schema',
    'performance_schema',
    'mysql',
    'sys'
);

找到了无主键的表,下一步就是为表新增主键了,无论你使用自增 id ,uuid ,或其他算法生成的主键字段,都建议为表新增主键。以自增 id 为例,我们可以为无主键的表这样新增主键:

# 为表 tb1 新增自增ID字段作为主键
ALTER TABLE tb1 ADD COLUMN inc_id INT UNSIGNED NOT NULL auto_increment COMMENT '自增主键' PRIMARY KEY FIRST;
# 查找到的无主键表 拼接出新增主键的SQL
SELECT
CONCAT('ALTER TABLE ',t1.table_schema,'.',t1.table_name,' ADD COLUMN inc_id INT UNSIGNED NOT NULL auto_increment COMMENT \'自增主键\' PRIMARY KEY FIRST;')
FROM
    information_schema.TABLES t1
LEFT OUTER JOIN information_schema.TABLE_CONSTRAINTS t2 ON t1.table_schema = t2.TABLE_SCHEMA
AND t1.table_name = t2.TABLE_NAME
AND t2.CONSTRAINT_NAME IN ('PRIMARY')
WHERE
    t2.table_name IS NULL
AND t1.table_type = 'BASE TABLE'
AND t1.TABLE_SCHEMA NOT IN (
    'information_schema',
    'performance_schema',
    'mysql',
    'sys'
) ;


总结:


本篇文章主要介绍了无主键表可能会产生的危害及如何查找是否存在无主键的表。文中的一些 SQL 都是根据系统表来查找的,各位可以保存下到自己的环境试试看哦。MySQL 中的表还是强制要求有主键才好,人要有主见,表也要有主键!

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
数据建模 Java 数据库
PowerDesigner使用之为表中字段添加索引
PowerDesigner使用之为表中字段添加索引
388 1
|
存储 SQL Oracle
Oracle优化避免索引失效
Oracle优化避免索引失效
357 0
|
存储 数据库 索引
【面试官挖坑】聚集索引会隐式的自动为表添加一个主键索引那你是不是就可以不设置主键索引了?
【面试官挖坑】聚集索引会隐式的自动为表添加一个主键索引那你是不是就可以不设置主键索引了?
|
关系型数据库 MySQL
MySQL查询之 如何删除主键和添加主键等修饰词
MySQL查询之 如何删除主键和添加主键等修饰词
137 0
|
关系型数据库 MySQL 数据库
【MySQL速通篇001】MySQL主键,自增列,各类索引,外键及变种,分组,连表,数据行操作等知识点 1
【MySQL速通篇001】MySQL主键,自增列,各类索引,外键及变种,分组,连表,数据行操作等知识点
330 0
|
关系型数据库 MySQL 数据库
【MySQL速通篇001】MySQL主键,自增列,各类索引,外键及变种,分组,连表,数据行操作等知识点 2
【MySQL速通篇001】MySQL主键,自增列,各类索引,外键及变种,分组,连表,数据行操作等知识点
149 0
|
存储 NoSQL 关系型数据库
三十四、外键约束
三十四、外键约束
144 0
三十四、外键约束
|
Oracle 关系型数据库 索引
Oracle优化之表连接方式
Oracle优化之表连接方式在Oracle数据库中,两个表之间的表连接方法有排序合并连接、嵌套循环连接、哈希连接和笛卡尔连接四种 1.排序合并连接(sort merge join)   排序合并连接是一种两表在做表连接时用排序(SORT)操作和合并(MERGE)操作来得到连接结果集的表连接方法  ...
1350 0