PostgreSQL 代码中的 0 对多和 1 对多关系

问题描述 投票:0回答:2

来自

https://www.postgresql.org/docs/current/ddl-constraints.html
上关于外键约束的 PostgreSQL 文章:

假设您有产品表:

CREATE TABLE products (
    product_no integer PRIMARY KEY,
    name text,
    price numeric
);

我们还假设您有一个存储这些产品订单的表。 我们要确保订单表只包含订单 实际存在的产品。所以我们定义了一个外键约束 引用产品表的订单表:

CREATE TABLE orders (
    order_id integer PRIMARY KEY,
    product_no integer REFERENCES products (product_no),
    quantity integer
);

现在无法使用非 NULL product_no 条目创建订单 没有出现在产品表中。

这是0对多的关系吗?

如何设置一对多关系?

通过这样做?

CREATE TABLE orders (
    order_id integer PRIMARY KEY,
    product_no integer REFERENCES products (product_no) NOT NULL,
    quantity integer
);

如果是这样,为什么 pgadmin4 在我按上面的方式配置表时会生成表示零对多的鱼尾纹符号?

postgresql foreign-keys erd cardinality
2个回答
0
投票

鱼尾纹表示零对多关系。

不,它没有。不要将基数(方向性的)与关系类型混淆。圆圈表示

orders
基数的下限(并且可以省略) - 请参阅“多”与“零或多”/“一或多”crowfoot notation? on Software Engineering.

product_no
标记为
NOT NULL
只会将零或一对多关系更改为恰好一对对多关系。两者通常被称为“一对多”或“1:N”关系。对于
products
的基数,这将表示为破折号或破折号圆(或者,含糊地,只是破折号)。

现在乌鸦脚上的圆圈(或破折号)就在many边(

orders
) - 是…-to-零或-many还是…-to-one-or-many ?在您的模式中,它确实是一个零或多个基数,因为可以有任意数量的
orders
-包括
0
-对于
product
.

请注意,实际的

0,1:1,N
1:1..N
1..N:1..N
关系(不是
…:0,N
)出奇地难以在 SQL 中表示,因为您遇到了先有鸡还是先有蛋的问题,请参阅 如何创建真实关系-SQL Server 中的一对一关系1:N 关系,其中 N 必须至少是一个条目)。


0
投票

你是对的,工具错了

教程中的外键约束确保

product_no
中的值必须存在于表
products
中。但是外键可以是
NULL
,在这种情况下没有值,并且存在检查不适用(另见外键可以为NULL和/或重复)。

这就是为什么第一个关系是可选的一对多(有时被滥用地称为零对多)。在鱼尾纹中,这原则上会用空心圆(代表可选的 O)和三叉戟来表示。有时不指示关系的可选或强制性特征(即只有三叉戟)。

要将约束从可选更改为强制性,您确实只需将外键指定为

NOT NULL
,就像您在第二个选择中所做的那样。

工具限制

我不是 pgadmin4 的专家,但快速浏览一下 图表工具文档 表明它只知道一对多和多对多关系,并且对话不允许有所作为介于可选和强制之间。例如,它是一个 known bug,它不能表示一对一的关系。

查看文档中的图表,在similar SO questions 和官方问题跟踪器中,图表工具似乎只知道:

对很多人

一个

这意味着该工具不能区分强制性(双杠代表一个,杠和三叉戟代表许多)和可选(圆形杠代表一个,圆形三叉戟代表许多),并且所使用的符号应理解为未指定对此。因此,小点不应被理解为可选的,而只是作为鱼尾纹三叉戟的奇特符号。

结论

由于图表工具无法处理这些微妙之处,因此从 SQL 语句进行的逆向工程无法以准确的方式表示这些变化,即使它有算法可以在约束中检测到它们。

© www.soinside.com 2019 - 2024. All rights reserved.