尝试使用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
哎呀!
答案 0 :(得分:2)
dept.dname
AS PRIMARY KEY
emp.dname
全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 ;