
主键:表中经常有一个列或多列的组合,其值能唯一地标识表中的每一行。这样的一列或多列称为表的主键,通过它可强制表的实体完整性。当创建或更改表时可通过定义 PRIMARY KEY 约束来创建主键。一个表只能有一个 PRIMARY KEY 约束,而且 PRIMARY KEY 约束中的列不能接受空值。由于 PRIMARY KEY 约束确保唯一数据,所以经常用来定义标识列。
作用:
1)保证实体的完整性
2)加快数据库的 *** 作速度
3) 在表中添加新记录时,ACCESS会自动检查新记录的主键值,不允许该值与其他记录的主键值重复。
4) ACCESS自动按主键值的顺序显示表中的记录。如果没有定义主键,则按输入记录的顺序显示表中的记录。
Mysql主从同步延迟发生现象:
pos一直保持不变,并且behind一直在增加,
备库执行:
SQL thread State列状态如下:
代表 线程已经从中继日志读取一个事件,可以对事件进行处理了。
查看binlog:
查看表结构发现没有主键和索引。
延迟发生原因:
首先mysql主从是基于行的复制。
举例解释下什么是基于行的复制,假设主库执行以下sql删除了表A中的100条数据:
这时mysql会把这个SQL按照每条记录,拆分成100条delete SQL在备库上执行,mysql这么做的目的也是最大程度的保证同步数据的可靠性。
但是可靠性的提升伴随而来的便是日志量的增多,同步过程会占用大量带宽。
其次,该表即无主键,也没有索引。
假设还是以上对A表的删除 *** 作,拆成的100条delete SQL传递并且在备库执行,因为表即无主键,也没有索引,所以每执行一次都要做全表扫描才能定位到要删除的那一条数据,可想而知同步效率会低很多。
解决方案:
1 表设计时就要有主键;
2 如果延迟已经发生,并且表不是特别大的情况下,在备库上为该表创建索引或是主键。
MySQL数据表使用InnoDB作为存储引擎的时候,数据结构就是使用B+树,而数据本身存储在主键索引上,也就是通常所说的聚簇索引,也就是每个表都需要有个聚簇索引树,但是,在建表的时候却发现可以不用指定主键,那么MySQL对于没有指定主键的表示如何处理的呢?
对于InnoDB,可以简单地把所有数据视为索引,每一个索引都对应一个B+数,而主键对应的索引就是聚簇索引,表的所有数据都存储在聚簇索引上,而除了聚簇索引的普通索引存储的只是主键的引用,所以,查询的时候对于普通索引需要进行 回表 才能取到具体数据。
既然InnoDB对数据的存储必须依赖于主键,那么对于没有创建主键的表,该怎么办?
InnoDB对聚簇索引处理如下:
很明显,缺少主键的表,InnoDB会内置一列用于聚簇索引来组织数据。而没有建立主键的话就没法通过主键来进行索引,查询的时候都是全表扫描,小数据量没问题,大数据量就会出现性能问题。
但是,问题真的只是查询影响吗?不是的,对于生成的ROW_ID,其自增的实现来源于一个全局的序列,而所以有ROW_ID的表共享该序列,这也意味着插入的时候生成需要共享一个序列,那么高并发插入的时候为了保持唯一性就避免不了锁的竞争,进而影响性能。
既然知道InnoDB对数据的存储和处理都是基于聚簇索引的,那么,在建表时候要注意主键的重要性,为每个表都设置一个主键,如果没有合适的字段来作为主键,可以设置一个业务无关的的代理主键,可以是自增ID,也可以是UUID(建议使用自增ID,性能较好)。
在理解InnoDB的数据结构之后自然而然就会知道主键的重要性,在建表的时候也不会忘记设置主键,无论表设计有无合适的唯一字段,都需要设置一个主键,提高性能的同时也是一种好的习惯,对于后续的拓展以及表之间关联都有一定的拓展性。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)