PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Дефинирано ограничение ОТЛОЖЕНО ПЪРВОНАЧАЛНО НЕЗАБАВНО все още е ОТЛОЖЕНО?

Спомням си, че повдигнах почти идентична точка, когато PG9 беше в алфа състояние. Ето отговора от Том Лейн (високопрофилен разработчик на PG ядро):
http://archives.postgresql.org/pgsql-general/2010-01/msg00221.php

Накратко:няма да се оправи.

Да не кажа, че съм съгласен с вашето предложение, че текущото поведение е грешка. Погледнете го от обратния ъгъл:това е поведението на NOT DEFERRABLE това е неправилно.

Всъщност нарушението на ограничението в тази актуализация никога не трябва да се случва в никакъв случай, тъй като в края на актуализацията ограничението е удовлетворено. Състоянието в края на командата е това, което има значение. Междинните състояния по време на изпълнението на един оператор не трябва да бъдат изложени на потребителя.

Изглежда, че PostgreSQL прилага ограничението без отлагане, като проверява за дубликати след всеки актуализиран ред и се проваля веднага при първия дубликат, което по същество е дефектно. Но това е известен проблем, вероятно толкова стар, колкото PostgreSQL. В днешно време решението за това е точно да се използва ОТЛОЖЕНО ограничение. И има известна ирония в това, че го гледате като недостатъчен, защото не успява да се провали, докато по някакъв начин той трябва да бъде решението на провала на първо място!

Обобщение на статуквото след PostgreSQL 9.1

  • NOT DEFERRABLE UNIQUE или PRIMARY KEY ограниченията се проверяватслед всеки ред .

  • DEFERRABLE ограниченията са зададени на IMMEDIATE (INITIALLY IMMEDIATE или чрез SET CONSTRAINTS ) се проверяват след всяко изявление .

  • DEFERRABLE ограниченията са зададени на DEFERRED (INITIALLY DEFERRED или чрез SET CONSTRAINTS ) се проверяватслед всяка транзакция .

Обърнете внимание на специалното третиране на UNIQUE / PRIMARY KEY ограничения. Цитиране на страницата с ръководството за CREATE TABLE :

Ограничение, което не може да бъде отложено, ще бъде проверено веднага след всяка команда .

Докато се посочва по-надолу в Съвместимост раздел под Non-deferred uniqueness constraints :

Когато е UNIQUE или PRIMARY KEY ограничението не е отложено, PostgreSQL проверява за уникалност незабавно всеки път, когато се вмъква или променя ред. SQL стандартът казва, че уникалността трябва да бъде принудена само в края на израза; това прави разлика, когато например една команда актуализира няколко ключови стойности. За да получите стандартно съвместимо поведение, декларирайте ограничението катоDEFERRABLE но не и отложено (т.е. INITIALLY IMMEDIATE ). Имайте предвид, че това може да бъде значително по-бавно от незабавната проверка на уникалността.

Удебелен акцент мое.

Ако имате нужда от FOREIGN KEY ограничения за препратка към колоната(ите), DEFERRABLE не е опция, защото (според документация):

Референтните колони трябва да са колоните на неотлагаемо ограничение за уникален или първичен ключ в реферираната таблица.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Изявление на PostgreSQL IF

  2. PostgreSQL сървърът няма да се изключи на Lion (Mac OS 10.7)

  3. PostgreSQL функция/запаметена процедура CURRENT_TIMESTAMP не се променя

  4. Как да нулирате последователността за идентификатори на PostgreSQL таблици

  5. Как да добавите брой дни в postgresql datetime