我正在从 ER 图创建数据库。
表Section中的主键和表Enrolled中的FK和PK不正确。
我没有正确执行我的 FK 约束,以便我可以检测引用完整性违规。
CREATE TABLE Student
(
StudentId INTEGER,
FName VARCHAR(20),
LName VARCHAR(20),
DOB CHAR(10),
Major VARCHAR(20),
PRIMARY KEY(StudentId)
);
CREATE TABLE Phone
(
sID INTEGER,
Pnumber CHAR(20),
Type CHAR(3),
PRIMARY KEY(Pnumber)
);
CREATE TABLE Class
(
ClassId VARCHAR(6),
Description VARCHAR(30),
NumCredits Integer,
Prereq VARCHAR(20),
PRIMARY KEY(ClassId)
);
CREATE TABLE Section
(
ClassId VARCHAR(6),
SecNo CHAR(10),
Semester CHAR(4),
ClassRoom VARCHAR(6),
TimeOffered VARCHAR(18),
PRIMARY KEY(SecNo),
FOREIGN KEY(ClassId) REFERENCES Class(ClassId)
);
CREATE TABLE Enrolled
(
StudentId INTEGER,
SecNum VARCHAR(40),
ClassId VARCHAR(8),
Semes VARCHAR(6),
GorDD VARCHAR(30)
FOREIGN KEY(ClassId) REFERENCES Section(ClassId),
FOREIGN KEY(StudentId) REFERENCES Student(StudentId)
);
CREATE TABLE Professor
(
EmpId INTEGER,
FName VARCHAR(10),
LName VARCHAR(10),
Dept VARCHAR(2),
QualClass VARCHAR(40),
PRIMARY KEY (EmpId)
);
CREATE TABLE Teaches
(
Class VARCHAR(5),
Section INTEGER,
Semester CHAR(4),
EmpId INTEGER,
FOREIGN KEY (EmpId) REFERENCES Professor(EmpId)
);
CREATE TABLE Qualified
(
EmpId INTEGER,
ClassId VARCHAR(5)
);
您确实应该为每张桌子准备一个简单、标准化的
AUTO_INCREMENT PRIMARY KEY
。这使得引用特定记录变得更加容易。在建立关系时,最好仅通过主键来引用表。字符串主键可能会很麻烦,特别是如果这些字符串可以更改。
此外,你对字符串长度的任意限制是极其烦人的。你凭什么说人们的名字只能有二十个字符长,或者教授的名字只能有十个字符长?实在是太马虎了。除非您有充分的理由,否则请对这些自由格式字段保持开放,默认 VARCHAR(255)
。如今,硬盘驱动器以 TB 为单位,您需要一亿学生才能用名称数据填满您的驱动器。
否则,作为数据库,这是可以的。我可能会完全放弃这个模式,并从您的实体图重建,顺便说一句,这是一个很好的工具,使用我正在使用的任何开发框架的约定。例如,Ruby on Rails、Django、Drupal 和 Tapestry 对于如何命名表都有自己的想法。
例如,数据输入错误可能需要更改数据库中的学生 ID。如果您使用的属性最终会发生变化,那么您必须为主键(StudentId)的每次更改(有效)创建一个新学生。
替代解决方案:
在数据库中使用自动键并使 StudentId 唯一但不是主要的。
对于已注册,我将创建一个自动递增的主键,并有一个链接到部分表的外键,具体取决于您如何解决该实体/表的唯一性。