外键和主键概念题

Foreign and Primary Key Conceptual Questions

我是SQL/PostgreSQL的新手,我有一个关于外键和一般键的概念性问题:

假设我有两个表:Table A 和 Table B.

A 有一堆列,其中两个是 A.id, A.seq。主键是 btree(A.id, A.seq),它有一个 A.id 引用 B.id 的外键约束。请注意,A.seq 是一个顺序列(第一行的值为 1,第二行的值为 2,依此类推)。

现在说B有一堆列,其中一个就是上面提到的B.id。主键是 btree(B.id).

我有以下问题:

  1. btree 到底是做什么的?在 btree 中有两个列名而不是只有一个(如 btree(B.id))有什么意义。
  2. 为什么 A 引用 B 而不是 B 引用 A 很重要?为什么外键的顺序很重要??

非常感谢!如果我对任何内容使用了不正确的术语,请纠正我。

编辑:我正在使用 postgres

你的数据结构没有意义。为什么A的主键会同时有idname?通常它只是 id。在某些数据模型中,您可能添加了版本或时间戳。我想不出一个合理的数据模型,其中还包括 name

此外,B 的外键必须同时指向 idname

但是,您的问题是 btree 的用途是什么?大多数数据库没有这样的选项。主键通常表示为:

id int primary key;
constraint unq_t_id primary key (id);

btree 是一种索引——实际上是我所知道的所有数据库中的默认索引类型。具有大量可用索引类型的数据库(例如 Postgres),您可以指定与主键关联的索引类型。

针对您的问题:

  1. 有几种实现唯一键的策略。最常见的一种是使用使用“b-tree”策略的“唯一”索引。这就是“btree”在 PostgreSQL 中的意思。

    在一个键中有两列仅取决于您要如何设计 table。当您拥有一个包含多个列的键时,称为“复合键”。

  2. A 引用 B 时,B 中的列必须代表一个“键”。 A 中的列不代表一个键,而只是一个 reference。实际上,该列的 A 中的值可以重复;也就是说,A 中的多行可以 指向 B.

    中的同一行

btree 索引按排序顺序存储值,这意味着您不仅可以搜索单个主键值,还可以高效地搜索一系列值:

SELECT ... WHERE id between 6060842 AND 8675309

PostgreSQL还支持其他index types, but only btree is supported for a unique index(例如主键)。

在您的 B table 中,主键是单列 id 意味着 id 中的每个值只能存在一行。换句话说,它是唯一的,如果你通过主键搜索一个值,它最多只能找到一行(如果你没有该值的行,它也可能会找到零行)。

您的 A table 中的主键用于 (id, seq)。这意味着 id 的每个值可以有多个行。 seq 的每个值也可以有多行,只要它们用于不同的 id 值。但是,该组合必须是唯一的。同一对值不能超过一行。

A 中的外键引用 B 时,这意味着该行必须存在于 B 中,然后才能将行存储在 A 中相同的 id 值。但是反过来就没有必要了。

示例:

假设 B 是给用户的,A 是给 phone 的。您必须先存储用户,然后才能存储该用户的 phone 记录。您可以为该用户存储一个或多个 phone,在 A table 中每行一个。我们说 A 中的一行引用了 B 中的用户行,意思是“这个 phone 属于用户#1234。”

但反向不受限制。用户可能没有 phone(至少不为该数据库所知),因此不需要 B 引用 A。换句话说,用户不需要 phone。您可以在 B(用户)中存储一行,即使在 A(phones)中没有该用户的行。

引用还意味着如果另一个 table 中的行引用 B 中的给定行,则您不能 DELETE FROM B WHERE id = ?。删除该用户会导致其他行成为孤立行。如果他们引用的用户行被删除,没有人能够知道这些 phone 属于谁。