同一个 table 中的多对多关系?
Many to many relationship in the same table?
我是设计数据库的新手,我想知道在同一 table 中的行之间实现多对多关系的规范方法是什么。
在我的例子中,我有一个 table 的公式,我想说 table 中的两个公式是相关的:
公式table:
formula_id SERIAL PRIMARY KEY
name TEXT NOT NULL
formula TEXT NOT NULL
我假设我会创建一个名为 related_formulas 的新 table,然后执行如下操作:
formula_relation_id SERIAL PRIMARY KEY
formula_id INT REFERENCES formulas (formula_id) ON DELETE CASCADE
formula_id2 INT REFERENCES formulas (formula_id) ON DELETE CASCADE
但后来我预见到一些问题,例如阻止同一行中的两个 id 具有相同的值。我敢肯定,由于我自己的经验不足,我还没有看到其他潜在的问题。
有人能给我指出正确的方向吗?
从 SERIAL
我假设 PostgreSQL...
CREATE TABLE formula_relation (
formula_relation_id SERIAL PRIMARY KEY,
formula1_id INT REFERENCES formulas (formula_id) ON DELETE CASCADE,
formula2_id INT REFERENCES formulas (formula_id) ON DELETE CASCADE,
CHECK (formula1_id < formula2_id)
);
(我还假设你的关系是对称的,所以 i
与 A[i]
相关也意味着 A[i]
与 i
相关;因此,有 formula1_id < formula2_id
确保行只能有一个规范的变体,并且您不需要检查反向配对。如果关系不对称,您应该 CHECK (formula1_id != formula2_id)
.)
Amadan 的回答很好地确保以一种规范的方式插入数据,但是如果您不想在插入公式时将数据库用户限制为特定顺序(这是由 CHECK (formula1_id < formula2_id)
在 Amadan 的答案),你可以考虑:
CREATE TABLE formula (
id int PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
formula_name text NOT NULL,
formula text NOT NULL
);
CREATE TABLE formula_formula_relation (
id int PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
formula1_id int NOT NULL REFERENCES formula ON DELETE CASCADE,
formula2_id int NOT NULL REFERENCES formula ON DELETE CASCADE,
CHECK (formula1_id <> formula2_id),
CONSTRAINT already_related_formulas_not_allowed_again EXCLUDE USING gist (
LEAST (formula1_id, formula2_id) WITH =,
GREATEST (formula1_id, formula2_id) WITH =
)
);
(您可能需要 运行 CREATE EXTENSION btree_gist;
)
我是设计数据库的新手,我想知道在同一 table 中的行之间实现多对多关系的规范方法是什么。
在我的例子中,我有一个 table 的公式,我想说 table 中的两个公式是相关的:
公式table:
formula_id SERIAL PRIMARY KEY
name TEXT NOT NULL
formula TEXT NOT NULL
我假设我会创建一个名为 related_formulas 的新 table,然后执行如下操作:
formula_relation_id SERIAL PRIMARY KEY
formula_id INT REFERENCES formulas (formula_id) ON DELETE CASCADE
formula_id2 INT REFERENCES formulas (formula_id) ON DELETE CASCADE
但后来我预见到一些问题,例如阻止同一行中的两个 id 具有相同的值。我敢肯定,由于我自己的经验不足,我还没有看到其他潜在的问题。
有人能给我指出正确的方向吗?
从 SERIAL
我假设 PostgreSQL...
CREATE TABLE formula_relation (
formula_relation_id SERIAL PRIMARY KEY,
formula1_id INT REFERENCES formulas (formula_id) ON DELETE CASCADE,
formula2_id INT REFERENCES formulas (formula_id) ON DELETE CASCADE,
CHECK (formula1_id < formula2_id)
);
(我还假设你的关系是对称的,所以 i
与 A[i]
相关也意味着 A[i]
与 i
相关;因此,有 formula1_id < formula2_id
确保行只能有一个规范的变体,并且您不需要检查反向配对。如果关系不对称,您应该 CHECK (formula1_id != formula2_id)
.)
Amadan 的回答很好地确保以一种规范的方式插入数据,但是如果您不想在插入公式时将数据库用户限制为特定顺序(这是由 CHECK (formula1_id < formula2_id)
在 Amadan 的答案),你可以考虑:
CREATE TABLE formula (
id int PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
formula_name text NOT NULL,
formula text NOT NULL
);
CREATE TABLE formula_formula_relation (
id int PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
formula1_id int NOT NULL REFERENCES formula ON DELETE CASCADE,
formula2_id int NOT NULL REFERENCES formula ON DELETE CASCADE,
CHECK (formula1_id <> formula2_id),
CONSTRAINT already_related_formulas_not_allowed_again EXCLUDE USING gist (
LEAST (formula1_id, formula2_id) WITH =,
GREATEST (formula1_id, formula2_id) WITH =
)
);
(您可能需要 运行 CREATE EXTENSION btree_gist;
)