Heim  >  Artikel  >  Datenbank  >  Wie implementiert man die kaskadierende übergeordnete Löschung mit Fremdschlüsseleinschränkungen in PostgreSQL?

Wie implementiert man die kaskadierende übergeordnete Löschung mit Fremdschlüsseleinschränkungen in PostgreSQL?

Linda Hamilton
Linda HamiltonOriginal
2024-10-31 22:34:29868Durchsuche

How to Implement Cascading Parent Deletion with Foreign Key Constraints in PostgreSQL?

Kaskadierende übergeordnete Löschung mit Fremdschlüsseleinschränkung

In relationalen Datenbanksystemen erfordert das Löschen einer untergeordneten Zeile häufig die Löschung der übergeordneten Zeile, wenn dies der Fall ist von keinem anderen Kind mehr erwähnt. Diese Aufgabe kann in PostgreSQL-Versionen 9.1 und höher mithilfe eines datenmodifizierenden CTE (Common Table Expression) ausgeführt werden.

Datenmodifizierender CTE-Ansatz

<code class="sql">WITH del_child AS (
    DELETE FROM child
    WHERE  child_id = 1
    RETURNING parent_id, child_id
    )
DELETE FROM parent p
USING  del_child x
WHERE  p.parent_id = x.parent_id
AND    NOT EXISTS (
   SELECT FROM child c
   WHERE  c.parent_id = x.parent_id
   AND    c.child_id <> x.child_id   -- !
   );</code>

Dies CTE löscht zunächst die angegebene untergeordnete Zeile. Anschließend werden die übergeordnete ID und die gelöschte untergeordnete ID zurückgegeben. Die zweite DELETE-Anweisung verwendet diese Informationen, um die übergeordnete Zeile zu löschen, wenn keine weiteren untergeordneten Zeilen mehr vorhanden sind. Die Bedingung c.child_id <> x.child_id stellt sicher, dass nur andere Kinder als das gelöschte berücksichtigt werden.

Beseitigung von Race Conditions

Um potenzielle Race Conditions zu verhindern, bei denen gleichzeitige Transaktionen zu unerwarteten Ergebnissen führen können , kann die übergeordnete Zeile vor dem Löschvorgang gesperrt werden. Dies wird erreicht, indem die FOR NO KEY UPDATE-Klausel im CTE verwendet wird, um die übergeordnete Zeile zu sperren.

<code class="sql">WITH lock_parent AS (
   SELECT p.parent_id, c.child_id
   FROM   child  c
   JOIN   parent p ON p.parent_id = c.parent_id
   WHERE  c.child_id = 12              -- provide child_id here once
   FOR    NO KEY UPDATE                -- locks parent row.
   )
 , del_child AS (
   DELETE FROM child c
   USING  lock_parent l
   WHERE  c.child_id = l.child_id
   )
DELETE FROM parent p
USING  lock_parent l
WHERE  p.parent_id = l.parent_id
AND    NOT EXISTS (
   SELECT FROM child c
   WHERE  c.parent_id = l.parent_id
   AND    c.child_id <> l.child_id   -- !
   );</code>

Dieser Ansatz beschränkt die Ausführung der riskanten DELETE-Vorgänge auf eine einzige Transaktion und eliminiert so effektiv die Möglichkeit einer gleichzeitigen Ausführung Störung.

Das obige ist der detaillierte Inhalt vonWie implementiert man die kaskadierende übergeordnete Löschung mit Fremdschlüsseleinschränkungen in PostgreSQL?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn