Pamatuji si, že jsem vznesl téměř stejný bod, když byl PG9 ve stavu alfa. Zde byla odpověď od Toma Lanea (vývojář jádra PG):
http://archives.postgresql.org/pgsql-general/2010-01/msg00221.php
Stručně řečeno:neopraví se.
Tím nechci říct, že souhlasím s vaším návrhem, že současné chování je chyba. Podívejte se na to z opačného úhlu:jedná se o chování NOT DEFERRABLE
to je nesprávné.
Ve skutečnosti by k porušení omezení v této UPDATE v žádném případě nikdy nemělo dojít, protože na konci AKTUALIZACE je omezení splněno. Stav na konci příkazu je to, na čem záleží. Mezistavy během provádění jednoho příkazu by neměly být uživateli vystaveny.
Zdá se, že PostgreSQL implementuje neodložitelné omezení kontrolou duplikátů po každé aktualizaci řádku a selhání okamžitě po prvním duplikátu, což je v podstatě chybné. Ale to je známý problém, pravděpodobně starý jako PostgreSQL. V dnešní době je řešením právě použití omezení DEFERRABLE. A je tu jistá ironie v tom, že se na to díváte jako na nedostatečný, protože selže, zatímco v prvé řadě to má být řešením selhání!
Shrnutí současného stavu od PostgreSQL 9.1
-
NOT DEFERRABLE
UNIQUE
neboPRIMARY KEY
omezení se kontrolují po každém řádku . -
DEFERRABLE
omezení nastavena naIMMEDIATE
(INITIALLY IMMEDIATE
nebo pomocíSET CONSTRAINTS
) jsou kontrolovány po každém příkazu . -
DEFERRABLE
omezení nastavena naDEFERRED
(INITIALLY DEFERRED
nebo pomocíSET CONSTRAINTS
) jsou kontrolovány po každé transakci .
Všimněte si speciálního zpracování UNIQUE
/ PRIMARY KEY
omezení. Citace manuálové stránky pro CREATE TABLE
:
Omezení, které nelze odložit, bude zkontrolováno okamžitě po každém příkazu .
I když je uvedeno dále v části Kompatibilita v části Non-deferred uniqueness constraints
:
Když
UNIQUE
neboPRIMARY KEY
omezení není odložitelné, PostgreSQL okamžitě zkontroluje jedinečnost kdykoli je řádek vložen nebo upraven. Standard SQL říká, že jedinečnost by měla být vynucena pouze na konci příkazu; to je rozdíl, když například jeden příkaz aktualizuje více hodnot klíče. Chcete-li dosáhnout chování v souladu se standardy, deklarujte omezení jakoDEFERRABLE
ale neodloženo (tj.INITIALLY IMMEDIATE
). Uvědomte si, že to může být výrazně pomalejší než okamžitá kontrola jedinečnosti.
Tučné zdůraznění moje.
Pokud potřebujete jakýkoli FOREIGN KEY
omezení odkazovat na sloupce, DEFERRABLE
není možnost, protože (podle dokumentace):
Odkazované sloupce musí být sloupci neodložitelného omezení jedinečného nebo primárního klíče v odkazované tabulce.