在我用来学习PHP和SQL的视频tutoria / book中,作者解释了使数据库表彼此相关的外键的概念。正如您将在下图中看到的那样,我们目前正在制作一个名为“评论”的表格。在这个SQL中,有一行称为“外键”的行photograph_id INT( 11 ) NOT NULL,
,作者称其将“注释”表与已存在的“照片”表相关联。
我的问题是,由于该表被称为“照片”(复数带有s),但sql外键是“photograph_id”,SQL如何连接这两个?究竟什么是“photograph_id”允许MySQL将它与“照片”表联系起来。
+-----------------------------+
| Tables_in_C263430_quoralist |
+-----------------------------+
| photographs |
| users |
+-----------------------------+
2 rows in set (0.21 sec)
mysql> CREATE TABLE comments (
-> id INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> photograph_id INT( 11 ) NOT NULL,
-> created DATETIME NOT NULL,
-> author VARCHAR( 255 ) NOT NULL,
-> body TEXT NOT NULL
-> );
答案 0 :(得分:5)
MySQL不会自动“连接”这两个表,你必须自己这样做:
CREATE TABLE comments (
id INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY,
photograph_id INT( 11 ) NOT NULL,
created DATETIME NOT NULL,
author VARCHAR( 255 ) NOT NULL,
body TEXT NOT NULL,
FOREIGN KEY (`photograph_id`) REFERENCES `photographs` (`id`) ON DELETE CASCADE
);
这将告诉MySQL你的表comments
有一个外键。您没有为密钥指定名称,因此mysql将自己选择名称。它们的键位于该表的photograph_id
列。密钥指的是表photographs
,其列id
。
也许作者意味着您使用该列“模拟”外键,这意味着您使用该键加入到照片的主键,而不是真正添加外键约束。因此,您(数据库管理员)知道该字段用于关系,但数据库本身不会(因此不会检查字段的完整性:您可以向不存在的照片添加注释)。 / p>
答案 1 :(得分:1)
照片表可能如下所示:
photograph_id image_path
========================================
34343 /images/img_343.jpg
34344 /images/img_344.jpg
34345 /images/img_345.jpg
34346 /images/img_346.jpg
34347 /images/img_347.jpg
这是存储在数据库中的一组照片文件名。请注意,有些人还会采用BLOB格式将照片本身存储在数据库中。
创建评论记录时,SQL会指定上述哪些照片记录用于照片。
答案 2 :(得分:1)
外键字段的实际名称并不重要;它主要用于文档。表的通常命名约定是它们是每行代表的复数,而列名是单数。
通过在从属表中指定外键约束(在您的示例中为注释)将表绑定在一起。请注意,每个表使用的存储引擎会影响系统是否强制执行外键约束。默认的MyISAM存储引擎不强制执行约束; InnoDB存储引擎可以。
答案 3 :(得分:1)
MyISAM
引擎创建表,忽略FOREIGN KEY
子句。您的表格都必须为InnoDB
。我建议你也看一下MySQL中的外键和参照完整性的介绍 - http://www.techrepublic.com/article/an-introduction-to-foreign-keys-and-referential-integrity-in-mysql/6035435
答案 4 :(得分:1)
您必须通过定义外键来告诉它。语法如下:
ALTER TABLE comments ADD CONSTRAINT fk_photgraph_id FOREIGN KEY (photograph_id) REFERENCES photographs (id)
(您可以在CREATE TABLE
语句中一次性执行相同操作,但我更喜欢上述内容,因为这样您可以先创建所有表,然后添加外键,而不必担心正确顺序)。
这将告诉MySQL photograph_id
表中的comments
列链接到id
表中的photographs
列。从那时起,MySQL将检查任何photograph_id
是否与有效的photographs.id
相关联;通过添加ON UPDATE
和ON DELETE
语句,您可以控制它的具体操作 - 例如,如果您指定ON DELETE CASCADE
,则删除照片也会删除所有引用它的注释; ON DELETE SET NULL
会将评论'photograph_id
设置为NULL;在删除所有评论或将其分配到其他照片之前,ON DELETE NO ACTION
和ON DELETE RESTRICT
将拒绝删除照片。级联删除非常强大,因此在使用它们时要小心。您可能删除的内容超出了预期,数据库没有“撤消”按钮。
要记住的一点是,MySQL中的外键只能与InnoDB存储引擎一起使用; MyISAM不支持外键。如果在MyISAM表上指定外键,MySQL将很乐意解析它,然后忽略它而不会引发任何错误。