Делает ли поле уникальным сделать его индексированным?

10

Если я наложу uniqueограничение на поле, нужно ли мне также создать индекс для этого поля, чтобы получить масштабируемое время вставки? Или это сделано для меня (даже если индекс, который он использует, не является общедоступным?)

В частности, я работаю с Apache Derby для создания прототипов, хотя я, вероятно, перенесу его в MySQL в ближайшем будущем. Я также надеюсь, что в стандарте SQL может быть что-то, что об этом говорит.

У меня никогда не будет необходимости искать по этому полю, поэтому я бы не стал делать бесполезный индекс. Но я бы предпочел бесполезный индекс, чем время O(n)вставки.

corsiKa
источник
2
Из того, что я знаю, уникальное ограничение реализовано за использованием уникального индекса. В этом вопросе вы можете увидеть некоторые мнения относительно этой ситуации: когда использовать уникальное ограничение вместо уникального индекса?
Мариан
@Marian спасибо за эту ссылку. Это было очень проницательно.
CorsiKa

Ответы:

2

--РЕДАКТИРОВАТЬ--

Мой оригинальный ответ (ниже), вероятно, вам вообще не нужен, потому что он не затрагивает вопрос об uniqueограничениях. Как уже говорили другие, эти ограничения обычно реализуются с подразумеваемым уникальным индексом. В особых случаях это может быть не так (например, disable novalidateдля Oracle).

Вопрос может быть: возможно ли обеспечить уникальность без индекса? В общем случае ответ отрицательный, хотя в некоторых случаях кластеризованный индекс будет означать, что индекс и таблица - это один и тот же объект.

--END EDIT--

Вы сказали: «Я бы предпочел иметь бесполезный индекс, чем иметь время вставки O (n)», но в общем случае базы данных не имеют времени вставки O (n). Есть два случая для рассмотрения:

  1. Обычная таблица с индексами или без них:

    Новые строки сбрасываются в верхней части кучи. СУБД, вероятно, рассматривает только 1 блок, поэтому не только O (1), но и очень маленький O (1).

    Если таблица имеет индексы, к каждому из них будет добавлен указатель на строку. Обычно это операция O (log (n)).

  2. Таблица с какой-либо кластеризацией, например, организованная индексная таблица или кластер для Oracle, или кластеризованный индекс для SQL Server и другие:

    Новые строки вставляются в конкретный блок, что может привести к разделению или переполнению блока, но что бы ни случилось, это все равно O (log (n)) или лучше , вызванное b-деревом или аналогичной структурой, используемой для поиска блока.

Джек говорит, попробуйте topanswers.xyz
источник
Но уникальность без индекса будет такова, O(n)как вы должны проверить всю таблицу. Вот чего я пытаюсь избежать.
CorsiKa
Это действительно лучший ответ на этот вопрос !!! +1
RolandoMySQLDBA
@ Трюк - да, я сначала не понял. Боюсь, индекс - это цена, которую вы платите за ограничение уникальности. Можете ли вы использовать кластерный индекс в вашем случае?
Джек говорит, попробуйте topanswers.xyz
1
@JackPDougless Я могу использовать стандартный «индекс» и получить время O(lg n)вставки. Это не проблема. Мой вопрос заключается в том, создаст ли для меня система, зная, что вам нужен этот индекс, чтобы получить приличное время вставки.
CorsiKa
2

ПЕРВИЧНЫЙ КЛЮЧ> = УНИКАЛЬНЫЙ> = ИНДЕКС == КЛЮЧ

Данные InnoDB заказываются PK. MyISAM PK действует так же, как UNIQUE.

INSERT должен добавить «строку» к каждому индексу (любого вида), который у вас есть. Это займет некоторое время. (Обычно не хватает времени, чтобы иметь значение.) Все индексы хранятся в формате BTree. Блоки MyISAM BTree составляют 1 КБ; InnoDB использует 16 КБ.

Вставка в InnoDB обновляет PK и данные одновременно.

Вставка в MyISAM обычно «добавляет» данные в .MYD. Отдельно добавляется строка в PK (если есть).

INSERT должен сначала проверить, что для любого ПЕРВИЧНОГО или УНИКАЛЬНОГО ключа нет дублирующего ключа. Это делается с помощью индекса. И, следовательно, почему UNIQUE и FOREIGN KEY CONSTRAINTs действительно строят индексы. Это O (logN), но обычно процессор, а не I / O, потому что при эффективном кэшировании.

Рик Джеймс
источник
Есть ли у вас в спецификации InnoDB цитата, в которой говорится, что UNIQUEограничение создаст индекс без указания пользователем того, что будет сделано?
CorsiKa
Хм ... Нет, просто годы опыта.
Рик Джеймс
И вот способ проверить это ... СОЗДАТЬ таблицу без каких-либо вторичных индексов; do SHOW TABLE STATUS - Index_length будет равен 0. Затем добавьте уникальный индекс; TABLE STATUS теперь покажет что-то. (Возможно, придется поместить нетривиальное количество данных в таблицу.)
Рик Джеймс
1

Чтобы ответить на вопрос, выделенный жирным шрифтом: Да, если поле уникально, оно индексируется как первичный ключ. Фактически, я обсуждал это в другом вопросе, касающемся того, что первичные ключи имеют свое собственное имя, чтобы отличать его от других уникальных (потенциальных) ключей .

Что касается ограничений, индексы создаются для вас так, чтобы была настроена парадигма ограничения. Вы должны быть в состоянии удалить дублирующиеся индексы, даже уникальные ключи, если только введенное вами ограничение не ссылается на другие уникальные ключи, которые вы лично создали, кроме парадигмы ограничения.

Возможно, вам никогда не придется искать это поле, но MySQL непременно должен будет указать его путь, чтобы определить допустимость ключей и определить, как выполнять операции ON DELETE CASCADE и ON UPDATE CASCADE.

Индекс UNIQUE просто гарантирует уникальность кортежей (синглетонов, пар, триплетов, ..., n-кортежей и т. Д.) В каждой строке таблицы.

Вы можете удалить такие дублирующиеся индексы на ваше усмотрение, при условии, что вы не нарушите парадигму ограничений, которую хотите иметь в таблице.

RolandoMySQLDBA
источник
1
Это не отвечает на мой вопрос. Мой вопрос связан со временем вставки. Если у вас есть уникальное ограничение, система должна обеспечить уникальность поля перед вставкой - если в поле нет индекса, ей придется искать всю таблицу ( O(n)). Если есть индекс, поиск будет намного быстрее (вероятно O(lg n)). Это моя проблема. Я хорошо осведомлен о механике ссылочной целостности, меня интересует (для целей этого вопроса) производительность.
CorsiKa