过去几周我一直在慢慢学习SQL。我已经学习了所有关系代数和关系数据库如何工作的基础知识。我现在要做的就是了解它是如何实现的。
我遇到的一个绊脚石是MySQL中的外键。我似乎找不到太多关于它们存在于MySQL所拥有的InnoDB存储架构中的其他内容。
MySQL中实现的外键的简单示例是什么?
这是我写的一个模式的一部分,如果你想指出我的缺点而不是向我展示一个有效的例子,它似乎不起作用。
CREATE TABLE `posts` (
`pID` bigint(20) NOT NULL auto_increment,
`content` text NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`uID` bigint(20) NOT NULL,
`wikiptr` bigint(20) default NULL,
`cID` bigint(20) NOT NULL,
PRIMARY KEY (`pID`),
Foreign Key(`cID`) references categories,
Foreign Key(`uID`) references users
) ENGINE=InnoDB;
答案 0 :(得分:21)
假设您的类别和用户表已经存在并且分别包含cID和uID作为主键,这应该有效:
CREATE TABLE `posts` (
`pID` bigint(20) NOT NULL auto_increment,
`content` text NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`uID` bigint(20) NOT NULL,
`wikiptr` bigint(20) default NULL,
`cID` bigint(20) NOT NULL,
PRIMARY KEY (`pID`),
Foreign Key(`cID`) references categories(`cID`),
Foreign Key(`uID`) references users(`uID`)
) ENGINE=InnoDB;
references
子句中需要列名。
答案 1 :(得分:9)
已编辑: Robert和Vinko声明您需要在外键约束中声明引用列的名称。这在InnoDB中是必需的,尽管在标准SQL中,如果父表中的名称相同,则允许省略引用的列名。
我在MySQL遇到的一个特质是外键声明会在几种情况下无声地失败:
不幸的是,MySQL没有给出它无法创建外键约束的消息。它只是忽略了请求,并创建了没有外键的表(如果你SHOW CREATE TABLE的帖子,你可能看不到外键声明)。我一直认为这是MySQL的一个不好的功能!
提示:整数数据类型的整数参数(例如BIGINT(20))不是必需的。它与存储大小或列的范围无关。无论您给出的参数如何,BIGINT总是相同的大小。如果使用ZEROFILL列修饰符,则数字指的是MySQL将填充列的位数。
答案 2 :(得分:4)
This有一些代码显示如何自己创建外键,以及在CREATE TABLE中。
以下是其中一个较简单的例子:
CREATE TABLE parent (
id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE child (
id INT,
parent_id INT,
INDEX par_ind (parent_id),
FOREIGN KEY (parent_id) REFERENCES parent(id)
ON DELETE CASCADE
) ENGINE=INNODB;
答案 3 :(得分:3)
我同意罗伯特的观点。您缺少references子句中列的名称(您应该收到错误150)。我将补充一点,您可以通过以下方式检查表格的创建方式:
SHOW CREATE TABLE posts;
答案 4 :(得分:1)
以前的答案处理外键约束。虽然外键约束对于维护引用完整性肯定是有用的,但是“外键”的概念本身是数据关系模型的基础,无论你是否使用约束。
无论何时执行equijoin,您都会将外键等同于某些东西,通常是它引用的密钥。例如:
select *
from
Students
inner join
StudentCourses
on Students.StudentId = StudentCourses.StudentId
StudentCourses.StudentId是引用Students.StudentId的外键。