Explain Codes LogoExplain Codes Logo

Delete rows with foreign key in PostgreSQL

sql
foreign-key
database-integrity
performance-optimization
Anton ShumikhinbyAnton Shumikhin·Sep 24, 2024
TLDR

To delete rows linked through a foreign key, either enable an ON DELETE CASCADE for the foreign key constraint, consequently causing automatic deletion of related rows, or proceed with manual deletion in two steps: erase child rows first, followed by parent rows.

Cascade deletion:

-- Look at me, now I am the deleter! ALTER TABLE child ADD CONSTRAINT fk_child FOREIGN KEY (parent_id) REFERENCES parent (id) ON DELETE CASCADE;

Manual deletion:

-- Careful, doing things manually can cause sweaty palms! DELETE FROM child WHERE parent_id = to_delete; DELETE FROM parent WHERE id = to_delete;

Replace child, fk_child, parent_id, parent, and to_delete with your concrete table and column names.

Mastering foreign key deletion

This section guides you in fully grasping how to delete rows with a foreign key in PostgreSQL.

Adjusting foreign keys with command ALTER TABLE

Leverage ALTER TABLE command to adjust foreign keys. It helps in automating deletion operations. Be sure to have the necessary privileges to avoid surprises!

-- Just a normal day in my life, dropping and recreating constraints. ALTER TABLE child DROP CONSTRAINT if_exists_fk_child; ALTER TABLE child ADD CONSTRAINT fk_child FOREIGN KEY (parent_id) REFERENCES parent (id) ON DELETE CASCADE;

Deciding between manual deletion and triggers

If ON DELETE CASCADE isn't your thing, you can opt for a manual deletion scheme or deploy a trigger to guarantee the removal of related rows.

-- Welcome to the world of triggers! CREATE OR REPLACE FUNCTION delete_child_rows() RETURNS TRIGGER AS $$ BEGIN DELETE FROM child WHERE parent_id = OLD.id; RETURN OLD; END; $$ LANGUAGE plpgsql; CREATE TRIGGER trg_before_delete_parent BEFORE DELETE ON parent FOR EACH ROW EXECUTE FUNCTION delete_child_rows();

Coping with large tables

When handling large tables, typical DELETE operations might seem lethargic. The TRUNCATE ... CASCADE command can be an efficient alternative.

-- Make way, big guy coming through! TRUNCATE TABLE parent CASCADE;

After truncating, reset sequence generators with RESTART IDENTITY for a clean slate:

-- Chronologically confused? Let's reset! TRUNCATE TABLE parent RESTART IDENTITY CASCADE;

Crucial aspects before deletion

Here are critical factors to consider when readying for row deletion concerning foreign keys.

Reviewing foreign key constraints

Before going gung-ho on changes, consider reviewing the present FK definitions using pg_get_constraintdef.

-- Peekaboo, show me what you got! SELECT pg_get_constraintdef(oid) FROM pg_constraint WHERE conrelid = 'child'::regclass AND contype = 'f';

About triggers: to disable or enable

For deleting rows that are likely to violate foreign key constraints, you may temporarily disable triggers.

-- It's quiet... TOO quiet... ALTER TABLE child DISABLE TRIGGER ALL; -- Perform your deletion operations here. ALTER TABLE child ENABLE TRIGGER ALL;

Ensuring database integrity

For manual deletions, it's of utmost importance to maintain the database's integrity by guaranteeing that referencing rows are appropriately managed prior to any deletion.

Expert tricks: optimizing your database

Cache these handy tricks to sustain optimized and fail-safe database operations regarding foreign keys.

Weighing performance of ON DELETE CASCADE

While cascading deletions simplify operations, they could be performance-intensive, specifically on large tables with many related records.

Checking privileges and potential locks

Ensure your database user privileges before performing table alterations. Remember, unanticipated long locks can hinder application performance.

Balancing database integrity and efficiency

Striking a harmonious balance between maintaining database integrity and efficient data management is crucial for smooth operations and to prevent unexpected data loss.