0

MySQLの例を使用して、REFERENCES CONSTRAINTを他の人に説明しようとしていますが、厄介な例を機能させることはできません。それを外部キーとして定義すれば機能するように見えますが、それを行う必要はないと言っている教科書があります(テーブルレベルではなく列レベルの参照制約にします)。

問題は、deptテーブルの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

ARGH!

4

2 に答える 2

2
  • dept.dnameとして宣言PRIMARY KEY
  • にFOREIGNKEY制約を作成します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

MySQL5.5リファレンスマニュアルからの抜粋

<snip>

InnoDBは、参照が列仕様の一部として定義されている「インラインREFERENCES仕様」(SQL標準で定義されている)を認識またはサポートしません。InnoDBは、個別のFOREIGNKEY指定の一部として指定された場合にのみREFERENCES句を受け入れます。他のストレージエンジンの場合、MySQLサーバーは外部キー指定を解析して無視します。

</ snip>

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

あなたの2つの教科書の著者は、列の定義に「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をUNIQUEKEYではなくPRIMARYKEYとして宣言するには:

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 に答える