为什么引用不起作用

时间:2013-01-19 14:43:17

标签: mysql sql foreign-keys

尝试使用MySQL示例向其他人解释REFERENCES CONSTRAINT,但我不能让讨厌的示例工作!如果我将它定义为FOREIGN KEY,它似乎有效,但是我的教科书说我不必这样做(使它成为列级参照约束而不是表级约束)。

问题是,在dept表中UPDATE到dname之后,为什么emp表中的dname不会改变?

-- SQL CODE BEGINS
DROP TABLE IF EXISTS dept;
DROP TABLE IF EXISTS emp;

CREATE TABLE dept (
    dname CHAR(10),
    dnum  numeric(3,0)
) ENGINE=InnoDB;

CREATE TABLE emp (
  dname CHAR(10) REFERENCES dept(dname) ON UPDATE CASCADE,
  ename CHAR(10)
) ENGINE=InnoDB;

INSERT INTO dept VALUES ("AAA", 111);
INSERT INTO dept VALUES ("BBB", 222);

INSERT INTO emp VALUES ("CCC", "Carol"); 
INSERT INTO emp VALUES ("AAA", "Alice");

SELECT * from dept;
SELECT * from emp;
UPDATE dept SET dname="XYZ" WHERE dnum=111;
SELECT * from dept;
SELECT * from emp;

-- SQL CODE ENDS

哎呀!

2 个答案:

答案 0 :(得分:2)

  • DECLARE dept.dname AS PRIMARY KEY
  • emp.dname
  • 上创建一个FOREIGN KEY约束

全DDL:

CREATE TABLE dept
(
    dname CHAR(10) PRIMARY KEY,
    dnum  numeric(3,0)
) ENGINE=InnoDB;

CREATE TABLE emp 
(
  dname CHAR(10) ,
  ename CHAR(10),
  CONSTRAINT em_FR FOREIGN KEY (dname)
      REFERENCES dept(dname) ON UPDATE CASCADE
) ENGINE=InnoDB;

答案 1 :(得分:1)

摘自MySQL 5.5参考手册

<剪断>

InnoDB无法识别或支持“内联REFERENCES规范”(在SQL标准中定义),其中引用被定义为列规范的一部分。仅当指定为单独的FOREIGN KEY规范的一部分时,InnoDB才接受REFERENCES子句。对于其他存储引擎,MySQL Server会解析并忽略外键规范。

< /剪断>

http://dev.mysql.com/doc/refman/5.5/en/create-table.html

我认为您的两本教科书的作者应该注意到他们推荐的方法,在列定义中添加“REFERENCES”子句,不会创建或强制执行外键约束。


为了创建外键约束,您需要在目标列上使用唯一索引。在您的情况下,您需要dept(dname)上的索引。

ALTER TABLE dept ADD CONSTRAINT dept_UX 
  UNIQUE KEY (dname) ; 

有了这个,你就可以创建一个外键约束:

ALTER TABLE emp ADD CONSTRAINT FK_emp_dept 
  FOREIGN KEY (dname) REFERENCES dept(dname) ON UPDATE CASCADE ;

(通常,外键引用表的PRIMARY KEY。但是UNIQUE KEY就足够了。实际上,对于InnoDB,所需要的只是一个索引,它不一定是唯一的,但我们不是我想去那里。)

将dname声明为PRIMARY KEY而不是UNIQUE KEY:

ALTER TABLE dept ADD PRIMARY KEY (dname) ;

REFERENCES子句添加到列定义中时,我相信MySQL会忽略它。 (语法被接受,但它没有被记录在数据字典中。如果你正在使用MyISAM,那没关系,因为MyISAM不强制执行外键约束。)

要创建外键约束作为表定义的一部分,我将其放在一个单独的行上:

 CREATE TABLE emp (
 dname CHAR(10), 
 ename CHAR(10),
 CONSTRAINT FK_emp_dept FOREIGN KEY (dname) REFERENCES dept(dname)
 ) ENGINE=InnoDB ;