Типичным решением для любой реляционной базы данных может быть таблица наподобие
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
Это будет работать для пользователей (если у каждого пользователя есть несколько одновременно запущенных транзакций), но не будет работать для компаний (например, когда вам нужны company_invoice_numbers), потому что транзакции от разных пользователей внутри одной компании могут блокировать друг друга, и будет узкое место в производительности. в этой таблице.
Самое важное функциональное требование, которое вы должны проверить, это разрешены ли в вашей системе пробелы в нумерации счетов. Когда вы используете стандартный auto_increment, вы допускаете пробелы, потому что в большинстве известных мне баз данных при откате транзакции увеличенное число не будет откатываться. Имея это в виду, вы можете улучшить производительность, используя одно из следующих рекомендаций.
1) Исключите процедуру, которую вы используете для получения новых номеров, из длительных транзакций. Предположим, что процедура вставить в счет является длительной транзакцией со сложной серверной логикой. . В этом случае вы сначала получаете новый идентификатор, а затем отдельной транзакцией вставляете новый счет. Если последняя транзакция будет откатана, автономер не уменьшится. Но user_invoice_numbers не будет заблокирован в течение длительного времени, поэтому множество одновременных пользователей могут одновременно вставлять счета.
2) Не используйте традиционную транзакционную базу данных для хранения данных с последним идентификатором для каждого пользователя. Если вам нужно поддерживать простой список ключей и значений, существует множество небольших, но быстрых механизмов базы данных, которые могут это сделать. которые работают для вас. Список баз данных ключей/значений< /а>. Вероятно, наиболее популярным является memcached. В прошлом я видел проекты, в которых простые хранилища ключей/значений были реализованы с использованием реестра Windows или даже файловой системы. Был каталог, где каждое имя файла было ключом, а внутри каждого файла был последний идентификатор. И это грубое решение было все же лучше, чем использование таблицы SQL, потому что блокировки выставлялись и снимались очень быстро и не участвовали в объеме транзакции.
Что ж, если мое предложение по оптимизации кажется слишком сложным для вашего проекта, забудьте об этом сейчас, пока вы действительно не столкнетесь с проблемами производительности. В большинстве проектов простой метод с дополнительной таблицей будет работать довольно быстро.
person
Bogdan_Ch
schedule
09.07.2009