首页 / MYSQL / MySQL:破解外键实现?
MySQL:破解外键实现?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了MySQL:破解外键实现?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3443字,纯文字阅读大概需要5分钟。
内容图文
![MySQL:破解外键实现?](/upload/InfoBanner/zyjiaocheng/904/b0f1dca667374202bd9b8c65e5e5a040.jpg)
用于在MySQL中定义外键的内联语法似乎没有做任何事情,而较长的CONSTRAINT语法似乎按预期工作.我很好奇为什么会这样.
我最近发现用于定义外键的内联语法(我认为它可以正常工作)不会对参照完整性进行任何实际检查. ON DELETE / UPDATE子句中定义的内容无关紧要.
我当然用InnoDB尝试了这个,因为我知道MyISAM不支持外键检查.
请看一下示例/小提琴,你会明白我的意思.
内联语法
这是根据我多年来使用的文档定义外键的正确方法.
-- Create a basic foreign key relationship.
CREATE TABLE `parent` (
`id` INTEGER UNSIGNED PRIMARY KEY AUTO_INCREMENT,
`a` VARCHAR(255) NOT NULL
)ENGINE=InnoDB; -- Just to be sure.
CREATE TABLE `child` (
`id` INTEGER UNSIGNED PRIMARY KEY AUTO_INCREMENT,
-- Short legitimate syntax, frequently used.
`parent_id` INTEGER UNSIGNED NOT NULL REFERENCES `parent` (`id`)
ON DELETE RESTRICT
)ENGINE=InnoDB; -- Just to be sure.
现在,如果我从父表中删除了一个在子表中引用的行,就会删除它,因为我从未定义过外键.
亲自试试:Fiddle
CONSTRAINT语法
使用CONSTRAINT关键字的语法越长,编写起来就越麻烦,但与内联定义相比,似乎可以按预期工作.
-- `parent` table has been omitted, since it is the same as above.
CREATE TABLE `child` (
`id` INTEGER UNSIGNED PRIMARY KEY AUTO_INCREMENT,
`parent_id` INTEGER UNSIGNED NOT NULL,
-- Longer, more cumbersome syntax.
CONSTRAINT `fk_child_parent` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)
ON DELETE RESTRICT
)ENGINE=InnoDB; -- Just to be sure.
如果我尝试从父级删除引用的行,则会按预期失败.
自己尝试一下:Fiddle(您必须取消注释左侧的最后一个语句才能看到它失败)
结论/实际问题
正如你在fiddles中看到的那样,用于创建外键的内联语法似乎没有做任何事情,而较长的CONSTRAINT语法可以正常工作.
有谁知道为什么会这样?有什么理由或者这只是我们必须解决的另一个MySQL怪癖吗?
请分享你的知识,我很好奇.
更新/显示CREATE TABLE验证
这是@MikePurcell指出的SHOW CREATE TABLE的输出.
“短”语法
CREATE TABLE `child`(
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`parent_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
CONSTRAINT语法
CREATE TABLE `child` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`parent_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_child_parent` (`parent_id`),
CONSTRAINT `fk_child_parent` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
现在很清楚,解析器只是使用“short”语法忽略表定义中的REFERENCES子句.至少文档更新会有所帮助.谢谢你的帮助.
仅供参考:这已经在2004年(Bug #4919)作为错误提交,似乎已经知道了一段时间.我真的希望他们至少会更新有关这方面的文件,因为我认为这不会很快修复.
解决方法:
我以前唯一知道的“短语法”是:
create_definition: col_name column_definition ... | [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,...) reference_definition reference_definition: REFERENCES tbl_name (index_col_name,...) [MATCH FULL | MATCH PARTIAL | MATCH SIMPLE] [ON DELETE reference_option] [ON UPDATE reference_option]
注意强制FOREIGN KEY子句.
但是,解析器确实接受您使用的“更短语法”,in accordance with the manual:
column_definition: data_type [NOT NULL | NULL] [DEFAULT default_value] ... [reference_definition]
注意缺少FOREIGN KEY子句.
事实上,这种奇怪的行为记录在同一页面中:
MySQL parses but ignores “inline
REFERENCES
specifications” (as
defined in the SQL standard) where the references are defined as part
of the column specification. MySQL acceptsREFERENCES
clauses only
when specified as part of a separateFOREIGN KEY
specification.
该限制也在in the tutorial中进行了更广泛的讨论.
这是一个错误还是一个缺失的功能has been long debated,所以看来.
内容总结
以上是互联网集市为您收集整理的MySQL:破解外键实现?全部内容,希望文章能够帮你解决MySQL:破解外键实现?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。