How to handle fragmentation of auto_increment ID column in MySQL

I have a table with an auto_increment field and sometimes rows get deleted so auto_increment leaves gaps. Is there any way to avoid this or if not, at the very least, how to write an SQL query that:

  1. Alters the auto_increment value to be the max(current value) + 1
  2. Return the new auto_increment value?

I know how to write part 1 and 2 but can I put them in the same query?

If that is not possible:

How do I "select" (return) the auto_increment value or auto_increment value + 1?


Solution 1:

Renumbering will cause confusion. Existing reports will refer to record 99, and yet if the system renumbers it may renumber that record to 98, now all reports (and populated UIs) are wrong. Once you allocate a unique ID it's got to stay fixed.

Using ID fields for anything other than simple unique numbering is going to be problematic. Having a requirement for "no gaps" is simply inconsistent with the requirement to be able to delete. Perhaps you could mark records as deleted rather than delete them. Then there are truly no gaps. Say you are producing numbered invoices: you would have a zero value cancelled invoice with that number rather than delete it.

Solution 2:

There is a way to manually insert the id even in an autoinc table. All you would have to do is identify the missing id.

However, don't do this. It can be very dangerous if your database is relational. It is possible that the deleted id was used elsewhere. When removed, it would not present much of an issue, perhaps it would orphan a record. If replaced, it would present a huge issue because the wrong relation would be present.

Consider that I have a table of cars and a table of people

car
carid
ownerid
name

person
personid
name

And that there is some simple data

car
1 1 Van
2 1 Truck
3 2 Car
4 3 Ferrari
5 4 Pinto

person
1 Mike
2 Joe
3 John
4 Steve

and now I delete person John.

person
1 Mike
2 Joe
4 Steve

If I added a new person, Jim, into the table, and he got an id which filled the gap, then he would end up getting id 3

1 Mike
2 Joe
3 Jim
4 Steve

and by relation, would be the owner of the Ferrari.

Solution 3:

I generally agree with the wise people on this page (and duplicate questions) advising against reusing auto-incremented id's. It is good advice, but I don't think it's up to us to decide the rights or wrongs of asking the question, let's assume the developer knows what they want to do and why.

The answer is, as mentioned by Travis J, you can reuse an auto-increment id by including the id column in an insert statement and assigning the specific value you want.

Here is a point to put a spanner in the works: MySQL itself (at least 5.6 InnoDB) will reuse an auto-increment ID in the following circumstance:

  • delete any number rows with the highest auto-increment id
  • Stop and start MySQL
  • insert a new row

The inserted row will have an id calculated as max(id)+1, it does not continue from the id that was deleted.