Я столкнулся с ситуацией в нашей базе данных, когда мне нужно сместить временные метки количества записей на день, однако у меня есть уникальное ограничение, которое требует, чтобы поле id и поле метки времени были уникальными.
Вот описание таблицы.
Table "public.eedata"
Column | Type | Modifiers
-------------+--------------------------------+------------------------------------------------------------
eedata_id | bigint | not null default nextval('eedata_eedata_id_seq'::regclass)
user_id | integer |
eeupload_id | bigint |
eetimestamp | timestamp(0) without time zone |
Indexes:
"pk_eedata" PRIMARY KEY, btree (eedata_id)
"eedata_user_id_key" UNIQUE, btree (user_id, eetimestamp)
"fki_eeuploadid" btree (eeupload_id)
Foreign-key constraints:
"fk_eeupload_id" FOREIGN KEY (eeupload_id) REFERENCES eeupload(eeupload_id) ON UPDATE CASCADE ON DELETE CASCADE
"fk_user_id" FOREIGN KEY (user_id) REFERENCES users(user_id) ON UPDATE CASCADE ON DELETE CASCADE
Проблема в этом случае вызвана ограничением eedata_user_id_key. Я могу успешно вычесть день, используя,
update eedata set eetimestamp = eetimestamp - interval '1 day' where eeupload_id = xxx;
потому что порядок, в котором применяется обновление, предотвращает любые коллизии, однако, когда я пытаюсь
update eedata set eetimestamp = eetimestamp + interval '1 day' where eeupload_id = xxx;
Я получаю
ERROR: duplicate key violates unique constraint "eedata_user_id_key"
То, что мне нужно сделать, это либо указать порядок, в котором применяется обновление (фактически, порядок для оператора обновления), либо возможность приостановить ограничение для одного оператора обновления.
Я использую Postgres 8.1.11, если это имеет значение.