数据库内部结构:外键约束的实现
PostgreSQL在创建外键约束时没有为其创建索引,而是创建了一些触发器。这可能是因为在创建外键时,PostgreSQL为引用表创建了一个哈希映射,并对引用表的每一行执行了一次探测。
与此不同,MonetDB为主键和外键创建了不同类型的索引,可能是连接索引和哈希索引。
另外,Oracle使用索引来强制实施主键约束,默认情况下不为外键创建任何索引,但有一些外键索引的提示。
因此,问题的原因是PostgreSQL在创建外键约束时没有为其创建索引。解决方法可能是手动创建索引或使用其他数据库管理系统,如MonetDB或Oracle。
文章整理如下:
PostgreSQL在创建外键约束时没有为其创建索引,而是创建了一些触发器。这可能是因为在创建外键时,PostgreSQL为引用表创建了一个哈希映射,并对引用表的每一行执行了一次探测。与此不同,MonetDB为主键和外键创建了不同类型的索引,可能是连接索引和哈希索引。另外,Oracle使用索引来强制实施主键约束,默认情况下不为外键创建任何索引,但有一些外键索引的提示。因此,问题的原因是PostgreSQL在创建外键约束时没有为其创建索引。解决方法可能是手动创建索引或使用其他数据库管理系统,如MonetDB或Oracle。
在Postgres中,主表中的引用列需要具有UNIQUE或PRIMARY KEY约束条件。根据文档:
引用列必须是引用表中非延迟唯一或主键约束的列。
这两个约束条件都是使用B树索引实现的。因此,引用列上始终存在B树索引:
如何强制PostgreSQL唯一约束/使用什么类型的索引?。
引用列不需要索引。如果主表中的行永远不会被更新或删除,这可能足够了。否则,引用列也应该有索引,但系统不会强制执行。这只是关于性能优化,而不是数据完整性。
外键约束本身的实际实现是系统目录pg_constraint中的一个条目,一个特殊的内部触发器和pg_depend中的另一个条目。
作为回答,谢谢。据我所知,当定义新的主键时,默认情况下会创建B+树索引(因此,这是一个CPU密集型任务,因为在创建B+树之前必须对行进行排序)。我观察到在postgres中创建FK时涉及了很多哈希,因此我推断除了pg_constraint和pg_depend中的新条目之外,可能还会在引用列上创建其他结构(可能是基于哈希的索引)。
.cajf:除了我已经列出的内容之外,不会创建任何其他结构。您观察到的是关系完整性的验证。在创建过程中,Postgres必须确保现有的值符合新的约束条件。
是的,检查值是否存在是有意义的,但在这种情况下,应该使用主键上的B+树索引。那么,为什么有很多哈希操作?
.cajf:我不确定您的意思。但是,当访问大部分表时,索引几乎没有用。该索引可能不会用于此特定目的。
您可能看到的是主键和外键之间的外连接的实现,以检测主键中不存在的外键条目。