即使我没有主键或唯一键,InnoDB仍会在合成列上创建群集索引,如下所述。
https://dev.mysql.com/doc/refman/5.5/en/innodb-index-types.html
那么,为什么InnoDB必须要求聚集索引?是否有一个defenite原因聚集索引必须存在于这里?
在Oracle数据库或MSSQL中,我不认为他们需要这个。 另外,我也不认为集群索引与普通表相比具有如此巨大的优势。
使用群集密钥查找数据确实不需要额外的磁盘读取,并且比没有群集索引但没有群集索引更快,通过使用物理rowID可以更快地查找辅助索引。 因此,我没有看到任何坚持使用它的理由。
答案 0 :(得分:1)
其他供应商有一个" ROWNUM"或类似的东西。 InnoDB要简单得多。而不是拥有那种动物,它只需要你通常想要的东西。在这两种情况下,它都是唯一标识行的值。这需要交易的内容 - 知道要锁定哪些行等,以提供事务完整性。 (我不会在这里进入理由。)
在要求(或提供)PK时,以及在进行某些其他简化时,InnoDB牺牲了几个很少使用(或易于解决)的功能:多个pks,多个聚簇索引,没有pk等。
由于"合成柱"需要6个字节,简单地提供id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
几乎总是更好,即使您不使用它。但是如果你不使用它,但确实有一个非NULL UNIQUE
键,那么你也可以把它变成PK。 (正如MySQL默认做的那样。)
通过辅助密钥的查找首先从辅助密钥的BTree获取PK值。然后向下钻取主BTree(用PK命令的数据)以找到该行。因此,二级密钥可能比使用PK更慢。 (通常情况下这还不够慢。)因此,这指出一个设计决策需要 PK。)(其他供应商使用ROWNUM或其他东西来定位记录,而不是PK。)
回到"为什么?"。在MySQL中有很多决策,设计师说这些决定对于这个免费产品来说简单性更好,让我们不再费心去构建一些复杂但很少使用的功能。起初没有子查询(临时表是一种解决方法)。没有意见(他们只是语法糖)。没有物化视图(好的,这可能是失败的;但可以模拟它们)。没有位映射或散列或isam(等)索引(BTree非常适合"全方位"用法)。
此外,通过"聚类" PK与数据,通过PK查找本质上比竞争对手更快(没有通过ROWNUM)。 (辅助键查找可能不会更快。)
另一个不同之处 - MySQL在实现" index merge"时很晚,其中它使用两个索引,然后是结果的AND或OR。这对于ROWNUM来说是有效的,但对于群集PK则不是。
(我不是MySQL / MariaDB / Percona开发人员,但自1999年以来我一直使用它们,几乎所有主要的MySQL会议,其中内部信息经常被泄露。所以,我认为我有足够的洞察他们提出这个答案的想法。)