2009-01-06 74 views
5

对于数据库分配,我必须建立一个学校系统的模型。部分要求是为员工,学生和家长建立信息模型。在数据库中建模继承

在UML类图中,我将此模型化为这三个类是人类类型的子类型。这是因为他们都需要关于地址数据等信息。

我的问题是:我如何在数据库(mysql)中建模?

思想至今如下:

  1. 创建包含每个类型的所有信息单片人表,将有很多依赖于被存储什么类型的空值。 (我怀疑这对讲师来说会很好,除非我令人信服地辩解)。
  2. 有三个外键的人表引用了子类型,但其中两个将是空的 - 实际上我甚至不确定这是否合理或可能?
  3. 根据这一wikipage about django这是可以实现的亚型的主键如下:

    "id" integer NOT NULL PRIMARY KEY REFERENCES "supertype" ("id")
  4. 别的东西,我还没有想过...

因此,对于那些谁拥有在数据库之前模拟继承;你是怎么做到的?你推荐什么方法?为什么?

链接到文章/博客文章或以前的问题是值得欢迎的。

谢谢你的时间!

UPDATE

好的谢谢你的回答。我已经有一个单独的地址表,所以这不是一个问题。

干杯,

亚当

+0

如果这是一个家庭作业添加作业标签请 – JoshBerke 2009-01-06 17:15:02

+0

还检查了:http://stackoverflow.com/questions/5802/inheritance-in-database – JoshBerke 2009-01-06 17:15:55

回答

5

4台的工作人员,学生,家长和个人为通用的东西。 工作人员,学生和家长都有外键的钥匙,每个钥匙都会引用回人(而不是其他方式)。

人员具有标识此人的子类别(即员工,学生或家长)的字段。

编辑:

正如HLGM指出,地址应该存在于一个单独的表,因为任何人可能有多个地址。 (但是 - 我即将不同意自己的意见 - 你可能希望故意将地址约束为每人一个,限制邮件列表的选择等)。

1

“因此,对于那些谁已经在数据库之前建模继承;?你是怎么做到这一点你推荐什么方法,为什么 ”

方法1和3都不错。差异主要在于你的用例是什么。

1)适应性 - 哪个更容易改变? FK关系与父表的几个单独的表。

2)性能 - 哪些需要更少的连接?一张桌子。

大鼠。没有设计完成这两个。

此外,除了您的单表和FK对父母之外,还有第三种设计。

三个独立的表格,包含一些常用列(通常在所有子类表中复制并粘贴超类列)。这非常灵活且易于使用。但是,它需要三个表格的联合来组装整个列表。

2

嗯,我认为所有的方法都是有效的,任何讲师因为个人意见而在一张桌子上甩掉它(除非要求具体说你不应该这样做)正在消除一个可行的策略。

我强烈建议您查阅关于NHibernate的文档,因为这提供了执行上述的不同方法。我现在会尝试鹦鹉很差。

您的选择:

  • 1)与所有具有 “分隔符” 列中的数据一个表。本专栏陈述了这个人是什么样的人。这在简单的情况下是可行的,并且(严重)高性能,因为连接会伤害太多
  • 2)每个类将导致列重复,但会避免重新连接,所以它的简单和快速在大多数情况下,lil和索引缓解了这一点)。
  • 3)“适当的”继承。规范化的版本。你几乎在那里,但你的钥匙是在错误的地方国际海事组织。你的员工表应包含一个PERSONID所以你可以再做:

    选择employee.id,从员工内部person.name加入上employee.personId = PERSON.PERSONID

人要获得所有的名字只在人员表上指定姓名的员工。

0

OO数据库通过相同的东西,并拿出几乎相同的选项。

如果要在数据库中建立子类的模型,您可能已经考虑过我在真正的OO数据库中看到的解决方案(将字段留空)。

如果不是,您可能会考虑创建一个不以这种方式使用继承的系统。

继承应该总是相当谨慎地使用,这可能是一个非常糟糕的情况。

一个很好的指导方针是永远不要使用继承,除非你实际上拥有的代码对“父”类的字段做的事情不同于“儿童”类中的相同字段。如果您的类中的业务代码没有专门引用某个字段,那么该字段绝对不应该导致继承。

但是,如果你在学校,这可能不符合他们想教的东西......

2

我会去#3。

您的目标是打动演讲者,而不是PM或客户。学者倾向于不喜欢空值,并可能(潜意识地)惩罚你使用其他方法(依赖于空值)。

而且你不一定需要django扩展名(PRIMARY KEY ... REFERENCES ...)可以使用普通的FOREIGN KEY。

0

“正确”的答案赋值的目的大概是3:

Person 
PersonId Name Address1 Address2 City Country 

Student 
PersonId StudentId GPA Year .. 

Staff 
PersonId StaffId Salary .. 

Parent 
PersonId ParentId ParentType EmergencyContactNumber .. 

哪里PERSONID永远是首要的关键,也是最后三个表的外键。

我喜欢这种方法,因为它可以很容易地代表具有多个角色的同一个人。例如,老师也可以成为父母。

0

我建议五个表 人 学生 员工 家长 地址

为什么 - 因为人们可以有多个addesses,人们也可以拥有多个角色,并且希望为员工的信息是比信息不同的你需要为家长或学生存储。

此外,您可能希望将名称存储为last_name,Middle_name,first_name,Name_suffix(如jr。),而不是名称。相信我你会想要在last_name上搜索!名称不是唯一的,所以你需要确保你有一个独特的代理主键。

请在尝试设计数据库之前阅读有关规范化的内容。这里是开始与源: http://www.deeptraining.com/litwin/dbdesign/FundamentalsOfRelationalDatabaseDesign.aspx

0

超级型的人应该这样被创建:

CREATE TABLE Person(PersonID int primary key, Name varchar ... etc ...) 

全部子类型应该这样创建:

CREATE TABLE IF NOT EXISTS Staffs(StaffId INT NOT NULL , 
    PRIMARY KEY (StaffId) , 
    CONSTRAINT FK_StaffId FOREIGN KEY (StaffId) REFERENCES Person(PersonId) 
) 

CREATE TABLE IF NOT EXISTS Students(StudentId INT NOT NULL , 
    PRIMARY KEY (StudentId) , 
    CONSTRAINT FK_StudentId FOREIGN KEY (StudentId) REFERENCES Person(PersonId) 
) 

CREATE TABLE IF NOT EXISTS Parents(PersonID INT NOT NULL , 
    PRIMARY KEY (PersonID) , 
    CONSTRAINT FK_PersonID FOREIGN KEY (PersonID) REFERENCES Person(PersonId) 
) 

在亚型员工,学生,家长的外键中增加了两个条件:

  1. 人员行不能删除,除非相应的子类型行将不会删除 。对于例如如果学生 表中有一个学生条目参照Person表,则不删除学生条目 不能删除人员条目,这是非常重要的。如果学生 对象被创建,则不删除学生对象,我们不能 删除基础Person对象。

  1. 所有基本类型有外键“非空”,以确保每个基地 类型将有现有总是基本类型。对于例如如果您创建 学生对象,则必须先创建Person对象。