通过多对多关系应用非空约束?

时间:2013-11-27 23:14:59

标签: sql postgresql

我需要确保数据库中的每个项目都有联系人。 “projects”和“contacts”具有多对多关系,在“projects_contacts”表中指定。我可以在项目中创建一个表约束,指定项目必须存在于连接表中吗?或者我需要采取完全不同的方法吗? (我需要用户能够在添加项目数据的过程中手动输入联系人数据,所以我担心NOT NULL会在联系之前挂起他们创建项目的能力。)

在构建用户界面时,这会更好地解决吗?

谢谢!

CREATE TABLE projects(
id_project INTEGER PRIMARY KEY,
description text)

CREATE TABLE contacts(
id_contact integer PRIMARY KEY
firstname varchar(100) )

CREATE TABLE projects_contacts(
id_projects_contacts integer PRIMARY KEY,>
id_project integer,
id_contact integer
CONSTRAINT FOREIGN KEY project_fkey (id_project) REFERENCES projects ON UPDATE CASCADE ON DELETE CASCADE
CONSTRAINT FOREIGN KEY contact_fkey (id_contact) REFERENCES contacts ON UPDATE CASCADE ON DELETE CASCADE)

2 个答案:

答案 0 :(得分:1)

使用表级约束实现此操作的唯一方法是projects包含对projects_contacts中任何条目的不可为空的外键引用。 但这将是一个循环引用,因为projects_contacts也依赖于`projects。

你说你不想强迫用户在创建项目时输入联系人,所以基本上你不能用这样的非可空引用约束项目。

没有约束意味着“我需要这个非空,但是后来。”在任何约束的定义中,它必须在您结束交易时满足。

因此,大多数人可以推迟约束,直到提交为止: http://www.postgresql.org/docs/9.3/static/sql-set-constraints.html

我假设您需要推迟的时间长于一笔交易的长度。

最终,这些类型的自定义业务规则最终会被您必须开发的应用程序代码强制执行。

答案 1 :(得分:1)

如果必须在项目中包含联系人,那么除非联系人数据(或密钥,如果已存在)是交易的一部分,否则您的GUI不应发送添加请求。

这样,您不需要FK来允许空值。

但是,从商业角度来看,如果联系人不再是项目的联系人并且没有分配替代联系人,您会怎么做?

在这种情况下,您的企业应该做出决定。如果是这样,FK必须在更新时允许空值。

要结合这两种情况,您的FK应该允许空值,但您的业务层不应接受使用null contact fk创建项目事务。

您还需要考虑这个业务问题:如果没有项目,联系人是否可以存在?答案在GUI设计中很重要。

根据您的声明“我需要用户能够在添加项目数据的过程中手动输入联系人数据” - 只有当联系人直接添加到当前项目时才对我有意义,但如果用户开始创建项目,创建联系人然后放弃创建项目的过程?您如何识别添加的联系人?所以,您可能希望改进此要求。