A column or set of columns that references the primary key of another table, enforcing referential integrity between parent and child tables.

A column (or set of columns) that references the primary key of another table, enforcing referential integrity. The foreign key table is the child; the referenced table is the parent. Prevents orphaned rows and enables JOINs. Disabled by some bulk-load operations.

Compatibility

Filter by Database
SQL FOREIGN KEY Compatibility Across Databases
Database System Support Status Since Version Notes
MySQL Native all Foreign keys are only enforced by the InnoDB engine — MyISAM silently ignores FK constraints. ON DELETE / ON UPDATE actions: RESTRICT, CASCADE, SET NULL, NO ACTION, SET DEFAULT. Both columns must have compatible types and the parent column must be indexed.
PostgreSQL Native all Full FK support with DEFERRABLE / INITIALLY DEFERRED options — you can defer constraint checking to end of transaction, useful for circular references or batch inserts. ON DELETE actions: NO ACTION, RESTRICT, CASCADE, SET NULL, SET DEFAULT.
SQL Server Native all Standard FK support. ON DELETE / ON UPDATE: NO ACTION, CASCADE, SET NULL, SET DEFAULT. FKs can be temporarily disabled with ALTER TABLE ... NOCHECK CONSTRAINT for bulk loads. Cannot cascade to the same table through multiple paths (no multiple cascade paths).
Oracle Native all Standard FK support. ON DELETE CASCADE and ON DELETE SET NULL supported; ON UPDATE CASCADE is NOT supported in Oracle. FKs can be disabled/enabled without dropping. An index on the FK column is recommended (Oracle does not auto-create it, unlike other engines).
SQLite Native 3.6.19 Foreign key enforcement is DISABLED by default and must be enabled per connection with PRAGMA foreign_keys = ON. Without this pragma, FK constraints are parsed but silently ignored. This is a common gotcha for SQLite users.

Details

SQLite's foreign keys are off by default — the most common FK gotcha in the SQLite ecosystem. Oracle does not support ON UPDATE CASCADE. MySQL's FK enforcement depends on the storage engine (InnoDB yes, MyISAM no). PostgreSQL's DEFERRABLE constraint option is unique and powerful for complex batch operations.

Standard Syntax

CREATE TABLE orders ( id INT PRIMARY KEY, customer_id INT, FOREIGN KEY (customer_id) REFERENCES customers(id) ON DELETE CASCADE ON UPDATE CASCADE );

Version Support

MySQL: Native in all listed versions PostgreSQL: Native in all listed versions SQL Server: Native in all listed versions Oracle: Native in all listed versions SQLite: Native since 3.6.19

Per-Database Syntax & Notes

MySQL Native syntax

Foreign keys are only enforced by the InnoDB engine — MyISAM silently ignores FK constraints. ON DELETE / ON UPDATE actions: RESTRICT, CASCADE, SET NULL, NO ACTION, SET DEFAULT. Both columns must have compatible types and the parent column must be indexed.

CREATE TABLE orders ( id INT AUTO_INCREMENT PRIMARY KEY, customer_id INT, FOREIGN KEY (customer_id) REFERENCES customers(id) ON DELETE CASCADE ON UPDATE RESTRICT ) ENGINE=InnoDB; -- Disable FK checks for bulk loads: SET FOREIGN_KEY_CHECKS = 0;

PostgreSQL Native syntax

Full FK support with DEFERRABLE / INITIALLY DEFERRED options — you can defer constraint checking to end of transaction, useful for circular references or batch inserts. ON DELETE actions: NO ACTION, RESTRICT, CASCADE, SET NULL, SET DEFAULT.

CREATE TABLE orders ( id SERIAL PRIMARY KEY, customer_id INT REFERENCES customers(id) ON DELETE CASCADE ); -- Deferrable constraint: ALTER TABLE orders ADD CONSTRAINT fk_customer FOREIGN KEY (customer_id) REFERENCES customers(id) DEFERRABLE INITIALLY DEFERRED;

SQL Server Native syntax

Standard FK support. ON DELETE / ON UPDATE: NO ACTION, CASCADE, SET NULL, SET DEFAULT. FKs can be temporarily disabled with ALTER TABLE ... NOCHECK CONSTRAINT for bulk loads. Cannot cascade to the same table through multiple paths (no multiple cascade paths).

CREATE TABLE orders ( id INT IDENTITY PRIMARY KEY, customer_id INT, CONSTRAINT fk_orders_customer FOREIGN KEY (customer_id) REFERENCES customers(id) ON DELETE CASCADE ); -- Disable for bulk load: ALTER TABLE orders NOCHECK CONSTRAINT fk_orders_customer;

Oracle Native syntax

Standard FK support. ON DELETE CASCADE and ON DELETE SET NULL supported; ON UPDATE CASCADE is NOT supported in Oracle. FKs can be disabled/enabled without dropping. An index on the FK column is recommended (Oracle does not auto-create it, unlike other engines).

CREATE TABLE orders ( id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, customer_id NUMBER, CONSTRAINT fk_orders_customer FOREIGN KEY (customer_id) REFERENCES customers(id) ON DELETE CASCADE ); -- Recommended: index the FK column manually CREATE INDEX idx_orders_cust ON orders(customer_id);

SQLite Native syntax

Foreign key enforcement is DISABLED by default and must be enabled per connection with PRAGMA foreign_keys = ON. Without this pragma, FK constraints are parsed but silently ignored. This is a common gotcha for SQLite users.

-- REQUIRED: enable FK enforcement first PRAGMA foreign_keys = ON; CREATE TABLE orders ( id INTEGER PRIMARY KEY, customer_id INTEGER REFERENCES customers(id) ON DELETE CASCADE );