0

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

问题是,对dept表中的dname进行UPDATE后,为什么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

啊!

4

2 回答 2

2
  • 声明dept.dnamePRIMARY KEY
  • 创建一个 FOREIGN 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;
于 2013-01-19T14:46:02.983 回答
1

摘自 MySQL 5.5 参考手册

<剪辑>

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

</snip>

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 ;
于 2013-01-19T14:55:17.590 回答