如何在另一个表中引用复合PK作为外键并且仍然具有规范化数据库?

时间:2013-11-10 22:04:00

标签: sql create-table erd

首先,这是我遇到问题的三个表的代码:

    CREATE TABLE ProgramSupervisor
    (    EmpNo                                CHAR (6),
         ProgramSupervisorNo                  CHAR (6),
         TeamNo                               CHAR (3),
         CONSTRAINT PKProgramSupervisor PRIMARY KEY (EmpNo , ProgramSupervisorNo) ,
         CONSTRAINT FKProgSupEmpNo FOREIGN KEY (EmpNo) REFERENCES Employee  )

另:

    CREATE TABLE ISL
    (    ISLNo                                  CHAR (6) ,
         EmpNo                                  CHAR(6),
         ProgramSupervisorNo                    CHAR (6),
         ISLName                                VARCHAR (30),
         ISLStreet                              VARCHAR (40),
         ISLCity                                VARCHAR (30),
         ISLState                               CHAR (2),
         ISLZip                                 CHAR (5),
    CONSTRAINT PKISL PRIMARY KEY (ISLNo) ,
    CONSTRAINT FKISLProgSupNo FOREIGN KEY (ProgramSupervisorNo, EmpNo) 
               REFERENCES ProgramSupervisor  )

另一个:

    CREATE TABLE Hourly
    (    EmpNo                           CHAR (6),
         ISLNo                           CHAR (3),
          NumberOfWriteUpes              SMALLINT,
    CONSTRAINT PKHourly PRIMARY KEY (EmpNo),
    CONSTRAINT FKEmpNo FOREIGN KEY (EmpNo) REFERENCES Employee,
    CONSTRAINT FKISLNo FOREIGN KEY (ISLNo) REFERENCES ISL  )

这是ERD和我正在努力的关系:

enter image description here

现在你有了这些信息,让我解释一下我遇到的问题。首先,ERD有点误导。我有一个ProgramSupervisor表,它是'Salary'父表的子表,'Salary'是父表'Employee'的子表。当'Employee'的PK为EmpNo时,薪水的PK,然后是ProgramSupervisor也是EmpNo。但是,我还希望ProgramSupervisorNo成为'ProgramSupervisor'表的PK,并为其提供复合PK。当我创建'ISL'表时,为了在ISL表中引用复合'ProgramSupervisor'PK作为FK,Access需要两个PK字段名称。这是否违反了标准化标准?由于它在'ISL'表中同时需要EmpNo和ProgramSupervisorNo,这是否意味着ProgramSupervisorNo不依赖于EmpNo,因此不应包含其中一个字段?我是新手,所以请原谅我粗制滥造的解释。

此外,“每小时”员工属于一个ISL,ISL可以拥有众多“每小时”员工,但“每小时”表也是员工的子表,并以EmpNo为主键。话虽这么说,如果我需要将EmpNo和ProgramSupervisorNo放在我的'ISL'表中,我怎么把ISLNo放在我的'Hourly'表中?

清除泥土?基本上,我只是将ProgramSupervisorNo放在'ISL'表中,因为每个ISL都有一个ProgramSupervisor。然后,我想把ISLNo放在我的'Hourly'表中。请提供一些例子并向我解释,就像我五岁。任何帮助深表感谢。

1 个答案:

答案 0 :(得分:2)

从学术角度来看,Primary key必须符合所有这些要点:

  • 独特
  • 最小
  • 所有PK字段均为非空

外键是对其他表的主键的引用。因此,它们必须包含引用的PK具有的字段。这并不违反正常化,因为PK必须是最小的(从学术角度来看)。

如果您拥有一个包含2个或更多列的主键,并且您认为仅使用一列引用其行就足够了,那么您的PK无效,因为它不是最小的。当它有效并且您需要所有这些列以满足唯一性时,您还需要外键中的所有这些列。

DBMS允许您定义非最小PK,但这就是您离开学术概念的地方。