如何防止自动增量跳过mysql数据库中的id号?
好吧,假设我有一个 mysql 数据库表,有两列,一列用于 id,另一列用于密码。如果我有三行数据,并且 id 值从 1 到 3,并且我删除第 3 行,然后创建另一行数据,我将在新创建的行上看到 id=4 而不是 id=3。我知道这与自动增量值有关,但我想知道是否可以在 php 文件中添加一些代码,该代码将自动重置所有 id 编号,以便您从 id=1 开始,直到最后一个 id 编号删除一行后增量为 1?
我的目标是创建一个表单,用户在其中输入密码,系统会将密码与数据库中的密码值进行匹配。如果存在匹配,则将删除具有匹配密码的行,并且将重新排序 ID 号列,以便不会跳过任何 ID 号。
更新:我正在通过将 1 到 4 之间的随机数设置为变量来制作旋转横幅广告系统,以便 php 文件将使用随机数变量检索从 id=1 到 id=4 的随机广告。如果随机数恰好是3并且id=3不存在,那么横幅广告行中就会出现间隙。如果有办法解决这种情况下的巨大差距,请告诉我。提前致谢
Okay, so let's say I have a mysql database table with two columns, one is for id and the other is for password. If I have three rows of data and the id values go from 1 to 3 and I delete row 3 and then create another row of data, I will see id=4 instead of id=3 on the newly created row. I know this has to do with the auto increment value but I was wondering if I can add some code in a php file that will automatically reset all the id numbers such that you start at id=1 and go up to the last id number in increments of 1 after a row has been deleted?
My goal is to create a form where the user enters a password and the system will match the password with a password value in the database. If there is a match, the row with the matched password will be deleted and the column of id numbers will be reordered such that no id numbers are skipped.
Update: I'm making a rotating banner ad system by setting a random number from 1 to 4 to a variable so that the php file will retrieve a random ad from id=1 to id=4 by using the random number variable. If the random number happens to be 3 and id=3 does not exist, there will be a gap in the row of banner ads. If there is a way to work around big gaps in this situation, please tell me. thanks in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
只需执行以下 SQL 查询:
...但这听起来是一个糟糕的主意,所以不要这样做。为什么主键的值如此重要?独特性要重要得多,而重置它会破坏这一点。
Just execute the following SQL query:
…but it sounds like a terrible idea, so don't do it. Why is the value of your primary key so important? Uniqueness is far more important, and reseting it undermines that.
您只能使用
重置为高于最高值数字的数字。如果你有1、2、3,并且你删除了2,你不能用它来填充2。如果你删除3,你可以用它来重新使用3(假设你没有放更高的东西)。这是你能做的最好的事情了。
You can only use
to reset to a number above the highest value number. If you have 1, 2, 3, and you delete 2, you cannot use this to fill 2. If you delete 3, you could use this to re-use 3 (assuming you haven't put anything higher). That is the best you can do.
然而运行这段代码并不是最好的主意。如果您依赖没有间隙的色谱柱,则您的应用程序有问题。您是否想计算用户数量?如果是这样使用 COUNT(id)?您是否正在尝试处理其他表?如果是这样,请使用外键。
如果您执意要以错误的方式执行此操作,您可以尝试寻找最低的可用数字并自行递增。但请记住涉及的竞争条件。
另外,请记住,如果更改数据库中的实际数字,您将需要更改其他表和代码中对其的所有引用。
However running this code is not the best idea. There is something wrong with your application if you depend on the column having no gaps. Are you trying to count the number of users? if so use COUNT(id)? Are you trying to deal with other tables? If so use a foreign key.
If you are dead set on doing this the Wrong Way you could try to look for the lowest free number and do the incrementing on your own. Keep in mind the race conditions involves however.
Also, keep in mind that if you change the actual numbers in the database you will need to change all references to it in other tables and in your code.
好吧,实际上您可以在插入语句中指定您希望记录具有的 id 号,例如:
如果没有主键冲突(数据库中没有 id=1 的记录),则 MySQL会很高兴地执行它。
ALTER TABLE 'tbl' AUTO_INCRMENT=#
也可以工作,这意味着您不必跟踪计数器。不过,当您思考这个问题时,您可能想阅读 自然键与代理键。让你的 id # 特别重要的想法有点不寻常,可能是设计有问题的迹象。
Well, you can actually just specify the id number you'd like a record to have as part of your insert statement, for example:
And if there's not a primary key collision (no record in the database with id=1), then MySQL will happily execute it.
The
ALTER TABLE 'tbl' AUTO_INCREMENT=#
thing also works, and means you don't have to keep track of the counter.While you're thinking about this, though, you might want to read some of the discussion on natural vs surrogate keys. The idea of having your id # be specifically important is a bit unusual and might be a sign of a troubled design.
您可以通过以下方式做到这一点:
UPDATE< /code> 来减少所有大于你刚刚删除的 id(再次,通过事务——不要忘记外键必须是 ON UPDATE CASCADE!)
但是它引出了一个问题:你为什么想要这个?值得这么麻烦吗?
几乎可以肯定的是,无论你的目标是什么,你都可以在没有这种巫术的情况下实现。
更新(针对评论):
要选择随机行数,您可以在 MySQL 中
选择 5 个随机的、有保证的现有横幅 ID。
警告:有相当多的人认为 ORDER BY RAND() 性能不佳。然而,恕我直言,将所有案例都放在同一个篮子里是不太正确的。如果表中的行数是可以管理的(我认为低于 10K 的行数不会太多),那么 ORDER BY RAND() 提供了一个非常好的、简洁的解决方案。另外,文档本身建议采用这种方法:
You could do that by:
UPDATE
to decrement all ids greater than the one you just deleted (again, with a transaction -- don't forget that foreign keys must be ON UPDATE CASCADE!)But it begs the question: why do you want this? is it going to be worth the trouble?
It's almost certain that you can achieve whatever your goal is without such witchery.
Update (to address comment):
To select a random number of rows, you can do e.g. in MySQL
to select 5 random, guaranteed existing banner ids.
A word of caution: there are quite a few people who view
ORDER BY RAND()
as a bad performance hog. However, it is IMHO not quite right to put every case in the same basket. If the number of rows in the table is manageable (I would consider anything below 10K to be not that many) thenORDER BY RAND()
provides a very nice and succint solution. Also, the documentation itself suggests this approach: