过去几周我一直在慢慢学习 SQL。我已经掌握了所有关系代数以及关系数据库如何工作的基础知识。我现在想做的是了解它是如何实现的。

我在这方面遇到的一个绊脚石是 MySQL 中的外键。除了它们存在于 数据库 MySQL 具有的存储架构。

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;
有帮助吗?

解决方案

假设您的类别和用户表已经存在并且分别包含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 子句中需要列名。

其他提示

编辑: Robert 和 Vinko 指出您需要在外键约束中声明引用列的名称。这在 InnoDB 中是必要的,尽管在标准 SQL 中,如果引用的列名与父表中的名称相同,则允许您省略引用的列名。

我在 MySQL 中遇到的一个特性是外键声明在几种情况下会默默失败:

  • 您的 MySQL 安装不包括 innodb 引擎
  • 您的 MySQL 配置文件未启用 innodb 引擎
  • 您没有使用 ENGINE=InnoDB 表修饰符声明您的表
  • 外键列与引用表中的主键列的数据类型不完全相同

不幸的是,MySQL 没有给出任何消息表明它无法创建外键约束。它只是忽略该请求,并创建没有外键的表(如果您显示 CREATE TABLE 帖子,您可能会看到没有外键声明)。我一直认为这是MySQL的一个不好的特性!

提示: 整数数据类型的整数参数(例如BIGINT(20)) 不是必需的。它与列的存储大小或范围无关。无论您给出什么参数,BIGINT 始终具有相同的大小。该数字是指如果使用 ZEROFILL 列修饰符,MySQL 将填充该列的位数。

这个有一些代码显示如何自己创建外键,以及在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;

我同意罗伯特的观点。您缺少references子句中列的名称(您应该收到错误150)。我将补充一点,您可以通过以下方式检查表格的创建方式:

SHOW CREATE TABLE posts;

以前的答案处理外键约束。虽然外键约束对于保持参照完整性肯定是有用的,但是“外键”的概念仍然是有用的。无论您是否使用约束,本身都是数据关系模型的基础。

每当你进行 equijoin 时,你就等于某事物的外键,通常是它引用的键。例如:

select *
from 
   Students
inner join
   StudentCourses
on Students.StudentId = StudentCourses.StudentId

StudentCourses.StudentId是引用Students.StudentId的外键。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top