如何设计数据库约束,以便两个实体只有在两个字段值匹配时才能具有多对多关系?
我有一个包含四个表的数据库,如下所示:
地址簿
--------------------
id
更多字段
联系方式
----------------------------------
id
地址簿 ID
更多领域
群组
----------------------------------
id
地址簿 ID
更多字段
联系人组
----------------------------------
复合键
群组 ID
联系 ID
我的关系是一对多的地址簿 >联系人,地址簿一对多>组以及联系人和组之间的多对多。
总而言之,我有一个地址簿。联系人和群组可以存储在其中,并且不能存储在多个地址簿中。此外,可以将所需数量的联系人添加到所需数量的组中。
我现在的问题如下。我希望添加一个约束,即如果联系人都具有相同的地址簿 ID,则他们只能成为群组的成员。
由于我不是数据库人员,这让我感到困惑。这是否意味着我的表结构设计错误?或者这是否意味着我必须在插入组到联系人表之前在某处添加检查?这对我来说似乎是错误的,因为我希望如果联系人没有相同的 ID,SQL 查询就不可能将联系人链接到组。
I have a database with four tables as follows:
Addressbook
--------------------
id
more fields
Contact
---------------------
id
addressbook id
more fields
Group
---------------------
id
addressbook id
more fields
Group to Contact
---------------------
Composite key
Group id
Contact id
My relationships are one to many for addressbook > contact, one to many for addressbook > group and many to many between contact and groups.
So in summary, I have an addressbook. Contacts and groups can be stored within it and they cannot be stored in more than one addressbook. Furthermore as many contacts that are needed can be added to as many groups as are needed.
My question now poses as follows. I wish to add the constraint that a contact can only be a member of a group if both of them have the same addressbook id.
As I am not a database person this is boggling my brain. Does this mean I have designed my table structure wrong? Or does this mean that I have to add a check somewhere before inserting into the group to contact table? This seems wrong to me because I would want it to be impossible for SQL queries to link contacts to groups if they do not have the same id.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您应该能够通过向联系人组桥接表添加addressbook_id列,然后对联系人使用复合外键来实现此目的> 和组表。
在 PostgreSQL 中(但可以轻松适应任何数据库,或者至少是支持复合 FK 的任何数据库):
通过在两个约束中使用相同的 addressbook_id 列,您当然可以强制它们在两个约束中相同参考表。
You should be able to accomplish this by adding a addressbook_id column to your Group to Contact bridge table, then using a compound foreign key to both the Contacts and Groups tables.
In PostgreSQL (but easily adaptable to any DB, or at least any DB that supports compound FKs):
By using the same addressbook_id column in both constraints, you are of course enforcing that they are the same in both referenced tables.
好的 - 多对多由 GroupToContact 表管理。
因此,约束位于 Group 和 GroupToContact 之间以及 Contact 和 GroupToContact (GTC) 之间
,即
,因此
您需要将 AddressBookId 添加到 GroupToContact 表中。
进一步注意 - 您不应该直接定义 Contact 和 Group 之间的任何关系 - 相反,您只需定义 OneToMany每个与 GroupToContact 表都有关系。
OK - the Many to Many is governed by the GroupToContact table.
So the constraints are between Group and GroupToContact and between Contact and GroupToContact (GTC)
Namely
And
So you will need to add AddressBookId to GroupToContact table
One further note - you should not define any relationship between Contact and Group directly - instead you just define the OneToMany relationships each has with the GroupToContact table.
正如 BonyT 建议:
As BonyT suggestion:
作为 CHECK 约束不能包含子查询。
您可以创建一个触发器来检查组和联系人是否具有相同的地址簿 ID
如果不这样做,则会生成错误。
尽管定义为强制执行完整性规则的数据库触发器不会检查表中已有的数据,但我建议您仅在完整性约束无法强制执行完整性规则时才使用触发器。
注意:(这是从记忆中得出的,因此语法上可能不正确)
As A CHECK Constraint can't include sub-queries.
You could create a trigger that checks that the group and contact have the same addressbookid
and generate an error if they do not.
Although a database trigger defined to enforce an integrity rule does not check the data already in the table, I would recommended that you use a trigger only when the integrity rule cannot be enforced by an integrity constraint.
Note:(This is from memory so probably not syntactically correct)
在您的 ER(实体关系)模型中,实体 Group 和 Contact 是(或应该是)“依赖实体”,也就是说,存在 < em>组或联系人基于1个或多个其他实体(在本例中AddressBook),它们有助于身份 依赖实体的。依赖实体的主键是复合的,并且包括它所依赖的实体的外键。
联系人和组的主键都包含其所属地址簿的主键。一旦你这样做了,一切就水到渠成了:
干杯。
In your E-R (Entity-Relationship) model, the entities Group and Contact are (or should be) "dependent entities", which is to say that the existence of a Group or Contact is predicated upon that of 1 or more other entities, in this case AddressBook, that contributes to the identity of the dependent entity. The primary key of a dependent entity is composite and includes foreign keys to the entity(ies) upon which it is dependent.
The primary key of both Contact and Group include the primary key of the AddressBook to which they belong. Once you do that, everything falls into place:
Cheers.