为什么大多数SQL数据库允许两次定义相同的索引?

时间:2010-07-28 19:00:02

标签: sql indexing constraints

为什么大多数SQL数据库允许两次定义相同的索引(或约束)?

例如在MySQL中,我可以这样做:

CREATE TABLE testkey(id VARCHAR(10) NOT NULL, PRIMARY KEY(id));
ALTER TABLE testkey ADD KEY (id);
ALTER TABLE testkey ADD KEY (id);
SHOW CREATE TABLE testkey;
CREATE TABLE `testkey` (
  `id` varchar(10) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `id` (`id`),
  KEY `id_2` (`id`)
)

我没有看到任何两次具有相同索引或约束的用例。我希望SQL数据库不允许我这样做。

我也没有看到命名索引或约束的重点,因为我可以像创建它一样引用它们进行删除。

6 个答案:

答案 0 :(得分:1)

所有编程语言允许编写裁员:

<?php
$foo = 'bar';
$foo = 'bar';

这只是一个例子,你显然可能有重复的代码,重复的功能或重复的数据结构,这些更浪费。

由您自己编写好的代码,这取决于具体情况。也许在极少数情况下写一些看似多余的东西是有充分理由的。在这种情况下,如果技术没有允许你这样做,你就会被淘汰出局。

您可能对一个名为Maatkit的工具感兴趣,该工具是MySQL用户不可或缺的工具集合。其中一个工具检查重复键:

http://www.maatkit.org/doc/mk-duplicate-key-checker.html

如果您是MySQL开发人员,新手或专家,您应立即下载Maatkit并留出一整天阅读文档,试用该集中的每个工具,并学习如何将它们集成到您的日常开发中任务。你会因为不早点这样做而踢自己。

对于命名索引,它允许您执行此操作:

ALTER TABLE testkey DROP KEY `id`, DROP KEY `id_2`;

如果未命名,则无法删除单个索引。您必须删除整个表并在没有索引的情况下重新创建它。

答案 1 :(得分:1)

有几个原因浮现在脑海中。对于支持多种索引类型的数据库产品,您可能希望将相同的字段或字段组合多次索引,每个索引根据预期用途具有不同的类型。例如,一些(可能是大多数)数据库产品具有树形结构索引,其对于直接查找(例如KEY_FIELD = 1)和范围扫描(例如KEY_FIELD&gt; 0和KEY_FIELD <5)都是有益的。此外,一些(但绝对不是全部)数据库产品也支持散列索引类型,它只对直接查找有用但速度非常快(例如,可用于比较,例如KEY_FIELD = 1但不能用于范围比较)。如果您需要非常快速的直接查找时间但仍需要提供范围比较,那么创建树结构索引和散列索引可能会很有用。

某些数据库产品确实会阻止您对表具有多个主键约束。但是,防止所有可能的重复可能需要数据库供应商的更多努力,而不是他们认为合理。在开源数据库的情况下,主要开发人员可能会认为,如果给定的功能对给定用户来说是一个足够大的交易,那么应该由该用户发送代码补丁以启用它所具有的任何功能。通缉。开源并不是“我使用你的开源产品的委婉说法;因此,你现在是我的奴隶,必须实现我可能想要的所有功能!”。

最后,我认为可以说,供软件开发人员使用的产品可以将其视为用户在使用产品时应该采取合理谨慎的假设。

答案 2 :(得分:1)

只有两个很好的理由 - 我能想到 - 允许两次定义相同的索引

  1. 与两次定义相同索引的现有脚本兼容。
  2. 改变实施需要我不愿意做的工作,也不需要为
  3. 付费

答案 3 :(得分:0)

我可以看到一些数据库阻止重复索引。 Oracle数据库防止重复索引https://www.techonthenet.com/oracle/errors/ora01408.php,而MySQL和PostgreSQL等其他数据库没有重复的索引预防。

答案 4 :(得分:-1)

你不应该在一个表中有这么多索引的情况下,你不能快速查看并查看那里的索引。

至于命名约束和索引,我只是命名约束。我将命名一个约束FK_CurrentTable_ForeignKeyedColumn,以便在快速查看它们列表时更加明显。

答案 5 :(得分:-1)

因为支持覆盖索引的数据库 - Oracle,MySQL,SQL Server ......(但奇怪的是PostgreSQL)。覆盖索引意味着索引两个或更多列,并从左到右处理该列列表以便使用它们。

因此,如果我在第1列,第2列和第3列定义覆盖索引 - 我的查询至少需要使用第1列来使用索引。下一个可能的组合是第1列和第1列。 2,最后1,2和3。

那么我的查询只使用第3列呢?如果没有其他两列,则不能使用覆盖索引。这只是第2列使用的问题......无论哪种情况,我都会考虑第2列和第3列的单独索引。