我一直在为一个项目使用InnoDB,并依赖于auto_increment。对于大多数表来说这不是问题,但对于删除表,这可能是一个问题:
AUTO_INCREMENT Handling in InnoDB
特别是这部分:
名为ai_col的AUTO_INCREMENT列:服务器启动后,对于第一次插入表t,InnoDB执行相当于此语句: SELECT MAX(ai_col)FROM t FOR UPDATE; InnoDB将语句检索的值加1,并将其分配给列和表的自动递增计数器。
这是一个问题,因为虽然它确保在表中,键是唯一的,但是这个表的外键不再是唯一的。
mysql服务器经常/不应该经常重启,但这是破坏。有没有简单的方法呢?
答案 0 :(得分:3)
如果您有外键约束,当表B引用该行时,如何从表A中删除一行?这对我来说似乎是个错误。
无论如何,您可以通过在应用程序启动时重置偏移来避免重复使用自动增量值。查询引用表A的所有表中的最大值,然后更改高于该最大值的表,例如,如果最大值为989,请使用:
alter table TableA auto_increment=999;
还要注意不同的MySQL引擎具有不同的自动增量行为。这个技巧适用于InnoDB。
答案 1 :(得分:1)
使用带有“SET NULL”的外键约束进行更新和删除。
答案 2 :(得分:1)
所以你有两张桌子:
表A
A_ID [PK]
和
表B
B_ID [PK]
A_ID [FK,TableA.A_ID]
在TableB中,A_ID的值不是唯一的?或者TableB.A_ID中是否有值不在TableA.A_ID?
中如果您需要TableB.A_ID的值是唯一的,那么您需要为该列添加UNIQUE约束。
或者我还缺少什么?
答案 3 :(得分:1)
创建另一个表,其中的列会记住上次创建的ID。这样,您就不必处理将其作为外键的新表中的最大值。
答案 4 :(得分:1)
http://docs.oracle.com/cd/E17952_01/refman-5.1-en/innodb-auto-increment-handling.html InnoDB使用以下算法初始化包含名为ai_col的AUTO_INCREMENT列的表t的自动递增计数器:在服务器启动后,对于第一次插入表t,InnoDB执行此语句的等效项: SELECT MAX(ai_col)FROM t FOR UPDATE; InnoDB递增语句检索的值,并将其分配给列和表的自动递增计数器。默认情况下,该值递增1。 auto_increment_increment配置设置可以覆盖此默认值。
和 http://docs.oracle.com/cd/E17952_01/refman-5.1-en/alter-table.html
您无法将计数器重置为小于或等于任何已使用过的值。
这就是为什么alter table不起作用的原因。我认为唯一的选择是消除数据并在具有新id的新表中重写它。 在我的情况下,表是logfile,所以我只是做了:
RENAME TABLE SystemEvents To SystemEvents_old; CREATE TABLE SystemEvents LIKE SystemEvents_old;