OceanBase Database in MySQL mode supports foreign keys to cross-reference related data between tables. Foreign key constraints help keep the related data consistent.
Features
A foreign key relationship involves a parent table and a child table. The parent table has the initial column values and the child table references the column values in the parent table. The foreign key constraint is defined on the child table.
The following is the basic syntax that defines a foreign key constraint in the CREATE TABLE or ALTER TABLE statement:
[CONSTRAINT [symbol]] FOREIGN KEY
[index_name] (col_name, ...)
REFERENCES tbl_name (col_name,...)
[ON DELETE reference_option]
[ON UPDATE reference_option]
reference_option:
RESTRICT | CASCADE | NO ACTION | SET DEFAULT
The following are the features of foreign key constraints:
Identifiers
Conditions and restrictions
Referential actions
Identifiers
The naming of foreign key constraints is governed by the following rules:
If you have defined the
CONSTRAINT symbolclause, use the name specified by the clause.If you have not defined the
CONSTRAINT symbolclause, or you have not entered a symbol after theCONSTRAINTkeyword, a name of the foreign key constraint is automatically generated.The name specified by the clause must be unique in a database. Otherwise, the error
ERROR 1005 (HY000): Can't create table 'test.fk1' (errno: 121)is reported.
The table name and column identifier in the FOREIGN KEY ... REFERENCES clause can be enclosed in backticks (`).
Conditions and restrictions
Foreign key constraints comply with the following conditions and restrictions:
The creation of foreign key constraints requires the
REFERENCESprivilege on the parent table.Corresponding foreign key columns and referenced key columns must have similar data types. The size and sign of fixed precision types such as
INTEGERandDECIMALmust be the same. The length of string types can be different. The character set and collation of non-binary (character) string columns must be the same.OceanBase Database in MySQL mode requires indexes on foreign keys and referenced keys. This way, the foreign key check is fast and does not require a table scan. In the referencing table, an index must be defined to hold foreign key columns listed as the first columns in the same order. If the referencing table has no such index, the index is automatically generated. This index may be silently dropped if you create another index that can be used to enforce the foreign key constraint. If you have specified the value of
index_name, the value is used as previously described.Index prefixes on foreign key columns are not supported. Therefore,
BLOBandTEXTcolumns cannot be included in a foreign key because indexes on those columns must always include a prefix length.Foreign key constraints cannot reference virtual or generated columns.
Referential actions
When an UPDATE or DELETE operation affects a key value in the parent table that has matching rows in the child table, the result depends on the referential action specified by the ON UPDATE and ON DELETE subclauses of the FOREIGN KEY clause. The following are referential actions:
CASCADE: Delete or update a row from the parent table and automatically delete or update the matching row in the child table.The
ON DELETE CASCADEandON UPDATE CASCADEclauses are supported. Do not define multipleON UPDATE CASCADEclauses that act on the same column in the parent or child table. If aFOREIGN KEYclause is defined on both tables in a foreign key relationship, making them the parent and child tables, theON UPDATE CASCADEorON DELETE CASCADEsubclause defined for oneFOREIGN KEYclause must be defined for the other. This ensures that cascading operations are successful. If theON UPDATE CASCADEorON DELETE CASCADEsubclause is only defined for oneFOREIGN KEYclause, cascading operations fail and the corresponding error is reported.Notice
Cascaded foreign key actions do not activate triggers.
RESTRICT: Reject the delete or update operation for the parent table.When you specify
RESTRICTorNO ACTION, it is equivalent to omitting theON DELETEorON UPDATEclause.NO ACTION: A keyword from standard SQL.For OceanBase Database in MySQL mode, this action is equivalent to
RESTRICT. If the referenced table contains a related foreign key value, OceanBase Database rejects the delete or update operation for the parent table. Some database systems have deferred checks, andNO ACTIONis a deferred check. In MySQL mode, foreign key constraints are immediately checked, soNO ACTIONis equivalent toRESTRICT.
For unspecified ON DELETE or ON UPDATE clauses, NO ACTION is always performed by default. By default, an explicitly specified ON DELETE NO ACTION or ON UPDATE NO ACTION clause does not appear in the output of SHOW CREATE TABLE.
Common operations
Add a foreign key constraint
You can use the following ALTER TABLE syntax to add a foreign key constraint to a table:
ALTER TABLE table_name
ADD [CONSTRAINT [symbol]] FOREIGN KEY
[index_name] (col_name, ...)
REFERENCES tbl_name (col_name,...)
[ON DELETE reference_option]
[ON UPDATE reference_option]
The foreign key can be self-referential, which means referring to the same table. Before you use the ALTER TABLE syntax to add a foreign key constraint to a table, make sure that you have created an index on the columns referenced by the foreign key.
Drop a foreign key constraint
You can use the following ALTER TABLE syntax to drop a foreign key constraint from a table:
ALTER TABLE table_name DROP FOREIGN KEY fk_symbol;
If the FOREIGN KEY clause defines a CONSTRAINT name when you create a foreign key constraint, you can refer to that name to drop the constraint. Otherwise, a constraint name is internally generated, and you must use this name. To obtain the foreign key constraint name, use SHOW CREATE TABLE.
Foreign key checking
Foreign key checking is controlled by the foreign_key_checks variable. By default, the variable is enabled. This variable is often enabled during normal operations to enforce referential integrity.
In the following scenarios, disabling foreign_key_checks is useful:
Drop a table referenced by a foreign key constraint. The table can only be dropped after you disable
foreign_key_checks. Constraints defined on a table are dropped together with the table.Reload tables in an order different from the order required by their foreign key relationships.
Import data. You can disable foreign key checking to speed up data import.
Execute
ALTER TABLEoperations on a table in a foreign key relationship.
Disabling foreign_key_checks has the following negative effects:
You are allowed to drop a database that contains tables with foreign keys that are referenced by tables outside the database.
You are allowed to drop a table with foreign keys referenced by other tables.
A table scan is not triggered when foreign_key_checks is enabled. Therefore, rows added to a table during the period when foreign_key_checks is disabled are not checked for consistency when foreign_key_checks is re-enabled.
Foreign key definitions and metadata
To view foreign key definitions, use SHOW CREATE TABLE. Example:
obclient> SHOW CREATE TABLE child\G
*************************** 1. row ***************************
Table: child
Create Table: CREATE TABLE `child` (
`id` int(11) DEFAULT NULL,
`parent_id` int(11) DEFAULT NULL,
CONSTRAINT `child_OBFK_1633952161788605` FOREIGN KEY (`parent_id`) REFERENCES `test`.`parent`(`id`) ON UPDATE RESTRICT ON DELETE CASCADE ,
KEY `par_ind` (`parent_id`) BLOCK_SIZE 16384 GLOBAL
) DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0
You can query information about foreign keys from the INFORMATION_SCHEMA.KEY_COLUMN_USAGE table. Query example:
obclient> SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGEWHERE REFERENCED_TABLE_SCHEMA IS NOT NULL;+--------------+------------+-------------+-----------------------------+| TABLE_SCHEMA | TABLE_NAME | COLUMN_NAME | CONSTRAINT_NAME |+--------------+------------+-------------+-----------------------------+| test | child | parent_id | child_OBFK_1633952161788605 |+--------------+------------+-------------+-----------------------------+
Examples
The following example shows how to relate parent and child tables by using a single-column foreign key:
CREATE TABLE parent ( id INT NOT NULL, PRIMARY KEY (id) ) CREATE TABLE child ( id INT, parent_id INT, INDEX par_ind(parent_id), FOREIGN KEY (parent_id) REFERENCES parent (id) ON DELETE CASCADE )
In the following example, which is more complex, the
product_ordertable has foreign keys for two other tables. One foreign key references a two-column index in the product table, whereas the other references a single-column index in the customer table.CREATE TABLE product ( category INT NOT NULL, id INT NOT NULL, price DECIMAL, PRIMARY KEY (category, id) ) CREATE TABLE customer ( id INT NOT NULL, PRIMARY KEY (id) ) CREATE TABLE product_order ( no INT NOT NULL AUTO_INCREMENT, product_category INT NOT NULL, product_id INT NOT NULL, customer_id INT NOT NULL, PRIMARY KEY (no), INDEX(product_category, product_id), INDEX(customer_id), FOREIGN KEY (product_category, product_id) REFERENCES product (category, id) ON DELETE RESTRICT ON UPDATE CASCADE, FOREIGN KEY (customer_id) REFERENCES customer (id) )