我正在关注Phil Greenspun's tutorial on SQL.
Phil使用Oracle进行教程,但我使用的是MySQL。以下是我的疑问:
mysql> CREATE TABLE mailing (
-> email varchar(100) not null primary key,
-> name varchar(100)
-> );
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO mailing (email, name) VALUES ('foo@bar.com', 'FooBar');
Query OK, 1 row affected (0.00 sec)
mysql> CREATE TABLE phone (
-> email varchar(100) not null references mailing,
-> phone varchar(20)
-> );
Query OK, 0 rows affected (0.00 sec)
如您所见,我已将email
表的phone
列设置为参考。
教程说:
phone
表有一个参考 完整性约束(“引用mailing
“)以确保我们不这样做 记录人们的电子邮件地址 我们不知道他们的名字
那么这个查询怎么起作用?:
mysql> INSERT INTO phone (email, phone) VALUES ('new@new.com', '112223');
Query OK, 1 row affected (0.00 sec)
...请注意,new@new.com
表格中没有mailing
。
我错过了什么?
答案 0 :(得分:5)
MySQL中的引用仅适用于InnoDB引擎,请按如下方式重写CREATE TABLE:
CREATE TABLE phone (
-> email varchar(100) not null references `mailing` (`email`),
-> phone varchar(20)
-> ) ENGINE=InnoDB;
默认情况下,MySQL使用忽略“引用”语句的MyISAM引擎。 阅读更多关于在MySQL中创建表的documentation
更新: 外键引用必须放在CREATE TABLE语句之外。谢谢,@ jswolf和@a_horse_with_no_name
CREATE TABLE phone (
-> email varchar(100) not null,
-> phone varchar(20),
-> REFERENCES `mailing` (`email`)
-> ON DELETE NO ACTION
-> ON UPDATE NO ACTION
-> ) ENGINE=InnoDB;
没有测试,但更有可能它会起作用。
答案 1 :(得分:3)
除了Nemoden的回答:
您的下一个问题将是Phil的示例,其中包含MySQL根本不支持的检查约束(并且没有存储引擎执行此操作)。
答案 2 :(得分:1)
作为Nemoden的回答,你应该使用InnoDB,而不是MyISAM。
FOREIGN KEY
关系可以(并且应该在MYSQL中)添加如下:
CREATE TABLE phone
( email varchar(100) NOT NULL
, phone varchar(20) DEFAULT NULL
, FOREIGN KEY fk_mailing (email) --- the "fk_mailing" name is optional
REFERENCES mailing (email)
)
ENGINE=InnoDB
DEFAULT CHARSET = utf8 ; --- or other charset you prefer
从您使用的教程:
我正在使用MySQL,我想评论一下我遇到的障碍 我正在按照本页面的教程进行操作。也许其他新手可以从中受益。
据我所知:
a)MySQL支持表的不同“存储引擎”。这可能是 一件好事。但是,并非所有引擎都支持参考约束。
b)对于支持“引用”约束的MySQL表,它必须是InnoDB类型。 在我的安装中(在SuSE Linux上,在标准RPM二进制包之外),这个 是不是的默认值。因此,您必须更改要进行的服务器配置 这是默认值,或者在结束括号后指定“ENGINE = InnoDB” 表定义。
c)即使对于InnoDB,上面的Phil描述的语法也不起作用,尽管如此 没有被拒绝,只是被忽略。根据手册,这实际上是只是一个 评论给开发人员这个列应该引用另一列, 即使mysql没有强制执行约束。
d)因此,使这种约束工作的唯一方法是:1。制作表格 InnoDB和2.使用“FOREIGN KEY(email)REFERENCES mailing_list(email)”格式 作为表定义中的单独条目。
[MySQL甚至不会发出警告!甚至没有提醒这样的参考条款 仅仅是“评论”。它会很高兴地忽略它们并允许任何旧值 那一排。啊。]
-- Antonio Ramirez, March 19, 2007