如何找到 MySQL 记录集中的 ID 间隙?
这里的问题与我遇到的另一个问题有关...
我有数百万条记录,并且每条记录的ID都是自动递增的,不幸的是有时生成的ID有时会被丢弃,因此之间存在很多差距身份证。
我想找到缺口,重新利用那些被废弃的id。
在 MySQL 中执行此操作的有效方法是什么?
The issue here is related to another question I had...
I have millions of records, and the ID of each of those records is auto-incremented, unfortunately sometimes the ID that is generated is sometimes thrown away so there are many many gaps between IDs.
I want to find the gaps, and re-use the ids that were abandoned.
What's an efficient way to do this in MySQL?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
首先,您想通过重用跳过的值来获得什么优势?普通的
INT UNSIGNED
最多可以算到 4,294,967,295。对于“数百万条记录”,您的数据库在用完有效 ID 之前必须增长一千倍。 (然后使用 BIGINT UNSIGNED 将使您的值增加到 18,446,744,073,709,551,615。)尝试回收 MySQL 跳过的值可能会花费您大量的时间来尝试补偿那些实际上没有的值。首先打扰MySQL。
话虽如此,您可以通过以下方式查找丢失的 ID:
这将仅查找每个序列中的第一个 丢失的数字(例如,如果您有
{1, 2, 3, 8, 10 }
它会找到{4,9}
),但它可能会很高效,当然,一旦您填写了 ID,您就可以随时再次运行它。First of all, what advantage are you trying to get by reusing the skipped values? An ordinary
INT UNSIGNED
will let you count up to 4,294,967,295. With "millions of records" your database would have to grow a thousand times over before running out of valid IDs. (And then using aBIGINT UNSIGNED
will bump you up to 18,446,744,073,709,551,615 values.)Trying to recycle values MySQL has skipped is likely to use up a lot of your time trying to compensate for something that really doesn't bother MySQL in the first place.
With that said, you can find missing IDs with something like:
This will find only the first missing number in each sequence (e.g., if you have
{1, 2, 3, 8, 10}
it will find{4,9}
) but it's likely to be efficient, and of course once you've filled in an ID you can always run it again.以下将为 mytab 中整数字段“n”中的每个间隙返回一行:
如果您想要连续链而不是间隙,那么最终选择应该是:
The following will return a row for each gap in the integer field "n" in mytab:
If instead of the gaps you want the contiguous chains then the final select should be:
如果您需要将第一个元素包含为 1,则此解决方案更好:
This solution is better, in case you need to include the first element as 1:
如果您使用的是
MariaDB
,您有一个更快的选项文档:https ://mariadb.com/kb/en/mariadb/sequence/
If you are using an
MariaDB
you have a faster optiondocs: https://mariadb.com/kb/en/mariadb/sequence/