繁体   English   中英

索引链接表聪明吗?

[英]Is indexing link tables smart?

举例来说,我有2个表格:“用户”>“项目”

用户可以拥有收藏夹项目,并且一个项目可以有多个将其视为收藏夹的用户,因此我将使用链接表。

现在我的链接表将包含以下内容:

id (int 11 AI)
user_id (int 11)
item_id (int 11)

现在将有必要/有用的是在user_id和item_id上放置索引,因为随着时间的推移该表将包含很多记录。

我不确定何时使用索引。 我的想法是何时使用它们(尽管可能完全不正确)是当您拥有大型数据库并且需要在列上进行搜索/过滤然后为它建立索引时。 如果不正确,很抱歉,这就是我一直被告知的内容。

简而言之,是的。

想象一下,如果每次您需要将主键值与另一个表中的外键进行匹配时,DBMS必须在整个表中搜索匹配的键,那么联接将如何工作。

基本上,是的,就是这样。

在这种情况下,我想说user_id列上的索引将很有用,因为您将向用户显示其收藏夹列表,对吗?

item_id上的索引可能用处不大,因为我怀疑您将显示喜欢某个特定项目的用户列表。 尽管您可能会关心计数(“ 100个用户喜欢此项目”),所以您可能最终会添加该索引。 或者,您可以取消规范化并将计数保留在items表中。 尽管您将需要编写额外的代码来维护该数字,但这将提供更好的性能。

最后但并非最不重要的-在链接表中,您可以id列。 只需在两列上添加主键索引( item_id顺序分别为user_iditem_id )。 这将确保您不能输入重复的行,并且由于user_id是索引的第一列,因此您可以在搜索查询中使用它。 不再需要仅在user_id列上添加单独的索引。

但是,这也取决于您使用的代码。 如果您使用某种需要为每个表分配id列的框架(ORM?),则此技巧无用。


根据要求由作者,这里有一个快速的介绍什么索引

假设您有一个数据库表,它只是一排没有特定顺序的行。 假设我们有一个表格people ,其namesurnameage列。

现在,当您想查找John Smith的年龄时,您可能会进行如下查询:

select age from people where name='John' and surname='Smith'

当您这样做时,数据库引擎只能做一件事-它必须遍历所有行并寻找匹配的行。 如果有100,000行,那将会很慢。

现在有一种更快的方法。 考虑一下电话簿(经典纸质版)。 在数千页的黄页上,有数百人的电话号码。 但是,即使您是人类,也可以很快找到所需的号码。 这是因为数字是按名称和姓氏的字母顺序排序的。 您打开一个随机页面,您可以立即看到您要查找的数字是在打开页面之前还是之后。 重复几次,您已经找到了。

这种搜索称为“二进制搜索”。 如果记录按名称和姓氏排序,那么数据库引擎也可以执行此操作。 因此,这就是主键-它告诉数据库不是按某种随机顺序存储记录,而是按某些列排序。 当出现新记录时,它可以快速找到其应有的位置并将其推入该位置,从而使该表永远保持排序状态。

这里已经有几件事要注意。

首先,您可以按一个或多个列进行排序,但是,就像在电话簿中一样,顺序很重要。 如果您先按name排序,然后按surname排序,那么这就是记录的顺序。因此,您将能够快速找到name='John'name='John' and surname='Smith' ,但是如果您只需要找到surname='Smith' ,那对您完全没有帮助。 就像在电话簿中一样。

其次,将记录推到中间的位置也有些慢。 并非犯罪,但仍然如此。 在末尾附加记录更快。 因此,人们倾向于将auto_increment列用作其主键,因为这样,每个新行都将放在末尾。

第三,在大多数数据库中,主键不仅用于快速搜索,而且还唯一地标识行。 这意味着如果有两行的主键列值相等,则数据库将不满意。 在那种情况下,它无法确定哪个必须先走,哪个必须最后走,而且它也不是唯一的。 使用auto_increment另一个原因。 请注意,如果PK索引中有多个列,则它们的组合必须是唯一的-每个列单独可能是不唯一的。 在我们的情况下,这意味着可以有许多约翰和许多​​史密斯,但只有一个约翰·史密斯。

但是我们仍然有一个问题。 如果我们想快速查找仅包含namesurname行,该怎么办? PK索引只能做这些事情之一,不能同时做。

这是其他非PK索引发挥作用的地方。 您可以将任意数量的表添加到表中。 在我们的例子中,我们可以创建另一个索引来仅保留surname列。

当我们这样做时,数据库会创建另一个隐藏表(好的,不是这样,但您可以这样想),它是原始表的副本,但只有surname列和返回到其中的行的特殊链接原始表。 该隐藏索引表按surname列排序。 因此,当您现在只需要指定surname来查找行时,数据库引擎可以在隐藏的索引表中查找该行,然后将其链接回到原始行并从原始行中获取数据。 快多了。

这些非PK指数通常也有几种味道。 有一个标准的“索引”根本没有任何限制-您可以在列,空值等中有重复的值。有一个“唯一的”索引,它强制索引中的所有值都必须是唯一的。 然后有时会有一些特殊的索引,例如FullText,Spatial等。索引也倾向于具有一些技术选择,但是您必须阅读这些的数据库文档。

最后要注意的一件事是-索引可以快速地在表中查找内容,但是它们要付出一定的代价。 对表的修改(插入,更新,删除)变慢,因为索引也需要更新。 请记住这一点,仅在必要时添加它们。

除主键外。 始终添加主键。 那是命令! :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM