简体   繁体   English

InnoDB 中的 Auto_increment 值?

[英]Auto_increment values in InnoDB?

I've been using InnoDB for a project, and relying on auto_increment.我一直在一个项目中使用 InnoDB,并依赖于 auto_increment。 This is not a problem for most of the tables, but for tables with deletion, this might be an issue:对于大多数表来说这不是问题,但对于删除的表,这可能是一个问题:

AUTO_INCREMENT Handling in InnoDB InnoDB 中的 AUTO_INCREMENT 处理

particularly this part:特别是这部分:

AUTO_INCREMENT column named ai_col: After a server startup, for the first insert into a table t, InnoDB executes the equivalent of this statement: SELECT MAX(ai_col) FROM t FOR UPDATE; 名为 ai_col 的 AUTO_INCREMENT 列:在服务器启动后,对于第一次插入表 t,InnoDB 执行此语句的等效语句:SELECT MAX(ai_col) FROM t FOR UPDATE; InnoDB increments by one the value retrieved by the statement and assigns it to the column and to the auto-increment counter for the table. InnoDB 将语句检索到的值递增 1,并将其分配给列和表的自动递增计数器。

This is a problem because while it ensures that within the table, the key is unique, there are foreign keys to this table where those keys are no longer unique.这是一个问题,因为虽然它确保在表内键是唯一的,但该表存在外键,这些键不再是唯一的。

The mysql server does/should not restart often, but this is breaking. mysql 服务器确实/不应该经常重启,但这是破坏性的。 Are there any easy ways around this?有什么简单的方法可以解决这个问题吗?

If you have a foreign key constraint, how can you delete a row from table A when table B references that row?如果您有外键约束,当表 B 引用该行时,如何从表 A 中删除该行? That seems like an error to me.这对我来说似乎是一个错误。

Regardless, you can avoid the reuse of auto-increment values by resetting the offset when your application starts back up.无论如何,您可以通过在应用程序启动备份时重置偏移量来避免重复使用自动增量值。 Query for the maximum in all the tables that reference table A, then alter the table above that maximum, eg if the max is 989, use this:查询引用表 A 的所有表中的最大值,然后更改该最大值之上的表,例如,如果最大值为 989,请使用以下命令:

alter table TableA auto_increment=999;

Also beware that different MySQL engines have different auto-increment behavior.还要注意不同的 MySQL 引擎有不同的自增行为。 This trick works for InnoDB.这个技巧适用于 InnoDB。

使用带有“SET NULL”的外键约束进行更新和删除。

So you have two tables:所以你有两个表:

TableA表A

A_ID [PK] A_ID [PK]

and

TableB表B

B_ID [PK] B_ID [PK]

A_ID [FK, TableA.A_ID] A_ID [FK, TableA.A_ID]

And in TableB, the value of A_ID is not unique?而在TableB中,A_ID的值不是唯一的? Or is there a value in TableB.A_ID that is not in TableA.A_ID?或者 TableB.A_ID 中是否有一个不在 TableA.A_ID 中的值?

If you need the value of TableB.A_ID to be unique, then you need to add a UNIQUE constraint to that column.如果您需要 TableB.A_ID 的值是唯一的,那么您需要向该列添加一个 UNIQUE 约束。

Or am I still missing something?或者我还缺少什么?

I checked.我检查了。 alter table TableA auto_increment=1; alter table TableA auto_increment=1; does NOT work.不起作用。 And the reason I found in two documents我在两个文件中找到的原因

http://docs.oracle.com/cd/E17952_01/refman-5.1-en/innodb-auto-increment-handling.html InnoDB uses the following algorithm to initialize the auto-increment counter for a table t that contains an AUTO_INCREMENT column named ai_col: After a server startup, for the first insert into a table t, InnoDB executes the equivalent of this statement: SELECT MAX(ai_col) FROM t FOR UPDATE; http://docs.oracle.com/cd/E17952_01/refman-5.1-en/innodb-auto-increment-handling.html InnoDB 使用以下算法来初始化包含 AUTO_INCREMENT 列的表 t 的自增计数器命名 ai_col:服务器启动后,对于第一次插入表 t,InnoDB 执行与此语句等效的语句:SELECT MAX(ai_col) FROM t FOR UPDATE; InnoDB increments the value retrieved by the statement and assigns it to the column and to the auto-increment counter for the table. InnoDB 递增语句检索到的值,并将其分配给列和表的自动递增计数器。 By default, the value is incremented by one.默认情况下,该值递增 1。 This default can be overridden by the auto_increment_increment configuration setting.这个默认值可以被 auto_increment_increment 配置设置覆盖。

and http://docs.oracle.com/cd/E17952_01/refman-5.1-en/alter-table.htmlhttp://docs.oracle.com/cd/E17952_01/refman-5.1-en/alter-table.html

You cannot reset the counter to a value less than or equal to any that have already been used.您不能将计数器重置为小于或等于任何已使用值的值。

This is the reason why alter table will not work.这就是alter table 不起作用的原因。 I think that only option is to wipe out data and rewrite it in a new table with new id.我认为唯一的选择是清除数据并在具有新 ID 的新表中重写它。 In my case table was logfile , so I just did:在我的案例表是 logfile ,所以我只是做了:

RENAME TABLE SystemEvents To SystemEvents_old;将表 SystemEvents 重命名为 SystemEvents_old; CREATE TABLE SystemEvents LIKE SystemEvents_old; CREATE TABLE SystemEvents LIKE SystemEvents_old;

Create another table with a column that remembers the last created Id.使用记住上次创建的 ID 的列创建另一个表。 This way you don't have to take care of the max values in new tables that have this as foreign key.这样您就不必处理将此作为外键的新表中的最大值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM