#sql #db2
#sql #db2
Вопрос:
Можно ли добавить автоматически созданный столбец первичного ключа (временную метку) в существующую таблицу с помощью alter table?
Что-то вроде этого, но оно не компилируется
ALTER TABLE DB2ADMIN.xxxyyyy ADD COLUMN ID TIMESTAMP NOT NULL WITH DEFAULT timestamp(generate_unique())@
Ошибка при подготовке
42601 (-104) [IBM] [CLI Driver] [DB2 / AIX64] SQL0104N После «OT NULL ПО УМОЛЧАНИЮ» был обнаружен неожиданный маркер «timestamp». Ожидаемые токены могут включать: «ПРОВЕРИТЬ». SQLSTATE=42601
Комментарии:
1.
TIMESTAMP
является зарезервированным словом. Заключите его в двойные кавычки, как в:ALTER TABLE DB2ADMIN.xxxyyyy ADD COLUMN ID "TIMESTAMP" NOT NULL WITH DEFAULT timestamp(generate_unique())@
2. Тем не менее, я думаю, что это плохая идея. PK не будет повторно представлять значение метки времени, а значение, основанное на метке времени… не совсем то же самое. При большой нагрузке эти значения могут немного отличаться от даты / времени.
Ответ №1:
Неразумно использовать поддельный (от generate_unique) тип данных временных меток в качестве первичного ключа, поскольку это затрудняет установку значений для ранее существующих строк и делает невозможной арифметику даты.
Временная МЕТКА типа данных лучше подходит для реальных дат / времени, потому что тогда вы можете использовать арифметику даты, что удобно для бизнеса. Если значения в вашем поддельном столбце временных меток взяты из generate-unique
, вы не можете разумно использовать арифметику даты.
Если вы попытаетесь использовать реальное значение временной метки (вместо generate_unique), например, current timestamp
тогда вы, вероятно, получите коллизии, в зависимости от скорости вставки. Обычно это плохая идея. Также это затрудняет установку значений для любых ранее существовавших строк.
Обычно намного проще и быстрее использовать автоматически созданный столбец идентификаторов в качестве суррогатного первичного ключа, особенно если в таблице уже есть существующие данные.
Вот типичный способ сделать это, который работает с Db2-LUW, а также с более старыми версиями Db2. В более поздних версиях Db2 возможны другие способы.
Сначала вам нужно убедиться, что в таблице еще нет первичного ключа, поскольку в таблице может быть не более одного из них.
Затем проверьте, имеет ли таблица уже уникальный индекс в столбце NOT NULL, потому что, если такой столбец существует, его можно повысить до столбца первичного ключа.
Если ничего из вышеперечисленного не существует, вы можете использовать логику, подобную приведенной ниже, чтобы добавить автоматически созданный столбец, задать уникальные значения во всех существующих строках и гарантировать, что любые будущие вставки автоматически получат уникальное значение в столбце без вмешательства приложения.
alter table myschema.mytab add column id bigint not null default 0 ;
alter table myschema.mytab alter column id drop default ;
alter table myschema.mytab alter column id set generated always as identity ;
update myschema.mytab set id = default ;
alter table myschema.mytab add constraint pkey primary key(id) ;
reorg table myschema.mytab ;
runstats on table myschema.mytab with distribution and detailed indexes all;
Комментарии:
1. Хорошо, tnx, у меня были сомнения по поводу использования int или timetamp, теперь вы меня убедили. Хотя временная метка была как-то более удобной в моем случае.
Ответ №2:
Вы можете использовать CURRENT_TIMESTAMP вместо метки времени (generate_unique())
ALTER TABLE sellers ADD COLUMN ID TIMESTAMP NOT NULL WITH DEFAULT CURRENT_TIMESTAMP
Комментарии:
1. «Если вы попытаетесь использовать реальное значение временной метки (вместо generate_unique), например, текущую временную метку, вы, вероятно, столкнетесь с конфликтами, в зависимости от скорости вставки. Обычно это плохая идея «. — @mao и я согласен с ним