好的我是MySQL的新手,所以请原谅任何愚蠢的问题,但我对我创建的简单数据库表有疑问。
请参阅:
我已将其设置为每个新条目都自动递增id
但是如果我要删除第三行,则存在间隙。我听说有一种方法可以在删除上一个条目时级联其他数字。我看了但是找不到任何可以帮助我在phpMyAdmin中更改它而不重新创建表的东西。
我该怎么做?
答案 0 :(得分:3)
这个问题每隔一段时间就出现一次,这就是auto_increment
给你序列号的错误,你可以使用序列号。你不能。
主键的唯一目的是唯一标识行。增量整数非常适合这个角色,它很容易在C / C ++ MySQL代码中实现,而且工作速度非常快。
但这就是它的全部。你没有得到漂亮的顺序编号功能。你不能将它用于你想要的东西,因为你所谓的是间隙。
不,你不会让MySQL填补空白。它很糟糕而且很危险,它会产生你甚至没想过的问题。
一句话是,永远不会依赖 auto_increment
重用“浪费”数字。
原因如下:
InnoDB,默认的MySQL引擎,在内部使用主键来物理组织硬盘上的记录。它依赖于每个 next id大于之前的功能。我不会详细介绍,但关键的想法是索引和数据写在同一页面上。这使得InnoDB在进行主键查找(SELECT col FROM table WHERE id = 1000000
类型的查询)时非常快。
现在,当你“重用”有间隙的密钥时会发生什么 - 想象一下这种情况:你有100万条记录。没有数字损失。 您删除记录500 000。 之后,您添加新记录,并使用您的逻辑 - 您需要“重复使用”数字500 000.所以你这样做。 但是,InnoDB预计每一条记录都会更大。因此,为了符合您的需求,它必须重新平衡它所写的内容。它必须从创纪录的500 000开始。现在你有50万条正在重组的记录,这意味着你有50万次检查和写入。这完全杀死了你的表现。假设你有一个机械硬盘。它能够达到每秒200-300次输入输出操作(IOPS)。如果每个重组记录需要1个I / O,重组50万个I / O需要20-30分钟。现在您需要30分钟才能完成插入。
另一个比性能问题严重得多的问题是并发和隔离问题。 人们不理解的是MySQL(和其他关系数据库)解决了并发问题,或者你是否会 - 同时访问的问题或“当两个用户同时编写时会发生什么”的问题。 MySQL负责这一点,甚至更多。而“浪费”数字的功能实际上就是它的实现。每个事务在某一点依赖于主键。甚至在您提交事务之前,已经为其分配了auto_increment。因此,即使事务失败或未提交,auto_increment也会“浪费”。这实际上是可取的行为。
我绝对没有列出所有的缺点,只有两个我能想到的(我也没有详细描述它们,因为时间不够但原则确实适用)。
结论是 - 不要“重用”浪费的auto_increment数字,不要听那些告诉你如何做的人,不要以为你的项目不会出现我上面列出的问题。如果你这样做,准备遇到你永远不会想到的问题。