Конкретный ответ на эту конкретную дилемму (которая у меня также была) следующий:
1) Создайте таблицу, в которой будут храниться разные счетчики для разных документов (счета, квитанции, RMA и т. Д.); Вставьте запись для каждого из ваших документов и добавьте начальный счетчик к 0.
2) Перед созданием нового документа выполните следующие действия (например, для счетов):
UPDATE document_counters SET counter = LAST_INSERT_ID(counter + 1) where type = 'invoice'
3) Получите последнее значение, которое вы только что обновили, например:
SELECT LAST_INSERT_ID()
или просто используйте PHP (или любую другую) функцию mysql_insert_id (), чтобы получить то же самое
4) Вставьте новую запись вместе с основным идентификатором, который вы только что вернули из БД. Это переопределит текущий индекс автоинкремента и убедится, что между записями нет пробелов в идентификаторе.
Все это, конечно, нужно обернуть внутри транзакции. Прелесть этого метода в том, что при откате транзакции ваш оператор UPDATE из шага 2 будет откатываться, и счетчик больше не будет меняться. Другие параллельные транзакции будут блокироваться до тех пор, пока первая транзакция не будет зафиксирована или откатана, поэтому у них не будет доступа ни к старому счетчику, ни к новой, пока все остальные транзакции не будут завершены первыми.