2014-10-11 87 views
1

您认为哪种方法是定义1:1关系(如配偶)的最佳方式?在数据库中表示1:1关系的最佳方式是什么

在我的实际数据库中,我有一张人们的桌子,其中一些人将被分类为与桌子上的其他人“共同”(因此该人将因此与原始人联合)。 '联合'将用于确定每个人的付款。

我能有这样的事情

PERSON 
------ 
Person_ID (PK) 
Name 
Phone 
Joint_With_ID (FK) 

其中Joint_With_ID要么是空或包含它们的联合与记录的PERSON_ID(和这个人的记录中包含的第一人的PERSON_ID),但我我不喜欢故意的空值。

我也可以有两个表

PERSON     PERSON_JOIN 
------     ----------- 
Person_ID (PK)   Joined_ID  (PK) 
Name      Person_ID 
Phone      Joined_With_Person_ID 

,并在PERSON_JOIN两个记录的每对夫妇是共同 即

Person_ID Joined_With_Person_ID 
    5    8 
    8    5 

两种情况提高PERSON1的可能性被记录为联合person2,但没有与person1联合的person2的记录。

我甚至可以在每个加入的PERSON_JOIN中只有一条记录,并且在尝试查看某个人是联合和谁时使用SQL来搜索这两个字段。但那太可怕了!

那么......最好的方法是什么?

+0

*“并在PERSON_JOIN两个记录的每对夫妇是联合” *所以没有区别在元组{5,8}和{8,5}之间的信息中?我问,因为你在谈论付款,在一些应用程序中,这两个元组意味着两件不同的事情。 – 2014-10-11 16:53:08

+0

是的,我更喜欢那种方法,但是你说的话是正确的,也让我担心 - 因此我的问题。应用程序需要知道某人是否与其他人一起决定是否支付联合费用或个人费用。如果他们是联合的,那么加入双方将支付联合费用。但是,正如你所说,其中一个元组是冗余的,只要用于查看一个人是否加入的sql可以考虑这两个字段。我宁愿以某种方式将其构建到架构中。 – user3209752 2014-10-11 17:45:36

+0

我没有说其中一个元组是冗余的。我说过,在一些应用中,这两个元组意味着不同的东西。 – 2014-10-11 17:58:43

回答

0

在我实际的数据库我的人,其中有些人会 被归类为表中的其他人(而 人因此将联合与原来的人)“联合”的表。 '联合'将用于确定每个人的[原文]支付。

通常的方法在一个SQL数据库做,这是对ID号强加一个秩序,保证了检查约束的顺序。这假定元组{5,8}与元组{8,5}的意思相同,并假定一个人不能与自己一起加入。在这里小心点。

如果我有“8嫁给5,5嫁给8”,我会认为这些意思是同一件事。但“8是5的依赖”并不意味着“5是8的依赖”。

create table person_join (
    person_id integer not null references person (person_id), 
    joined_with_person_id integer not null references person (person_id), 
    primary key (person_id), 
    check (person_id < joined_with_person_id) 
); 

如果您需要加入多人,更改主键约束

primary key (person_id, joined_with_person_id), 

你可能需要额外的指标,因为你或多或少需要独立查询两列。

create index on person_join (joined_with_person_id); 

如果你需要知道的人“5”是否有任何加入的人,你可以

select * 
from person_join 
where person_id = 5 
    or joined_with_person_id = 5; 
+0

这似乎是最好的折衷办法,人员表中没有空值,只有一个记录需要在连接表中。用户界面将阻止自我加入,因为用户只能在创建联合记录时从所有“其他”人员中选择某个人。 – user3209752 2014-10-11 18:38:46

0

配偶关系通常不是1:1 - 并非每个人都有配偶。它更像'0或1'到'0或1',忽略了一夫多妻制和一妻多夫的社会。有些但不是全部的人都有配偶,而有配偶的人一次最多只有一个配偶。 (记录谁是谁的配偶是另一个单独的bag'o'worms。)

因此,您的PERSON_JOIN模式设计是两个更好的。

+0

是的,那是我的想法也是。在这种情况下,不是真正的配偶,这个人要么没有联合的人。如果他们这样做,那么这个人也有一个联合的人(另一个人)。我担心的是,SQL负责确保每个插入插入两条记录,每个删除删除两条记录,每个更新至少更新2条记录,但最多可以记录4条记录(如果personA不再与personB联合但与personC联合 - 并且最终人格C已经与人B联合在一起(并且可能不再与人物联合)。这就是一个脆弱的SQL! – user3209752 2014-10-11 17:35:06

+0

如果你一次这样做,那么它不需要停在4条记录:如果你有A = B,C = D,E = F,G = H之前,你做任何改变,然后,A = C,B = E,D = G,你仍然有新的任务让F和H担心。为简化起见,您需要分两步进行重新分配;对所有受影响的参与方取消分配步骤(给定A = B和C = D之前,A = C之后,然后取消分配A,B,C和D,然后分配A和C),这就限制了损害,你确定这种关系总是互惠的吗?对于配偶而言,对社交网站上的朋友来说,事实并非如此。在你理解你的数据。 – 2014-10-11 17:47:00

+0

互惠,是的。商业规则说,如果两个人(只有两个)是“合作伙伴”并居住在同一个地址,那么他们是共同的。这个应用程序的用户将决定他们是否联合并且将创建'加入'记录,也许当第二个人被插入到人员表中时,也许以后,当'加入'被定义为已经发生时。 (我正在编辑我的评论,以考虑你突出显示的事件链,但是网站不允许这样做,我必须考虑推动你提出的sql,因为人桌中的每个人都可能会交换! ) – user3209752 2014-10-11 17:57:18

相关问题