【发布时间】:2023-03-23 03:42:01
【问题描述】:
情况:
一家公司有很多项目
一个项目有很多标签
一个项目只属于一家公司
一个标签可以属于多个项目
公司必须有权访问自己的标签
示例 1:
在第一张图片中,公司的所有标签都可以通过 projects/project_tag 获得。但是如果所有项目都被删除,那么公司的标签将无法再访问,因为 project_tag 和项目之间的链接已经消失。 标签应该总是与公司相关联,即使没有项目。
示例 2(其中标签也与公司相关联):
在第二张图片中,它应该可以工作,但这现在是“循环引用”吗? 对于这样的问题,最好的解决方案应该是什么? 那么外键呢?
问题最后是: 如何针对这种情况正确设置数据库/数据模型?
第二个例子中可能出错的例子:
companies:
id=1, name=MyCompany
id=2, name=OtherCompany
tags:
id=1, company_id=1, name=MyTag
id=2, company_id=2, name=OtherTag
projects:
id=1, company_id=1, name=MyProject
project_tag:
project_id=1, tag_id=1
project_id=1, tag_id=2 --> THIS ROW IS NOT VALID!
最后一个 project_tag 行无效,因为:
project 1 已链接到 company_id 1
tag_id 2 已链接到 company_id 2
更新:感谢大家提供的信息!
根据接受的答案,PostgreSQL 的 CREATE 查询将变为:
CREATE TABLE companies (
id SERIAL PRIMARY KEY NOT NULL,
name TEXT NOT NULL
);
CREATE TABLE projects (
id SERIAL PRIMARY KEY NOT NULL,
company_id INT NOT NULL,
name TEXT NOT NULL,
UNIQUE (id, company_id),
FOREIGN KEY (company_id) REFERENCES companies (id) ON DELETE RESTRICT ON UPDATE CASCADE
);
CREATE TABLE tags (
id SERIAL PRIMARY KEY NOT NULL,
company_id INT NOT NULL,
name TEXT NOT NULL,
UNIQUE (id, company_id),
FOREIGN KEY (company_id) REFERENCES companies (id) ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE TABLE project_tag (
id SERIAL PRIMARY KEY NOT NULL,
company_id INT NOT NULL,
project_id INT NOT NULL,
tag_id INT NOT NULL,
UNIQUE (company_id, project_id, tag_id),
FOREIGN KEY (company_id, project_id) REFERENCES projects (company_id, id) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (company_id, tag_id) REFERENCES tags (company_id, id) ON DELETE CASCADE ON UPDATE CASCADE
);
已测试:
- 在 same company_id 上检查插入 project_tag 的行(否则: 拒绝)
- 无法将重复行插入到 project_tag
- 如果项目被删除,则链接的 project_tag 行也会被删除
- 如果标签被移除,则链接的 project_tag 行 也会被移除
- 如果公司在仍有项目的情况下被移除,则移除被拒绝(参见项目表:ON DELETE RESTRICT)
- 如果一个公司(没有项目)被删除,所有链接的标签也会被删除
【问题讨论】:
-
“循环引用”没有错。请解释你认为一个是什么以及为什么你认为他们有问题。你的问题是基于误解。此外,基数不足以进行设计。您必须给出感兴趣的关系(船)/关联的含义——每个都由一个表/关系表示。 (“有”、“属于”和“链接到”是无可救药的笼统。)然后考虑到可能出现的情况,找到约束——基数反映了其中的一些。阅读信息建模和关系数据库设计简介,包括对更高 NF 的规范化。
标签: database database-design relational-database circular-reference datamodel