Можете ли вы иметь несколько ключей в SQL и зачем вам это нужно? - PullRequest
3 голосов
/ 17 июня 2011

Есть ли причина, по которой вы хотели бы иметь несколько КЛЮЧЕЙ в ТАБЛИЦЕ?Какой смысл иметь несколько ключей в одной таблице?

Вот пример, который я нашел:

CREATE TABLE orders(
id INT UNSIGNED NOT NULL AUTO INCREMENT,
user_id INT UNSIGNED NOT NULL,
transaction_id VARCHAR(19) NOT NULL,
payment_status VARCHAR(15) NOT NULL,
payment_amount DECIMAL(15) NOT NULL,
payment_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(id),
KEY(user_id),
)

Кроме того, вы заметите, что программист DBase не делает transaction_id a KEY.Есть ли причина для этого?

Ответы [ 5 ]

4 голосов
/ 17 июня 2011

KEY в MySQL - это альтернативный синтаксис для «индекса».
Индексы являются общими для всех баз данных, но на данный момент они не охвачены ANSI - это просто чудеса, которые так же похожи, как и они.Может быть распространено иметь более одного индекса, связанного с таблицей - потому что индексы улучшают извлечение данных за счет скорости обновления / удаления / вставки.

Помните, что MySQL (5.x?) Автоматически создаетиндекс, если он еще не существует для первичного ключа таблицы.

4 голосов
/ 17 июня 2011

Существует несколько возможных причин.

  • Повышение производительности поиска (когда в предложении WHERE используются поля KEY, оно работает быстрее)
  • Ограничение содержимого таблицы (при использовании ключа UNIQUE длястолбец, он не может иметь одно и то же значение дважды или более)

Это наиболее распространенные причины.

3 голосов
/ 17 июня 2011

В SQL у вас может быть только один PRIMARY KEY на таблицу.

KEY(foo) - поддельный синтаксис в стандартном SQL.В MySQL KEY foo является плохо названным синонимом для INDEX foo и не накладывает УНИКАЛЬНОЕ ограничение.(Он плохо назван, потому что на самом деле он не относится к функционированию ключа.)

Может быть несколько UNIQUE INDICES, которые могут играть роль «ключей-кандидатов».(Уникальное ограничение может быть указано без ассоциированного индекса, но точка «ключа», как правило, представляет собой быстрый просмотр .) Точка PRIMARY KEY заключается в уникальной идентификацииотдельная запись и почти исключительно поддерживается индексами и может даже иметь прямое отношение к кластеризации данных.

Только минимальный объем [уникальных] ИНДИКСОВ, необходимый для , обеспечивает достоверность данных и соответствуют требованиям к производительности * Следует использовать 1020 * - они налагают штрафы на производительность для механизма запросов, а также требуют дополнительных затрат на обновление и обслуживание.

Неуникально INDEX's(INDEX foo, или в случае MySQL, KEY foo) исключительно для того, чтобы база данных могла оптимизировать запросы.Они на самом деле не отображаются на "ключи" и могут называться "индексами покрытия";если они выбраны планировщиком запросов, эти индексы могут повысить производительность, даже если они ничего не добавляют к самой логической модели.(По соображениям производительности ядро ​​базы данных может потребовать, чтобы FOREIGN KEYS были покрыты индексами.)

В этом случае создание INDEX ( не думайте «KEY»! ) для user_id обычно (значительно) ускоряет запросы с такими предложениями, как:

... WHERE user_id = {somenumber}

Без индекса вышеупомянутый запрос потребует полного сканирования таблицы (например, чтение всех записей).

ПокаЯ не знаю, почему transaction_id не является индексом, это может не потребоваться (или даже вредно для данных шаблонов доступа ) - рассмотрим случай, когда каждый запрашивает, чтодолжен быть быстрым:

  1. Не использует transaction_id или;
  2. Также имеет user_id = ... или другое ограничение, которое может использовать INDEX.Таким образом, в случае, подобном WHERE user_id = ... AND transaction_id = ..., планировщик запросов , вероятно, сначала найдет записи для соответствующего пользователя , а затем ищет соответствующий transaction_id - он все еще долженсделать сканирование, но только на гораздо меньший набор данных , чем исходная таблица.Только простой WHERE transaction_id = ... обязательно потребует ПОЛНОГО СКАНИРОВАНИЯ.

В случае сомнений используйте EXPLAIN - или другой анализатор запросов - ипосмотрите, что MySQL думает , что он должен делать.И последнее замечание: иногда оценочные планы выполнения запросов могут отличаться от фактических планов выполнения, и устаревшая статистика может заставить планировщика запросов выбирать неидеальный план.

Счастливое кодирование.

0 голосов
/ 17 июня 2011

В теории баз данных ключ - это ограничение, обеспечивающее уникальность.Relvar (аналог таблицы SQL) может действительно иметь несколько ключей-кандидатов.Классическим примером является набор химических элементов, для которых имя, символ, атомный номер и атомный вес являются ключами (и народ по-прежнему захочет добавить свой собственный суррогатный ключ к нему;)

MySQL продолжается долготрадиция злоупотребления словом KEY, сделав его синонимом INDEX.Ясно, что таблица MySQL может иметь столько индексов, сколько необходимо для производительности при заданном наборе обстоятельств.

Из вашего DDL SQL кажется очевидным, что идентификатор является суррогатным ключом, поэтому мы должны искать естественныйключ с не так много, чтобы продолжить.Хотя transaction_id может быть кандидатом, не исключено, что заказ может включать более одной транзакции.С практической точки зрения, я думаю, что аудитор с подозрением относится к нескольким заказам, сделанным одним и тем же пользователем одновременно, поэтому предположим, что ключ user_id и payment_time должен быть ключевым.Однако, если transaction_id не является ключом, таблица не будет полностью нормализована.Поэтому я бы дал дизайнеру преимущество сомнения и предположил, что transaction_id также является ключом.

0 голосов
/ 17 июня 2011

«Ключи» могут относиться к одному из:

Возможно, вам потребуется несколько, потому что вам нужно реализовать более одной из этих функций в одной таблице.Это на самом деле довольно часто.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...