对于数据库分配,我必须为学校建模系统。部分要求是为员工,学生和家长建模信息。
在UML类图中,我将其建模为这三个类是人类型的子类型。这是因为他们都需要有关地址数据的信息。
我的问题是:如何在数据库(mysql)中对此进行建模?
到目前为止的想法如下:
根据这个wikipage about django,可以按如下方式在子类型上实现主键:
"id" integer NOT NULL PRIMARY KEY REFERENCES "supertype" ("id")
对于那些之前在数据库中建模继承的人;你是怎么做到的?你推荐什么方法?为什么?
非常欢迎链接到文章/博客文章或以前的问题。
谢谢你的时间!
更新
好的,谢谢大家的答案。我已经有一个单独的地址表,所以这不是问题。
干杯,
亚当
答案 0 :(得分:5)
4桌工作人员,学生,家长和人员为通用的东西。 工作人员,学生和家长都有外键,每个人都会回复人(而不是相反)。
人员有一个字段,用于标识此人的子类(即员工,学生或家长)。
编辑:
正如HLGM所指出的,地址应该存在于一个单独的表中,因为任何人都可能有多个地址。 (但是 - 我不同意自己 - 你可能希望故意将地址限制为每人一个,限制邮件列表的选择等。)
答案 1 :(得分:2)
嗯,我认为所有方法都是有效的,任何一位在一张桌子上将其推倒的讲师(除非要求具体说你不应该这样做)正在取消一个可行的策略,因为他们个人的意见。
我强烈建议您查看有关NHibernate的文档,因为这提供了执行上述操作的不同方法。我现在试图拙劣地鹦鹉学舌。
您的选择:
3)“正确”的继承。标准化版本。你几乎就在那里,但你的钥匙在错误的地方IMO。您的Employee表应包含PersonId,以便您可以执行以下操作:
从employee.personId = person.personId
获取员工姓名仅在人员表上指定的所有员工姓名。
答案 2 :(得分:2)
我会去#3。
您的目标是给讲师留下深刻印象,而不是PM或客户。学者倾向于不喜欢无效,并且可能(潜意识地)惩罚你使用其他方法(依赖于空值)。
并且您不一定需要django扩展(PRIMARY KEY ... REFERENCES ...)您可以使用普通的FOREIGN KEY。
答案 3 :(得分:1)
“那么对于之前在数据库中建模继承的人来说,你是怎么做到的?你推荐什么方法?为什么? “
方法1和3都很好。差异主要在于您的用例。
1)适应性 - 哪个更容易改变?几个与父表具有FK关系的独立表。2)性能 - 需要更少的连接?一张单桌。
大鼠。没有设计可以完成两者。
此外,除了您的单表和FK到父母之外,还有第三种设计。
三个单独的表,包含一些公共列(通常是所有子类表中的超类列的复制和粘贴)。这非常灵活且易于使用。但是,它需要三个表的并集来组合整个列表。
答案 4 :(得分:0)
如果重点是在数据库中建模子类,那么您可能已经在考虑我在真实OO数据库中看到的解决方案(将字段留空)。
如果没有,您可能会考虑创建一个不以这种方式使用继承的系统。
继承应该总是非常谨慎地使用,这可能是一个非常糟糕的情况。
一个好的准则是永远不要使用继承,除非你实际上有一些代码与“Parent”类的字段不同,而不是“Child”类中的相同字段。如果您的类中的业务代码没有专门引用字段,那么该字段绝对不应该导致继承。
但是,如果你在学校,那可能与他们想要教的东西不符......
答案 5 :(得分:0)
出于分配目的,“正确”答案可能是#3:
Person
PersonId Name Address1 Address2 City Country
Student
PersonId StudentId GPA Year ..
Staff
PersonId StaffId Salary ..
Parent
PersonId ParentId ParentType EmergencyContactNumber ..
其中PersonId始终是主键,也是最后三个表中的外键。
我喜欢这种方法,因为它可以很容易地代表具有多个角色的同一个人。例如,老师也可以成为父母。
答案 6 :(得分:0)
我建议五张桌子 人 学生 员工 亲 地址
为什么 - 因为人们可以有多个广告,人们也可以拥有多个角色,而且您希望员工获得的信息与您为父母或学生存储所需的信息不同。
此外,您可能希望将名称存储为last_name,Middle_name,first_name,Name_suffix(如jr。)而不是名称。相信我你会想要在last_name上搜索!名称不是唯一的,因此您需要确保拥有唯一的代理主键。
在尝试设计数据库之前,请先阅读有关规范化的信息。这是一个开始的来源: http://www.deeptraining.com/litwin/dbdesign/FundamentalsOfRelationalDatabaseDesign.aspx
答案 7 :(得分: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)
)
子类型中的外键员工,学生,家长增加了两个条件: