我正在开发一个将有两种用户的应用程序,教师和学生。
教师和学生都有名字和姓氏、唯一的电子邮件和唯一的用户名(唯一的意思是教师不能与学生拥有相同的用户名/电子邮件)。
除了这些公共(public)领域之外,学生还有 4 个领域:A、B、C 和 D。
教师将拥有 E、F 和 G。
为此设计数据库的最佳方式是什么?我应该使用 2 个表(一个给学生,一个给老师,每个都有所有字段)还是 3 个表(一个用户表 - 用于用户名和电子邮件等常见字段,然后与学生建立一对一的关系和只包含特定字段的教师表。
此数据库将用于学生/教师必须登录的系统。我想最好只在一个表中查找凭据,而不是在应用程序中有 2 个不同的登录点,每个登录点查询不同的表。
实际上,我将使用 hibernate 从 java 类生成表,因此从面向对象的角度来看,使用 3 个表听起来更好。
我期待看到其他对此的意见。
谢谢,
最佳答案
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 列引用 People 中的一行,其中 PersonType = 'T'
,类似地,Student.PersonID 引用 People 中的一行,其中PersonType = 'S'
。
没有一种特别简洁的方法可以自动执行该操作。您的选择包括向始终保存“T”或“S”的每个教师和学生添加一个 PersonType 列,然后创建一个引用 People(PersonID, PersonType) 的外键。这很难看,因为 Teacher 或 Student 表中的值是常量,而且只有 PersonID 是唯一的。
否则,您将强制执行代码中的约束。我可能会使用定期检查违反约束的条目(Teacher 中标识 People 表中的学生的条目,或 Student 中标识 People 表中的教的条目)备份的代码。
这映射到 Hibernate 的效果如何是一个单独的问题。您可能会发现两个 View 很有用:
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 的限制是不必要的。
关于此给定场景的数据库设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8863284/