如何处理MySQL中auto_increment ID列的碎片
我有一个带有 auto_increment 字段的表,有时行会被删除,因此 auto_increment 会留下间隙。有没有办法避免这种情况,或者如果没有,至少如何编写一个 SQL 查询来:
- 将
auto_increment
值更改为 max(当前值) + 1 - 返回新的
auto_increment
值?
我知道如何编写 1 和 2 部分,但是我可以将它们放在同一个查询中吗?
如果不可能:
如何“选择”(返回)auto_increment
值或auto_increment
值+ 1?
I have a table with an auto_increment field and sometimes rows get deleted so auto_increment leaves gaps. Is there any way to avoid this or if not, at the very least, how to write an SQL query that:
- Alters the
auto_increment
value to be the max(current value) + 1 - Return the new
auto_increment
value?
I know how to write part 1 and 2 but can I put them in the same query?
If that is not possible:
How do I "select" (return) the auto_increment
value or auto_increment
value + 1?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
重新编号会造成混乱。现有报告将引用记录 99,但如果系统重新编号,它可能会将该记录重新编号为 98,现在所有报告(和填充的 UI)都是错误的。一旦分配了唯一的 ID,它就必须保持固定。
将 ID 字段用于除简单唯一编号之外的任何内容都会出现问题。 “无间隙”的要求与能够删除的要求根本不一致。也许您可以将记录标记为已删除,而不是删除它们。那么就真的没有间隙了。假设您正在生成编号发票:您将拥有带有该编号的零值取消发票,而不是将其删除。
Renumbering will cause confusion. Existing reports will refer to record 99, and yet if the system renumbers it may renumber that record to 98, now all reports (and populated UIs) are wrong. Once you allocate a unique ID it's got to stay fixed.
Using ID fields for anything other than simple unique numbering is going to be problematic. Having a requirement for "no gaps" is simply inconsistent with the requirement to be able to delete. Perhaps you could mark records as deleted rather than delete them. Then there are truly no gaps. Say you are producing numbered invoices: you would have a zero value cancelled invoice with that number rather than delete it.
即使在 autoinc 表中,也有一种方法可以手动插入 id。您所要做的就是识别丢失的 ID。
但是,不要这样做。如果您的数据库是关系数据库,这可能会非常危险。删除的 id 可能已被其他地方使用。删除后,它不会造成太大问题,也许会孤立一条记录。如果替换,它将带来一个巨大的问题,因为会出现错误的关系。
考虑一下我有一个汽车表和一个人员表
并且有一些简单的数据
,现在我删除了约翰。
如果我在表中添加一个新人吉姆,并且他获得了一个填补空白的 id,那么他最终将获得 id 3
,并且根据关系,他将成为法拉利的所有者。
There is a way to manually insert the id even in an autoinc table. All you would have to do is identify the missing id.
However, don't do this. It can be very dangerous if your database is relational. It is possible that the deleted id was used elsewhere. When removed, it would not present much of an issue, perhaps it would orphan a record. If replaced, it would present a huge issue because the wrong relation would be present.
Consider that I have a table of cars and a table of people
And that there is some simple data
and now I delete person John.
If I added a new person, Jim, into the table, and he got an id which filled the gap, then he would end up getting id 3
and by relation, would be the owner of the Ferrari.
我总体上同意本页(以及重复问题)上的智者的建议,建议不要重复使用自动增量ID。这是很好的建议,但我不认为由我们来决定提出问题的正确或错误,让我们假设开发人员知道他们想做什么以及为什么。
答案是,正如 Travis J 所提到的,您可以通过在插入语句中包含 id 列并分配所需的特定值来重用自动增量 id。
这里有一点需要注意:MySQL 本身(至少 5.6 InnoDB)将在以下情况下重用自动增量 ID:
插入的行将有一个 id,计算为 max(id)+1,它不会从已删除的 id 继续。
I generally agree with the wise people on this page (and duplicate questions) advising against reusing auto-incremented id's. It is good advice, but I don't think it's up to us to decide the rights or wrongs of asking the question, let's assume the developer knows what they want to do and why.
The answer is, as mentioned by Travis J, you can reuse an auto-increment id by including the id column in an insert statement and assigning the specific value you want.
Here is a point to put a spanner in the works: MySQL itself (at least 5.6 InnoDB) will reuse an auto-increment ID in the following circumstance:
The inserted row will have an id calculated as max(id)+1, it does not continue from the id that was deleted.
正如 djna 在她/他的回答中所说,以这种方式更改数据库表不是一个好的做法,如果您选择了正确的方案和数据类型,也没有必要这样做。顺便说一句,根据你的问题的一部分:
INSERT
查询而导致的,>id
列只是一个计数器,与数据库中的任何其他列无关,这可能是您(或任何其他正在寻找此类内容的人)正在寻找的内容:
解决方案
id
列auto_increment
再次添加它,但如果您只想将
auto_increment
重置为第一个可用值:As djna said in her/his answer, it's not a good practice to alter database tables in such a way, also there is no need to that if you have been choosing the right scheme and data types. By the way according to part od your question:
INSERT
queriesid
column is just a counter and has no relation to any other column in your database, this may be the thing you ( or any other person looking for such a thing ) are looking for:
SOLUTION
id
columnauto_increment
onBut if you just want to reset the
auto_increment
to the first available value:不确定这是否有帮助,但在 SQL Server 中,您可以重新设置身份字段。 mySql 中似乎有一个 ALTER TABLE 语句来实现这一点。例如,将id设置为继续在59446。
我认为您应该能够组合查询来获取auto_increment字段的最大值,然后使用alter table根据需要进行更新。
not sure if this will help, but in sql server you can reseed the identity fields. It seems there's an ALTER TABLE statement in mySql to acheive this. Eg to set the id to continue at 59446.
I'm thinking you should be able to combine a query to get the largest value of auto_increment field, and then use the alter table to update as needed.