数据库内部:外键约束的实现
问题:数据库内部:外键约束的实现 例如,在 PostgreSQL 中,外键是如何实现的? 我注意到在创建外键时涉及很多散列,所以我假设在引用主键列的外键列上创建了一个基于散列的索引。如果是这样(例如,当我们想从被引用的表中删除一行时——这个带有主键的行或所谓的主表),我们可以轻松地检查被引用表中的行是否实际被引用。更重要的是,可能DBMS要求引用的主键列上至少有一个B+树索引,因为当我们要向引用表
问题:数据库内部:外键约束的实现
例如,在 PostgreSQL 中,外键是如何实现的?
我注意到在创建外键时涉及很多散列,所以我假设在引用主键列的外键列上创建了一个基于散列的索引。如果是这样(例如,当我们想从被引用的表中删除一行时——这个带有主键的行或所谓的主表),我们可以轻松地检查被引用表中的行是否实际被引用。更重要的是,可能DBMS要求引用的主键列上至少有一个B+树索引,因为当我们要向引用表插入新行时,我们可以很容易地检查是否存在具有所需主键值的行在参考表中。一些消息来源声称使用触发器来确保外键约束。
解答
我检查了一下,确实,PostgreSQL 没有为外键创建索引(使用此查询:https://stackoverflow.com/a/25596855/1245175)。
另一方面,为外键创建了一些触发器:
test=# SELECT tgname AS trigger_name
FROM pg_trigger
WHERE tgname !~ '^pg_';
trigger_name
--------------
(0 rows)
test=# ALTER TABLE LINEITEM ADD CONSTRAINT LINEITEM_FK1 FOREIGN KEY (L_ORDERKEY) REFERENCES ORDERS;
ALTER TABLE
test=# SELECT tgname AS trigger_name
FROM pg_trigger
WHERE tgname !~ '^pg_';
trigger_name
------------------------------
RI_ConstraintTrigger_a_16419
RI_ConstraintTrigger_a_16420
RI_ConstraintTrigger_c_16421
RI_ConstraintTrigger_c_16422
因此,我假设在 PostgreSQL 中创建外键期间,会为引用的表创建一个哈希映射,然后对引用表的每一行执行一次探测。
有趣的是,MonetDB 为主键和外键创建了不同类型的索引(可能分别是连接索引和哈希索引)。
sql>select * from sys.idxs;
+------+----------+------+-------------+
| id | table_id | type | name |
+======+==========+======+=============+
| 6467 | 6446 | 0 | orders_pk |
| 6470 | 6464 | 1 | lineitem_fk |
+------+----------+------+-------------+
2 tuples (3.921ms)
此外,Oracle 使用索引强制执行主键约束,默认情况下它不会为外键创建任何索引,但是,有一些外键索引提示:https://asktom.oracle.com/pls/asktom/f ?pu003d100:11:0::::P11_QUESTION_ID:292016138754
更多推荐
所有评论(0)