索引和外键有什么区别?

19

我想创建一个包含3个表的数据库,其中一个是用于文章,另一个是用于标签,第三个将帖子与标签相关联,使用post_id和tag_id作为外键引用。

您能解释一下在这种情况下索引(Index)是什么以及它与外键(Foreign Key)的区别,以及它如何影响我的数据库设计吗?

6个回答

25

表上的索引是一种数据结构,可以使对行的随机访问变得快速高效。它有助于优化表的内部组织。

外键只是指向另一个表中相应列的指针,形成两个表之间的参照约束。


8
一个索引是为了在表中快速查找数据而添加的。索引可以有约束条件,即用于创建索引的列必须是唯一的(unique:对于该索引只返回数据库中的一个行,或者non-unique:返回多个行)。表的主键是唯一索引,通常只有一个列。
外键是一个在表中引用另一个表中唯一索引的值。它用作关联表的方法。例如,子表可以通过其在父表中的唯一索引列查找一个父行。

约束(特别是唯一约束)基本上是列的属性,而不是索引。 - Dmitry

6
你的第三个表将会有外键。索引不是必需的,只有在你想要快速通过ID查找大量数据时才需要它们。也许你会想在文章主键上建立一个索引,但是DBMS可能会自动创建它。
索引是冗余的数据结构,可以加速某些查询。 对于实际问题来说,外键是确保表格之间没有无效指针的一种方法(在你的情况下,从关系表到文章和标签)。

2
外键不强制执行NOT NULL规则。外键对列的值施加约束条件。 - jabbie
他所说的并不是强制设置 NOT NULL 值,而是确保子表中的 Id 值存在于父表中。 - Noah Goodrich
没错。谢谢你的解释,Gabriel。 - Dmitry

3
问题: 你能解释一下在这种情况下索引是什么以及它与外键的区别,以及它对我的数据库设计有何影响吗?

在您的Posts_Tags表中,外键是两列。使用外键时,每个外键列必须包含来自所引用的主表的值。在这种情况下,是Posts和Tags表。

Posts_Tags->PostID必须是Posts->PostID中包含的值。

Posts_Tags->TagID必须是Tags->TagID中包含的值。

将索引视为已经为查询/搜索其值提供了增加的速度和效率的列,但代价是增加了数据库的大小。通常,主键是索引,其他需要在网站上进行查询/搜索的列,在您的情况下,可能是帖子名称(Posts->PostName)。

在您的情况下,索引对您的设计几乎没有影响(它们可以提高速度和效率),但外键非常重要,以避免数据损坏(其中包含与帖子和/或标记不匹配的值)。


2
您描述的是一种非常常见的数据库结构,称为“多对多关系”。
索引不应该对此架构产生任何影响。实际上,索引不应该影响任何架构。索引是空间和时间之间的权衡:索引指定您愿意使用额外的存储空间,以换取通过数据库更快地搜索。
维基百科有一篇关于数据库索引的优秀文章:Index (database)

1

你提供的链接仅适用于MySQL中的InnoDB数据库。更好的链接可以在“http://dev.mysql.com/doc/refman/5.1/en/example-foreign-keys.html”找到。 - Chip Uni
我认为MySQL会自动在主键和引用列上创建索引。 - Dmitry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接