Иногда при проектировании базы данных разработчики недооценивают масштаб проекта.
И тогда проект взлетает и становится высоконагруженным.
Затем в какой-то момент кто-то замечает, что тип идентификатора INT выбран в качестве первичного ключа большой таблицы с ограничением в 2 147 483 647. На первый взгляд кажется, что 2 миллиарда записей — это очень много.
А что, если каждый день добавлять по 10 миллионов новых записей? И уже потрачено более 1 миллиарда ценностей? У вас есть приложение, которое работает 24/7? Тогда у вас останется всего 114 дней, чтобы исправить тип первичного ключа.
Это не так уж много, если у вас есть значение ключа, используемое как в веб-приложении, так и в клиентском приложении.
Если описанная ситуация вам знакома, и вы заметили эту досадную деталь — у вас заканчиваются значения первичного ключа — уже слишком поздно, то эта статья для вас.
В статье вы найдете скрипты, приведенные для таблицы TableWithPKViolation, в которой поле TableWithPKViolationId вызывает проблему.
В худшем случае вы столкнетесь с ошибкой «Ошибка арифметического переполнения при преобразовании IDENTITY в тип данных int».
Это означает, что значения первичного ключа уже закончились и ваше приложение перестало работать.
В этом случае можно использовать следующие решения:
- Измените тип первичного ключа на BIGINT. Всем понятно, что лучший вариант — залезть в машину времени и поменять INT на BIGINT там, в прошлом.
Но сделать это можно и сейчас, если поле TableWithPKViolationId не используется в серверных и клиентских приложениях, то у вас есть возможность быстро и безболезненно изменить тип.
Сделайте это и не тратьте время на остальную часть статьи.
Обратите внимание, что если в вашей таблице более 1 миллиарда записей, то изменение будет применено, т.е.
может занять более 3 часов, в зависимости от мощности вашего сервера, и потребует дополнительного места для журнала транзакций (если есть возможность, переключитесь на модель режима восстановления в режиме Simple).
Сценарий изменения следующий:
ALTER TABLE TableWithPKViolation ALTER COLUMN TableWithPKViolationId BIGINT;
- Используйте отрицательные значения.
Обычно при использовании идентификатора значением по умолчанию является IDENTITY(1,1).
Когда значение приближается к 2 миллиардам записей, вы можете сбросить начальное значение с помощью следующей команды:
DBCC CHECKIDENT (TableWithPKViolation, - 2147483647, reseed)
и, таким образом, получите гораздо больше времени для перехода на BIGINT. Единственное неудобство этого решения — отрицательные значения первичного ключа.Убедитесь, что ваша бизнес-логика допускает отрицательные значения.
Это, пожалуй, самое простое решение.
- III. Создайте таблицу с неиспользуемыми значениями.
Подсчитайте недостающие значения и создайте таблицу со списком неиспользуемых значений.
Это даст вам дополнительное время для перехода в BIGINT. Этот метод подойдет вам, если вы не полагаетесь на порядок записей в таблице, то есть не используете ORDERY BY Id. Или не так много мест, где есть такая сортировка, и можно изменить сортировку на другое поле, например, по дате добавления записи.
Есть два способа создать таблицу с неиспользуемыми значениями: Метод А .
Отсутствующие значения.
Когда вы используете Identity, у вас всегда есть недостающие значения, поскольку значения резервируются при запуске транзакции, и если транзакция откатывается, следующей транзакции назначается новое значение первичного ключа рядом с зарезервированным.
Зарезервированное значение, созданное для отмененной транзакции, останется неиспользованным.
Эти неиспользуемые значения можно сформировать в отдельную таблицу и применить с помощью кода ниже.
Метод Б .
Удалены значения.
Если вы регулярно удаляете записи из таблицы, в которой заканчиваются значения первичного ключа, то любые удаленные значения можно повторно использовать как свободные значения.
Ниже я приведу пример кода для этой опции.
Исходная таблица TableWithPKViolation.
CREATE TABLE [dbo].
[TableWithPKViolation](
-
Что Такое Настольный Компьютер?
19 Oct, 24 -
Биоэтика
19 Oct, 24 -
Путь К Мечте
19 Oct, 24