MySQL从ER图创建表

时间:2014-07-25 16:34:45

标签: mysql sql database database-design entity-relationship

我正在从ER图创建数据库但是我不认为我的一些主键和外键是正确的。我认为它们不正确的表是部分中的主键和注册表中的FK和PK。我也认为我没有正确执行我的FK约束,因此我可以检测参照完整性违规。

这是ER图我基于数据库。

ER Diagram

以下是我制作的表格

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图创建数据库。

3 个答案:

答案 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)中的每个更改创建(有效)新学生。

替代解决方案:

  • 在数据库中使用自动密钥,使StudentId唯一但不是主要的。
  • 使用StudentId作为主键,并使其每次都自动更新 它在父表中的变化时间。

我不建议使用第二个选项,因为它只是一个解决旧问题的方法。