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. 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
Just execute the following SQL query:
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). 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)? 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.
Well, you can actually just specify the id number you'd like a record to have as part of your insert statement, for example:
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.
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.
You could do that by:
- Inventing a mechanism that provides the next available id when you want to insert (e.g. a transaction involving reading and incrementing an integer column somewhere -- pay special attention to the transaction isolation level!)
- 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!)
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
SELECT id FROM banners ORDER BY RAND() LIMIT 5
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) then ORDER BY RAND()
provides a very nice and succint solution. 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:
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. It is a fast way to generate random numbers on demand that is portable between platforms for the same MySQL version.
精彩评论