2012-04-27 52 views
1

我有编码一多了一些困难,许多关系:需要的编码多了一些建议和反馈:在MySQL

enter image description here

我想这些:一对多的关系,如下图所示的图像表和关系设置,以便:

  • 家长可以有一个以上的孩子(这里的孩子是 “播放器”),和一个孩子可以有一个或更多的家长(最多 二) 。
  • “家庭”可以由一个或多个父母(最多两个), 以及一个或多个孩子(无限)组成。

我不知道如何适应父母的姓氏不同于他们的“孩子”,反之亦然。我还没有被告知这是否会成为问题,但这是我认为值得考虑的事情。 Parent和Player类都继承了人类超类的字段(如名字,姓氏,地址,年龄,d.o.b等)。

我正要测试一些输入到家庭餐桌,当我意识到我并不完全知道如何插入一个或更多的家长与一个或一个以上的孩子,他们的父母(或照料者)。我认为我理论上已经理清了这一点,但经过测试后,我意识到它不会工作,我已经花了90多分钟时间对一些想法进行草图绘制,但我真的迷失了方向。

============================================= =====================================

UPDATE:27-04-2012 @ 22:19 NZST

我应该给出一个我正在寻找的结果的可视化表示 - 当查询一个包含这些表的数据库时。这里是直观表示法:

+-------------------+-----------------+---------------------+ 
| ParentsFirstName | ParentsLastName | ChildrenInFamily | 
+-------------------+-----------------+---------------------+ 
| Gregory   | Peck   | Michael    | 
| Laura    | Peck   | Michael    | 
| Martha   | Petersen  | Matt, Christopher | 
| Chris    | Michaels  | Richard, Shaun  | 
| Nadine   | Michaels  | Richard, Shaun  | 
| Barry    | Dackers   | Harry    | 
| Kevin    | Mitchell  | Daniel    | 
| Rebecca   | Mitchell  | Daniel    | 
+-------------------+-----------------+---------------------+ 

“孩子”在一个名为“玩家”的表中,父母在一个名为“父母”的表中。在这篇文章中的MySQL代码代表涉及这个特定问题的表(你应该注意到我使用Person类作为超类,而父/子表作为子类)。通过使用外键引用其他一些表格(“学校ID”字段来自名为“学校”的表格,其具有“学校名称”字段)。

我不确定我是否已经为我想实现的目标构建了表格,但是通过做一些研究,我发现了一个名为GROUP_CONCAT的函数,它至少给了我一个关于查询可能的外观的函数 - for这个特殊的问题。

容纳不共享同一姓氏的父母,以及孩子不共享相同的姓氏作为父母,是另一个大的挑战,我不能甚至试图绕到我的头(我我想这对寄养家庭来说也是如此)。因此,对于上面的可视化,我假设非单亲父母已婚并且拥有相同的姓氏,并且这两个孩子的父姓都是一样的。

============================================= =====================================

这是我尝试过的一些代码着手创建设法解决这部分数据库的一部分(注:“玩家”是父母的“儿女”):

DROP TABLE IF EXISTS `person` ; 
CREATE TABLE `person` (
    `personID` INT(5) NOT NULL AUTO_INCREMENT , 
    `firstName` VARCHAR(50) NOT NULL , 
    `lastName` VARCHAR(50) NOT NULL , 
    `dateOfBirth` DATE NOT NULL , 
    `personType` CHAR(6) NOT NULL, 
    `photo` BLOB NULL DEFAULT NULL , 
    PRIMARY KEY (`personID`)) 
ENGINE = InnoDB; 
SHOW WARNINGS; 

DROP TABLE IF EXISTS `parent` ; 
CREATE TABLE `parent` (
    `parentID` INT(5) NOT NULL, 
    FOREIGN KEY (`parentID`) REFERENCES `person` (`personID`) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE) 
ENGINE = InnoDB; 
SHOW WARNINGS; 

DROP TABLE IF EXISTS `player` ; 
CREATE TABLE `player` (
    `playerID` INT(5) NOT NULL, 
    `schoolID` INT(5) NOT NULL, 
    FOREIGN KEY (`playerID`) 
    REFERENCES `person` (`personID`) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE, 
    FOREIGN KEY (`schoolID`) 
    REFERENCES `school` (`schoolID`) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE) 
ENGINE = InnoDB; 
SHOW WARNINGS; 

DROP TABLE IF EXISTS `family` ; 
CREATE TABLE `family` (
    `parentID` INT(5) NOT NULL , 
    `playerID` INT(5) NOT NULL , 
    PRIMARY KEY (`parentID`, `playerID`), 
    FOREIGN KEY (`playerID`) 
    REFERENCES `player` (`playerID`) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE, 
    FOREIGN KEY (`parentID`) 
    REFERENCES `parent` (`parentID`) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE) 
ENGINE = InnoDB; 
SHOW WARNINGS; 

如果有人能帮助我理清这个问题给出一些指导,甚至一些通用的例子和解释,那将是非常好的。我认为这是一种多种多样的关系,我不能完全放弃,因为父母可以有一个或多个孩子,而一个孩子可以有一个或多个父母(在这种情况下,一个家庭不会真正成为一个没有孩子的家庭)。

非常感谢提前!

+0

如何通过另一列扩展'家庭'表为secont家长? – mrab 2012-04-27 06:09:38

+0

@mrab你能解释一下这一点吗?我正在使用“Parent”表中的外键来链接“Family”表,因此我如何在这里照顾至少两个父母? – Rob 2012-04-27 10:50:45

回答

2

一个孩子可以有不超过2个父母,他们都有特定的角色(母亲与父亲),并且可能存在父母一方或双方未知的情况。

因此,这不是一个真正的“多对多”的关系,但实际上“很多到零或一个或两个”,它可以自然地这样表示(包括MotherIDFatherID是为空的):

enter image description here

如果你把LastName两个ParentPlayer(或你的情况的通用超),这也自然包括了那些父母和他们的孩子不同姓氏的情况。

然后,您可以轻松地获得“每个父母的子女”这样的(SQL Fiddle)...

SELECT 
    ParentID, 
    Parent.FirstName ParentFirstName, 
    Parent.LastName ParentLastName, 
    PlayerID, 
    Player.FirstName PlayerFirstName, 
    Player.LastName PlayerLastName 
FROM 
    Parent 
    LEFT JOIN Player 
     ON Parent.ParentID = Player.MotherID 
     OR Parent.ParentID = Player.FatherID 
ORDER BY ParentId 

...并在应用程序代码透视数据,如果这是你的愿望。


上述模型允许Parent的性别和其母亲/父亲的角色之间的不匹配。如果你想避免这种情况,你可以走极端,做这样的事情...

enter image description here

...但我宁愿不要复杂化,并与第一种模式,并坚持在应用程序级别执行此。

+1

*“一个孩子可以有不超过2个父母,他们都有特定的角色(母亲与父亲)”*除了我们有收养或[同性恋婚姻](http://qntm.org/gay)被允许:) – 2012-04-27 13:46:01

+0

@ypercube当然,b那么我们可以简单地声明一个父母为“父母1”,另一个父母为“父母2”,并且不需要从根本上改变逻辑。唯一的问题是,如果我们想要模拟一个情况,即可能有2个以上的“父母”(例如我们想要统计生物父母和养父母) - OP将不得不决定这种情况是否足够重要证明模型复杂化。 – 2012-04-27 18:03:41

+0

我的意思不是 - 以任何方式 - 你的答案是无效的。只是想要添加该链接的借口。它有关于婚姻 - 家庭关系建模的相当好的选择列表。 – 2012-04-27 19:34:18

0

实现多对多关系的Family表通常在用户输入了Parent/Player(s)数据后创建。通常,用户界面将被描述为主表格/子表格组合,其中从主表格中输入/选择父表格,并且在子表格中输入/显示与父表格相关联的一个或多个玩家;通常是某种网格。

+0

非常感谢您的反馈:)。虽然我只使用命令行作为“接口”......我只是使用MySQL来解决这个问题。我想实现的目标是让家庭表(两张许多桌子之间的连接表)为每个家长设置两列 - 其中一张是强制性的,然后是能够拥有无限量儿童的东西。因为其中一个父母是可选的,所以我不能将它们作为主键使用。 – Rob 2012-04-27 07:48:21

+0

...另外,我真的不希望每个孩子的记录都存在重复列表 – Rob 2012-04-27 07:49:44

+0

大家好,我刚刚遇到这个链接:http://www.dougboude.com/blog/1/2009/12/A-SWEET-Little-MySQL-Function-GroupConcat.cfm - 这是给我的一些线索,但仍然可以随时提供您的帮助...... – Rob 2012-04-27 08:08:04

2

我会质疑家族实体的使用。由于离婚和随后的父母再婚,孩子可以成为两个家庭的成员 - 你会如何塑造?可能一个孩子没有四个人有效地扮演“在父母的身边”?

1

所有你需要的是一个有两个字段的连接表:孩子,照顾者。这基本上就是你的“家庭”表 - 我不明白你的“父母”表的目的。在“家庭” BOTH值将外键的“人”(即让“玩家”比你有你的图中更通用的表格。)

这则允许任何孩子有任何数量的护理人员。任何看护者都可以和任何数量的孩子联系在一起。所有可能的不正当的和美妙的家庭安排的组合都可以容纳。

0

我不确定这是否是一个“答案”本身,但这是我的尝试在调整我的MySQL代码以适应什么Branko Dimitrijevic的回答提供了我。下面是有关对表我调整MySQL代码:

DROP TABLE IF EXISTS `person` ; 
CREATE TABLE `person` (
    `personID` INT(5) NOT NULL AUTO_INCREMENT , 
    `firstName` VARCHAR(50) NOT NULL , 
    `lastName` VARCHAR(50) NOT NULL , 
    `dateOfBirth` DATE NOT NULL , 
    `personType` CHAR(6) NOT NULL, 
    `photo` BLOB NULL DEFAULT NULL , 
    PRIMARY KEY (`personID`)) 
ENGINE = InnoDB; 
SHOW WARNINGS; 

DROP TABLE IF EXISTS `parent` ; 
CREATE TABLE `parent` (
    `parentID` INT(5) NOT NULL, 
    PRIMARY KEY (`parentID`), 
    FOREIGN KEY (`parentID`) REFERENCES `person` (`personID`) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE) 
ENGINE = InnoDB; 
SHOW WARNINGS; 

DROP TABLE IF EXISTS `player` ; 
CREATE TABLE Player (
    `playerID` INT(5) NOT NULL, 
    `motherID` INT(5), 
    `fatherID` INT(5), 
    `schoolID` INT(5), 
    PRIMARY KEY (`playerID`), 
    FOREIGN KEY (`playerID`) REFERENCES `person` (`personID`) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE, 
    FOREIGN KEY (`motherID`) REFERENCES `parent` (`parentID`) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE, 
    FOREIGN KEY (`fatherID`) REFERENCES `parent` (`parentID`) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE, 
    FOREIGN KEY (`schoolID`) REFERENCES `school` (`schoolID`) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE) 
ENGINE = InnoDB; 
SHOW WARNINGS; 

这是这些表的逻辑模型的一部分:

enter image description here

如果布兰科,或其他任何人,可以验证我的与Branko的答案尝试,这将是很好的。你也会注意到,我正在为模型使用MySQL Workbench。

以下是超出范围对于这方面的问题,但如果有人能帮助这也将是巨大的:

我一直要求不使用反向或正向工程转换SQL代码模型模式但这使我能够验证我在Visio中构建的模型的正确性。不过,我不能完全得到的Visio模型看起来像工作台模型 - 这里是的Visio版本我想为上述模型中的表:

enter image description here

正如你可以在Visio中的版本看到, “fatherID”和“motherID”列没有被指示为外键,这正是我想要的(并在Workbench版本中进行了说明)。如果有人能帮助我让我的Visio模型看起来与Workbench版本相同,那将是一件好事。

0

我不知道为什么一个人会有多个地址 - 但我想他们可以。但是,如果我正在做多个地址,那么我会将地址推入另一个表,并有一个person_address加入表。这样您就不会为居住在同一地址的每个人重复地址数据。

您的父母表需要两个字段 - 一个用于父母,另一个用于玩家(正如我之前所说的BOTH我认为如果他们都指向人,它会更好地工作)。为什么你有paren和player之间有两条关系?

此人|父母关系不会是1..1 - 1..1,因为这意味着每个人都是父母,您的玩家可能不是。

只是在旁边 - 但你真的好像专注于一位母亲和父亲。可能没有任何一个或多个。你不需要单独的关系来规定性别 - 这应该是PERSON中的数据,或者根本就不是那些与数据无关的数据。