我正在从ER图创建数据库但是我不认为我的一些主键和外键是正确的。我认为它们不正确的表是部分中的主键和注册表中的FK和PK。我也认为我没有正确执行我的FK约束,因此我可以检测参照完整性违规。
这是ER图我基于数据库。
以下是我制作的表格
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)
);
感谢您帮助我们了解如何从ER图创建数据库。
答案 0 :(得分:0)
快速查看之后,在我看来,你想要为由ClassId,SecNo和Semester组成的Section有一个复合主键,假设这三个属性构成了Section实体的唯一性范围。您也可以只有一个唯一的SectionID(例如自动递增int)
对于Enrolled,我会创建一个自动递增的主键,并有一个链接到Section表的外键,具体取决于你如何解决该实体/表的唯一性。
希望这会有所帮助。当然,有很多方法可以解决这个问题。
答案 1 :(得分:0)
对于每个表,你真的应该有一个简单的,标准化的AUTO_INCREMENT PRIMARY KEY
。这使得特定记录的引用变得更加容易。在构建关系时,最好通过主键 引用表。字符串主键可能很麻烦,特别是如果这些字符串可以更改。
此外,您对字符串长度的任意限制非常令人讨厌。你是谁说人们应该只有二十个字符的长度,或者教授的名字只能长十个?那真是草率。除非你有充分的理由,否则请保留这些自由格式字段,默认为VARCHAR(255)
。硬盘驱动器今天以兆兆字节为单位,你需要有一亿学生用你的名字数据填满你的驱动器。
否则,作为数据库,这没关系。我可能完全抛弃这个模式并从你的实体图重建,顺便说一下,使用我正在使用的任何开发框架的约定。例如,Ruby on Rails,Django,Drupal和Tapestry都会对如何命名表有自己的想法。
答案 2 :(得分:0)
使用特定于数据库域的主键通常更有用,也更实用,因为在现实生活中,大多数实体没有真正不变且唯一的键非常适合主键。
例如,数据输入错误可能需要更改数据库中的学生ID。如果您使用最终更改的属性,则必须为主键(StudentId)中的每个更改创建(有效)新学生。
替代解决方案:
我不建议使用第二个选项,因为它只是一个解决旧问题的方法。