简体   繁体   English

如何防止自动增量跳过mysql数据库中的id号?

[英]how to prevent auto increment from skipping id numbers in a mysql database?

Okay, so let's say I have a mysql database table with two columns, one is for id and the other is for password. 好的,我们假设我有一个包含两列的mysql数据库表,一个用于id,另一个用于密码。 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. 如果我有三行数据并且id值从1到3并且我删除第3行然后创建另一行数据,我将在新创建的行上看到id = 4而不是id = 3。 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? 我知道这与自动增量值有关,但我想知道我是否可以在php文件中添加一些代码,这些代码将自动重置所有id号,这样你就可以从id = 1开始,然后转到最后一个id号。删除一行后的增量为1?

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. 如果匹配,将删除具有匹配密码的行,并且将重新排序id号列,以便不跳过id号。

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. 更新:我正在通过将1到4的随机数设置为变量来制作旋转横幅广告系统,以便php文件将使用随机数变量从id = 1到id = 4检索随机广告。 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. 如果随机数恰好为3且id = 3不存在,则横幅广告行中将存在间隙。 If there is a way to work around big gaps in this situation, please tell me. 如果有办法解决这种情况下的巨大差距,请告诉我。 thanks in advance 提前致谢

Just execute the following SQL query: 只需执行以下SQL查询:

ALTER TABLE `tbl_name` AUTO_INCREMENT = 1;

…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. 唯一性更为重要,重置它会破坏它。

You can only use 你只能使用

ALTER TABLE 'tbl' AUTO_INCREMENT=#

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). 如果您有1,2,3,并且删除2,则不能使用它来填充2.如果删除3,则可以使用它来重复使用3(假设您没有更高的值)。 That is the best you can do. 这是你能做的最好的事情。

ALTER TABLE 'table' AUTO_INCREMENT = 1;

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)? 如果是这样使用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. 另外,请记住,如果更改数据库中的实际数字,则需要在其他表和代码中更改对它的所有引用。

You could do that by: 你可以这样做:

  1. Inventing a mechanism that provides the next available id when you want to insert (eg a transaction involving reading and incrementing an integer column somewhere -- pay special attention to the transaction isolation level!) 想要插入时创建一个提供下一个可用id的机制(例如,涉及在某处读取和递增整数列的事务 - 特别注意事务隔离级别!)
  2. Using 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!) 使用UPDATE递减所有id大于你刚删除的id(再次,使用事务 - 不要忘记外键必须是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 eg in MySQL 要选择随机数行,您可以在MySQL中进行

SELECT id FROM banners ORDER BY RAND() LIMIT 5

to select 5 random, guaranteed existing banner ids. 选择5个随机的,保证现有的横幅ID。

A word of caution: there are quite a few people who view ORDER BY RAND() as a bad performance hog. 需要注意的是:有很多人认为ORDER BY RAND()是一个糟糕的表现。 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) then ORDER BY RAND() provides a very nice and succint solution. 如果表中的行数是可管理的(我认为任何低于10K的行数都不是那么多)那么ORDER BY RAND()提供了一个非常好的和简单的解决方案。 Also, the documentation itself suggests this approach: 此外, 文档本身也提出了这种方法:

However, you can retrieve rows in random order like this: 但是,您可以按随机顺序检索行,如下所示:

mysql> SELECT * FROM tbl_name ORDER BY RAND();

ORDER BY RAND() combined with LIMIT is useful for selecting a random sample from a set of rows: ORDER BY RAND()结合LIMIT对于从一组行中选择随机样本非常有用:

mysql> SELECT * FROM table1, table2 WHERE a=b AND c ORDER BY RAND() LIMIT 1000; mysql> SELECT * FROM table1,table2 WHERE a = b AND c ORDER BY RAND()LIMIT 1000;

RAND() is not meant to be a perfect random generator. RAND()并不是一个完美的随机发生器。 It is a fast way to generate random numbers on demand that is portable between platforms for the same MySQL version. 这是一种快速生成按需随机数的方法,可以在同一MySQL版本的平台之间移植。

Well, you can actually just specify the id number you'd like a record to have as part of your insert statement, for example: 那么,您实际上只需指定您希望记录作为插入语句的一部分的ID号,例如:

INSERT INTO person VALUES(1,'John','Smith','jsmith@devnull.fake','+19995559999');

And if there's not a primary key collision (no record in the database with id=1), then MySQL will happily execute it. 如果没有主键冲突(数据库中没有id = 1的记录),那么MySQL将很乐意执行它。

The ALTER TABLE 'tbl' AUTO_INCREMENT=# thing also works, and means you don't have to keep track of the counter. ALTER TABLE 'tbl' AUTO_INCREMENT=# thing也有效,这意味着您不必跟踪计数器。

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. 让你的身份#特别重要的想法有点不寻常,可能是设计困难的标志。

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

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