Пользовательские идентификаторы последовательностей SQL Server 2008

Большинство моих баз данных используют столбцы IDENTITY в качестве первичных ключей. Я пишу журнал изменений/контрольный журнал в базе данных и хочу использовать идентификатор BIGINT для последовательного отслеживания изменений.

Хотя BIGINT довольно большой, однажды он иссякнет, и мой дизайн не будет работать должным образом в этот момент. Я знал об этой проблеме с другими столбцами идентификаторов и намеревался в конечном итоге преобразовать их в GUID/UUID, как я использовал в Postgres в прошлом.

GUID занимает 16 байт, а BIGINT — 8. Для моей текущей задачи я хотел бы остаться с BIGINT для экономии места и последовательности. В Postgres я создал пользовательскую последовательность, в которой первые две цифры обозначают текущий год, а фиксированное количество цифр — последовательность внутри года. Генератор последовательности автоматически сбрасывает последовательность при изменении года.

SQL Server 2008 не имеет генератора последовательностей. Мое исследование выявило некоторые идеи, большинство из которых включают использование таблицы для хранения порядкового номера, обновление его в транзакции, а затем использование его для присвоения моим данным в отдельной транзакции.

Я хочу написать SP или функцию, которая будет обновлять последовательность и возвращать мне новое значение при вызове из триггера в целевой таблице до записи строки. Есть много идей, но все они, кажется, говорят о проблемах блокировки и изоляции.

Есть ли у кого-нибудь предложения о том, как автоматизировать назначение этого идентификатора, защитить процесс от назначения дубликатов при одновременной записи и предотвратить проблемы с задержкой блокировки?


person sthames42    schedule 23.01.2014    source источник
comment
Почему бы вам не использовать автоматически сгенерированные значения IDENTITY? Почему вы пытаетесь создать их самостоятельно?   -  person Sebastian K    schedule 24.01.2014
comment
Если вы используете BIGINT IDENTITY, начиная с 1, и вставляете одну тысячу строк каждую секунду, вам потребуется ошеломляющее 292 миллиона лет, прежде чем вы достигнете предела в 922 квадриллиона. .. Вас это ДЕЙСТВИТЕЛЬНО беспокоит?   -  person marc_s    schedule 24.01.2014


Ответы (1)


Хранимая процедура подвержена таким проблемам, как блокировка и тупиковые ситуации. Однако есть способы обойти это.

А пока, почему бы не начать отключение идентификатора в нижней части отрицательного диапазона?

CREATE TABLE FOO
(
ID BIGINT IDENTITY(-9223372036854775808, 1) 
)

Это дает вам диапазон от -9 223 372 036 854 775 808 до 9 223 372 036 854 775 807.

Вы действительно собираетесь съесть 2 ^ 63 + 2 ^ 63 числа?

Если вы все еще привержены другому решению, я могу дать вам кусок рабочего кода. Однако необходимо использовать блокировки приложений и изоляцию Serializable.

Он по-прежнему склонен к тайм-аутам или блокировке в зависимости от настройки тайм-аута и нагрузки на сервер.

Короче говоря, в 2012 году появились последовательности. Это в основном то, что вы хотите.

person CRAFTY DBA    schedule 24.01.2014