Типичным решением для любой базы данных отношений может быть таблица типа
user_invoice_numbers (user_id int primary key clustered, last_id int)
и хранимая процедура или запрос SQL, например
update user_invoice_numbers set last_id = last_id + 1 where user_id = @user_id
select last_id from user_invoice_numbers where user_id = @user_id
Это будет работать для пользователей (если у каждого пользователя есть несколько одновременно запущенных транзакций), но не будет работать для компаний (например, когда вам нужны companies_invoice_numbers), потому что транзакции от разных пользователей внутри одной и той же компании могут блокировать друг друга, и будут узкое место производительности в этой таблице.
Самое важное функциональное требование, которое вы должны проверить: разрешено ли вашей системе иметь пробелы в нумерации счетов или нет . Когда вы используете стандартный auto_increment, вы допускаете пропуски, потому что в большинстве известных мне баз данных при откате транзакции увеличенное число не будет откатываться. Имея это в виду, вы можете улучшить производительность, используя одно из следующих указаний
1) Исключите процедуру, которую вы используете для получения новых номеров из длительных транзакций. Предположим, что вставка в счет процедура является длительной транзакцией со сложной серверной стороной логика. В этом случае вы сначала получаете новый идентификатор, а затем в отдельной транзакции вставляете новый счет. Если откат последней транзакции будет выполнен, авто-номер не уменьшится. Но user_invoice_numbers не будет заблокирован в течение длительного времени, поэтому многие пользователи одновременно могут вставлять счета-фактуры одновременно
2) Не используйте традиционную транзакционную базу данных для хранения данных с последним идентификатором для каждого пользователя. Когда вам нужно вести простой список ключей и значений, существует множество небольших, но быстрых механизмов базы данных, которые могу сделать эту работу за вас. Список баз данных ключей / значений . Вероятно, memcached является самым популярным. В прошлом я видел проекты, где простые хранилища ключей / значений были реализованы с использованием реестра Windows или даже файловой системы. Существовал каталог, в котором каждое имя файла было ключом, а внутри каждого файла был последний идентификатор. И это грубое решение было все же лучше, чем использование таблицы SQL, потому что блокировки были созданы и выпущены очень быстро и не были вовлечены в объем транзакции.
Что ж, если мое предложение по оптимизации кажется слишком сложным для вашего проекта, забудьте об этом сейчас, пока вы действительно не столкнетесь с проблемами производительности. В большинстве проектов простой метод с дополнительной таблицей будет работать довольно быстро.