2011-12-19 38 views
4

我一直在尝试几天来设计这个数据库。我在访问中设计它,然后在MYSQL服务器上实现为PHP Web应用程序。SQL成员表显示成员之间的家庭关系

我有一个表:

成员

  • MEMBERID(自动编号,PK)
  • 成员名称
  • MemberDetails

成员可以与其他成员的许多关系,这可能是孩子,家长,朋友,S看到一位会员,我希望能够与现有会员建立新的关系,然后让相关会员看到这种关系,而无需进一步的投入。成员也应该能够列出他们所有的关系。

你能告诉我应该怎么做吗?我尝试了几个选项,但没有一个看起来像预期的那样工作。我对SQL感到满意,我只是在Unary关系设计上遇到了麻烦。

-edit- 此外,我忘了添加,由于服务器的限制,无法使用INNODB。最有可能的将是MYISAM,但我还是想引用完整性:(

+0

我认为你需要检讨你的真实生活标识符。一个人的名字很少(大概是“家庭事务[原文如此]”表明共享姓氏!)和一个autoNumber PK将只允许重复的人进入数据库,而不是消除重复。标识符必须标识人员,据推测他们不知道系统分配给他们的自动编号值。 – onedaywhen

+0

对不起,我简化了数据库表。实际PK是:MemberID,FirstName,LastName。姓氏不适用于朋友和女朋友。我正在努力专注于如何将会员与海誓山盟联系起来。 –

回答

0

尝试添加的数据透视表:

Relationships: 

MemberId1 
MemberId2 
RelationshipType 
+0

我看了一下,不确定如何实现这一个到我的设计。 –

0

与collumns创建一个表:

Member_1_id 
Member_2_id 
Relation_type 

然后你可以使用它像那: 如果爱丽丝是鲍勃女儿,你会有这些关系:

<Bob id> <Alice id> 'Father' 
<Alice id> <Bob id> 'Daughter' 

然后,您可以将一些额外的数据放入这些关系中,例如关系何时开始(即,当有人订婚)。

您可能还希望在具有成员id的两列上创建索引。

编辑: 为了避免重复此表中的数据,您可以创建一个视图,然后将每个关系存储为只有一行。然而,这种解决方案不会让你命名像“父亲”和“儿子”这样的关系。

SELECT member1, member2, relation FROM rel_table UNION ALL SELECT member2, member1, relation FROM rel_table; 
+0

谢谢,我试过这种方法,我看不到如何解决重复数据输入问题,这是我试图避免的一个问题。 –

+0

如果没有重复的数据输入,你将失去调用关系'儿子'和'父亲'的能力,你必须给这个关系的'方向'命名同一个名字。 如何使用视图?然后,您可以将每个成员对存储在关系表中,并且仍然可以轻松使用它。 – Maciek

4

让表members包含成员数据和表relations包含成员关系数据。 relations.member_id将会引用会员relations.related_member_id - 发送给相关会员。 relations.type是可枚举的关系类型。

CREATE TABLE `members` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , 
`name` TEXT NOT NULL , 
`details` TEXT NOT NULL 
) ENGINE = INNODB; 

CREATE TABLE `relations` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , 
`member_id` INT NOT NULL , 
`related_member_id` INT NOT NULL , 
`type` ENUM( 'Child', 'Parent', 'Friend', 'Spouse') NOT NULL, 
FOREIGN KEY (member_id) REFERENCES members(id), 
FOREIGN KEY (related_member_id) REFERENCES members(id) 
) ENGINE = INNODB; 

UPD:的MyISAM版(除去外键,所有可能的外键的功能应该由服务器端脚本处理):

CREATE TABLE `members` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , 
`name` TEXT NOT NULL , 
`details` TEXT NOT NULL 
) ENGINE = MyISAM; 

CREATE TABLE `relations` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , 
`member_id` INT NOT NULL , 
`related_member_id` INT NOT NULL , 
`type` ENUM( 'Child', 'Parent', 'Friend', 'Spouse') NOT NULL 
) ENGINE = MyISAM; 
+0

对不起,我忘了补充说,由于服务器限制,无法使用INNODB。很可能会是MYISAM。否则,这种解决方案将是完美的,(我最初设计的,直到这个小呃被抛出我的方式) –

+0

然后使用MyISAM并删除外键。您必须使用PHP处理外键功能。我用MyISAM表格更新了我的回复。 – Minras

2

与@Minras设计开始(+1),我倒是有

MEMBERS 
    MemberId 
    Name 
    Details 

RELATIONS 
    FromMemberId 
    ToMemberId 
    RelationType 

但不是检查约束,我想补充第三个表:

RELATIONTYPE 
    RelationType 
    Description 
    FromLabel 
    ToLabel 

其中RelationType是一个整数,“Labels”是字符数据。这种关系是“定向的”,因为你必须密切关注哪个成员是“来自”,哪个是“来”(但对于“非定向”关系并不那么重要,比如“去高中一起”)。此设计可让您:

  • 定义具有多个标签的人之间的关系,例如, A is father of BB is son of A
  • 如果,当添加新的关系,并在必要时

显然,你要么必须通过外键或一切关系完整性不管你有可用的,否则你将有一个火车事故等待发生。

这并没有解决如何唯一清晰地标识具有重复名称的成员的问题。要做到这一点,您需要考虑“真实世界中的人们用于处理这种情况(学生ID?社会安全号码?)所用的识别属性,或者引入特定于您的应用程序的工件(例如,登录名+密码)。

+0

第三张桌子不是那么有效。 –