辅助密钥的目的是什么?假设我有一个表记录了所有签到(类似于Foursquare),列id, user_id, location_id, post, time
,并且可能有数百万行,许多人声称使用辅助键来加速该过程。< / p>
为什么这样做?并且user_id
和location_id
都应该是辅助密钥吗?
我正在使用mySQL btw ...
修改:会有一个页面列出/计算特定用户的所有签到,另一个页面列出已签到特定位置的所有用户
mySQL查询
输入1
SELECT location_id FROM checkin WHERE user_id = 1234
SELECT user_id FROM checkin WHERE location_id = 4321
类型2
SELECT COUNT(location_id) as num_users FROM checkin
SELECT COUNT(user_id) as num_checkins FROM checkin
答案 0 :(得分:3)
密钥(也称为索引)用于加速查询。如果要查看给定用户的所有签入,则需要在user_id字段上使用密钥。如果要查看给定位置的所有检查,则需要在location_id字段上建立索引。您可以在mysql documentation
了解更多信息答案 1 :(得分:0)
我想评论你的问题和你的例子。
让我强烈建议您,因为您使用的是MySQL,所以确保您的表使用innodb引擎类型,原因很多,您可以自行研究。
InnoDB的一个重要特性是您具有参照完整性。那是什么意思?在签入表中,您有一个user_id
的外键,它是用户表的主键。使用引用完整性,MySQL不允许您插入具有user_id的行,该user_id不存在于用户表中。使用MyISAM,你可以。仅此一项就足以让你想要使用它。
关于键/索引的问题,基本上在定义表并为列或某些列组合声明键时,mysql将创建索引。
索引对于性能至关重要,因为表随着行的插入而增长。
所有关系数据库和文档数据库都依赖于BTree indexing的实现。 Btree非常擅长的是使用可预测数量的查找来查找项目(或不是)。因此,当人们谈论关系数据库的性能时,其基本构建块是使用btree索引,这些索引是通过KEY语句或使用alter table或create index语句创建的。
要理解为什么会这样,假设您的用户表只是一个文本文件,每行一行,可能用逗号分隔。当您添加行时,文本文件中的新行将添加到底部。
最终你会发现文件中有10,000行。
现在您想知道您是否为姓氏为史密斯的某个人输入了一行。你怎么能找到它?
如果没有对文件进行任何排序或单独的索引,您只有一个选项,即从文件的第一行开始,扫描表中的每一行以查找匹配项。即使你找到了一个史密斯,也许不是唯一的史密斯&#39;在表格中,每次你想要进行搜索时,你必须从上到下阅读整个文件。
显然随着表的增长,搜索的性能变得越来越差。
在关系数据库用语中,这称为&#34; 表扫描&#34;。数据库必须从第一行开始,扫描每行读取直到它结束。
没有索引,关系数据库仍然有效,但它们高度依赖于IO性能。
使用Btree索引,首先在索引中找到要查找的行。索引具有直接指向所需数据的指针,因此不再需要扫描表,而是读取所需的各个数据页。这就是数据库即使在数百万或者数百万或数百万行的情况下仍能保持足够的性能的方式。
要真正开始深入了解mysql的工作原理,您需要熟悉EXPLAIN EXTENDED ...并开始查看查询的解释计划。像您提供的那些简单的那些将有简单的计划,向您显示要检查的行数以及是否使用一个或多个索引。
对于摘要查询,索引没有帮助,因为您正在执行COUNT()。当您没有其他限制搜索的条件时,需要扫描该表。
我确实注意到摘要查询中的错误。根据您的标签,我认为这些是正确的查询,可以根据您的列别名来获得您想要的内容。
SELECT COUNT(DISTINCT user_id) as num_users FROM checkin
SELECT COUNT(*) as num_checkins FROM checkin
这是使用InnoDB的另一个原因,InnoDB在正确配置时具有类似于其他rdbms(如oracle和sql server)的数据缓存(innodb缓冲池)。 MyISAM根本不会缓存数据,因此如果您反复查询可能需要大量IO的相同类型的查询,MySQL将不得不反复进行所有数据读取工作,而对于InnoDB,该数据很可能会坐在缓存中并返回结果,而不必返回并从存储中读取。
主要与次要
内部确实没有这样的概念。主键是特殊的,因为它允许数据库查找单个行。主键必须是唯一的,并且为了反映这一点,关联的Btree索引是唯一的,这意味着它不允许您在索引中存在具有相同数据的2个键。
索引是否唯一是一个很好的工具,可以让您在许多其他情况下保持数据库的一致性。我们假设您有一名&#39;员工&#39;带有SS_Number列的表来存储社会安全#。如果您希望系统支持通过SS编号查找员工,那么在该列上建立索引是有意义的。如果没有索引,您将进行表扫描。但是您也希望该索引是唯一的,这样一旦插入了带SS#的员工,数据库就无法让您输入具有相同SS#的重复员工。
但是要为你揭开神秘面纱,当你声明键时,这些索引只是为你创建并在大多数情况下自动使用,当你定义表时。
当你不处理密钥(主要或外国)时,例如用户名,第一个,最后一个&amp;你需要知道如何创建一个索引,因为你正在一个或多个不是键的列上搜索(使用where子句条件)。<姓氏,ss#等等。 / p>