Nat*_*ong 6 database-design constraint
在我正在处理的应用程序中,我们有一种“受限制的一对多”关系。我想知道这是否有名称,以及是否可以在数据库级别强制执行。
标准的一对多可能是people
to pets
。一个人可以养多只宠物,每只宠物都属于指定的物种。你可以有 0 只宠物,或者 2 只狗和一只猫,或者只有一只长尾小鹦鹉等等。
在我们的例子中,我们想说“一个人可以有很多宠物,但每种宠物不能超过一只”。你可以拥有 0 只宠物,或者只有一只猫,或者一只狗和一只长尾小鹦鹉,但你永远不能拥有 2 个任何物种。
我只能看到两种方法来做到这一点:
people
为每个可能的宠物的外键(acat_id
和 adog_id
等)设置一列。不过,这意味着NULL
桌子上会有很多s。pets
都有一个指向 的外键people
,并使用数据库外部的代码按物种强制执行唯一性。任何替代想法?
Aar*_*and 11
我不知道您所描述的关系有官方或技术名称(我也不知道您是否会发现许多宠物爱好者希望仅限于一只狗,一只猫等) ,但这是我可能会如何处理这个问题:
CREATE TABLE dbo.People
(
PersonID INT PRIMARY KEY
--, ... name, etc.
);
CREATE TABLE dbo.PetTypes
(
PetTypeID INT PRIMARY KEY
--, ... species name, etc.
);
CREATE TABLE dbo.PeoplePets
(
PersonID INT, -- FK to dbo.People
PetTypeID INT, -- FK to dbo.PetTypes
--, ... pet name etc.
PRIMARY KEY (PersonID, PetTypeID)
);
Run Code Online (Sandbox Code Playgroud)
现在这是否足够简单,我不确定。对于不同类型的宠物,您可能有不同的属性,因此您可能需要对其进行扩展,但我认为总体上这个概念是合理的。
这是一个连接表,您的需求由 Pets 表上的自然键处理。在这种情况下,人和宠物物种之间存在多对多关系。
如果您允许人们随着时间的推移更换宠物,则执行规则会变得更加复杂。在这种情况下,您需要向主键添加第三列(在这种情况下我通常使用日期类型)并使用触发器来强制一次只拥有一个物种的宠物。一个常见的现实例子是职位中的员工。
一个相关的案例是订单详细信息。在这种情况下,一个订单将有一个或多个不同产品的明细行。(我通常对每个订单使用 line_id 递增。)相同的唯一性可能适用于产品,并且可以通过关系上的唯一键来处理。
简单情况的伪代码:
TABLE persons
person_id int, auto increment, not null
...
PRIMARY KEY (people_id)
TABLE species
species_id int, auto increment, not null
...
PRIMARY KEY (species_id)
TABLE pets (people_species)
people_id FK(people), not null
species_id FK(species), not null
....
PRIMARY KEY (person_id, species_id)
Run Code Online (Sandbox Code Playgroud)