作者回复: 👍 这是一个典型的场景
作者回复: 1. 是的
2. 我觉得最初的一个原因是,由于以前(8.0版本前)自增主键值是不持久化的,只放在内存里面。每次重启后,重新打开表时,需要计算“自增字段里面的最大值”,然后加1,作为当前的autoincrement的值。
如果没有索引,算这个值就要做全表扫描,性能可能很差,影响访问表的速度。
好问题。不过这个只是我个人猜测,也可能还有别的原因。😆
作者回复: 好问题,不会
因为binlog在记录这种带自增值的语句之前,会在前面多一句,用于指定“接下来这个语句要需要的 自增ID值是多少”,而这个值,是在主库上这一行插入成功后对应的自增值,所以是一致的
作者回复: “(时间+业务+机器+序列,bigint类型,实际长度有17位,其中序列保存在内存中,每次递增,主键值不连续)。” ----bigint就是8位,这个你需要确定一下。如果是8位的还好,如果是17位的字符串,就比较耗费空间;
(1)如果“序列”是递增的,还是不能直接用来体现业务逻辑吧? 创建有业务意义的字段索引估计还是省不了的 ?
(2)mysql确实做不到“插入之前就先算好接下来的id是多少”,一般都是insert执行完成后,再执行select last_insert_id
(3) 先insert a再update b再update a,确实看上去比较奇怪,不过感觉这个逻辑应该是可以优化的,不应该作为“主键选择”的一个依据。你可否脱敏一下,把模拟的表结构和业务逻辑说下,看看是不是可以优化的。
总之,按照你说的“时间+业务+机器+序列”这种模式,有点像用uuid,主要的问题还是,如果这个表的索引多,占用的空间比较大
作者回复: 👍
作者回复: 👍 大势所趋😆
作者回复: 是说自增主键没指定?
两个语句分别去申请自增主键,申请到的值是不一样的,所以并不冲突
作者回复: 全局的
作者回复: innodb_autoinc_lock_mode = 2的时候就要binlog_format = row才好
作者回复: 👍
作者回复: 是的,我手残了。。
多谢指出,发起勘误了哈