我正在开发一个有2种用户,教师和学生的应用程序。
老师和学生都有名字和姓氏,唯一的电子邮件和唯一的用户名(独特的我也意味着教师不能拥有与学生相同的用户名/电子邮件)。
除了这些常见领域,学生还将有4个领域:A,B,C和D.
教师将有E,F和G.
为此设计数据库的最佳方法是什么?我应该使用2个表(一个用于学生,一个用于教师,每个用于所有字段)或3个表(用户表 - 用于常用字段,如用户名和电子邮件,然后与学生建立一对一的关系和教师表只包含特定字段。
此数据库将用于学生/教师必须登录的系统中。我想最好只在一个表中查找凭据,而不是在应用程序中有两个不同的登录点,每个都查询不同的表。
实际上我将使用hibernate从java类生成表,所以从面向对象的角度来看,使用3个表听起来更好。
我期待看到其他意见。
谢谢,
答案 0 :(得分:1)
CREATE TABLE People
(
PersonID INTEGER NOT NULL PRIMARY KEY, -- Add local incantation for auto-allocated numbers
FirstName VARCHAR(32) NOT NULL,
LastName VARCHAR(32) NOT NULL,
Email VARCHAR(64) NOT NULL UNIQUE,
UserName VARCHAR(16) NOT NULL UNIQUE,
PersonType CHAR(1) NOT NULL CHECK(PersonType IN('S', 'T')) -- S student, T teacher
);
CREATE TABLE Student
(
PersonID INTEGER NOT NULL REFERENCES People,
A ...,
B ...,
C ...,
D ...
);
CREATE TABLE Teacher
(
PersonID INTEGER NOT NULL REFERENCES People,
E ...,
F ...,
G ...
);
您希望强制执行一项约束,即Teacher.PersonID列引用人员PersonType = 'T'
中的行,同样适用于引用人员PersonType = 'S'
中的行的Student.PersonID。 / p>
没有一种特别干净的方法可以自动执行。您的选项包括向每个将始终保持“T”或“S”的教师和学生添加列PersonType,然后创建引用People(PersonID,PersonType)的外键。这很难看,因为Teacher或Student表中的值是常量,因为PersonID本身是唯一的。
否则,您将在代码中强制执行约束。我可能会使用通过定期检查备份的代码来检查违反约束的条目(教师中用于标识People表中学生的条目,或Student中用于标识People表中教学的条目)。
这个映射到Hibernate的程度是一个单独的问题。您可能会发现两个视图很有用:
CREATE VIEW StudentInfo AS
SELECT P.*, S.A, S.B, SS.C, S.D
FROM People AS P
JOIN Student AS S
ON P.PersonID = S.PersonID AND P.PersonType = 'S';
CREATE VIEW TeacherInfo AS
SELECT P.*, T.E T.F, T.G
FROM People AS P
JOIN Teacher AS T
ON P.PersonID = T.PersonID AND P.PersonType = 'T';
当然,您可以有争议地认为对PersonType的限制是不必要的。
答案 1 :(得分:0)
只是一个意见。我会将所有内容放在一个表中,但使用Hibernate继承和“每个类层次结构的映射”映射创建多个Hibernate映射
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/inheritance.html
答案 2 :(得分:0)
Hibernate(至少3.x)推荐每个类层次结构策略的表。它的缺点是每一行都有一个列用于任何子类中的每个字段,因此您将浪费一些空间。它仍然弥补了简单性的不足。
你可以做的另一件事就是让每个班级都有自己的表。即hibernate不知道继承。这可能会使应用程序的其他部分复杂化......