来自复合键的mysql外键引用

时间:2012-04-25 18:08:11

标签: mysql database foreign-keys composite-key referential-integrity

我正在创建一个应用程序,它将处理和记录学生何时得到大学教员的建议,我需要一种有效的方法来构建表格。我的问题来自于缺乏引用完整性,这是因为无法创建外键,只能在ADVISE_HIST中的一部分复合键上引用学生(STUDENT_ID,DATE_ADVISED)

这里有一些表

create table STUDENT(
  LNAME varchar(50),
  FNAME varchar(50),
  ID char(9) primary key,
  ASSIGNED_ADVISOR_EMAIL varchar(70),
  foreign key (ASSIGNED_ADVISOR_EMAIL) references DEP_FACULTY(EMAIL) ON DELETE SET NULL,
  IS_ADVISED tinyint(1),
);

create table DEP_FACULTY(
  LNAME varchar(50),
  FNAME varchar(50),
  EMAIL varchar(70) primary key
);

create table ADVISE_HIST(
  STUDENT_ID char(9),
  /*foreign key (STUDENT_ID) references STUDENT(ID),*/
  ACTUAL_ADVISOR_EMAIL char(70) NOT NULL,
  foreign key (ACTUAL_ADVISOR_EMAIL) references DEP_FACULTY(EMAIL),
  DATE_ADVISED date,
  primary key REF_ADVISE_HIST (STUDENT_ID, DATE_ADVISED),
);

我的问题是,是否存在无法创建此密钥的方法,或者是否有一个我没有想到的更好的结构?

1 个答案:

答案 0 :(得分:0)

MySQL有很多restrictions on foreign keys。可能妨碍您的方式之一。 。

  • 两张桌子都必须使用INNODB引擎。
  • “在引用表中,必须有一个索引,其中外键列以相同的顺序列为第一列。”

此代码适用于我的版本(5.1.62)。

create table DEP_FACULTY(
  LNAME varchar(50),
  FNAME varchar(50),
  EMAIL varchar(70) primary key
) ENGINE = INNODB;

insert into DEP_FACULTY values ('Gregor', 'Brandich', 'gbrandich@thisdomain.com');

create table STUDENT(
  LNAME varchar(50),
  FNAME varchar(50),
  ID char(9) primary key,
  ASSIGNED_ADVISOR_EMAIL varchar(70),
  foreign key (ASSIGNED_ADVISOR_EMAIL) references DEP_FACULTY(EMAIL) ON DELETE SET NULL,
  IS_ADVISED tinyint(1)
) ENGINE = INNODB;

insert into STUDENT values ('Charmaine', 'DePeletier', 'cmd', 'gbrandich@thisdomain.com', 1);

create table ADVISE_HIST(
  STUDENT_ID char(9),
  foreign key (STUDENT_ID) references STUDENT(ID),
  ACTUAL_ADVISOR_EMAIL char(70) NOT NULL,
  foreign key (ACTUAL_ADVISOR_EMAIL) references DEP_FACULTY(EMAIL),
  DATE_ADVISED date,
  primary key REF_ADVISE_HIST (STUDENT_ID, DATE_ADVISED)
) ENGINE = INNODB;

insert into ADVISE_HIST values ('cmd', 'gbrandich@thisdomain.com', CURRENT_DATE);
insert into ADVISE_HIST values ('ctd', 'gbrandich@thisdomain.com', CURRENT_DATE);

在最后两个插入中,第一个工作。第二个应该抛出外键约束错误。