Во втором примере, который вы показываете, столбцы xid
, yid
проиндексированы , но ничто не мешает вашему приложению ввести одну и ту же пару xid
, yid
в несколько строк ABC
таблица:
INSERT INTO ABC (xid, yid) VALUES (123, 456), (123, 456); -- NO ERROR
Таким способом вы можете получить непреднамеренные дубликаты, и это может вызвать странные эффекты, когда вы выполняете объединения и подсчитываете. Также, если вам нужно обновить строку, чтобы изменить связь между данным xid
и его yid
, вы можете обновить одну строку, а не другую (и).
Вы должны по крайней мере объявить ключ над (xid, yid)
как UNIQUE KEY
, чтобы избежать дублирования.
В первом показанном вами примере используется составной первичный ключ (некоторые люди говорят, что составной первичный ключ). SQL поддерживает многостолбцовые индексы и многостолбцовые ограничения. В этом нет недостатка, за исключением того, что если вы хотите выполнить запрос, чтобы выбрать одну строку, вам нужно использовать два столбца вместо одного в условии, которое идентифицирует строку.
DELETE FROM ABC WHERE xid = 123 AND yid = 456;
Аналогично, если другая таблица содержит внешний ключ для ссылки на таблицу ABC
, в ней должны быть оба столбца.
Многие программисты считают использование двух столбцов настолько обременительным и вводящим в заблуждение, что они предпочитают добавить суррогатный ключ из одного столбца.
Настаивать на избыточном суррогатном ключе, когда он не нужен, я считаю антипаттерном SQL.
Повторяйте ваш обновленный вопрос выше: знаете ли вы, что составной индекс помогает только тогда, когда ваш поиск включает в себя самые левые столбцы в индексе? Это верно для любого составного индекса в любой марке РСУБД. Пример: * +1032 *
CREATE TABLE myC (
somethingid INT,
userid INT,
PRIMARY KEY (somethingid, userid)
);
SELECT * FROM myC WHERE userid = 12345;
Этот запрос не может использовать индекс первичного ключа.
Классическим примером для объяснения использования составного индекса является аналогия телефонной книги : Если я попрошу вас найти всех, чья фамилия "Томас", вы можете использовать тот факт, что телефонная книга заказана фамилия, чтобы помочь сделать ваш поиск быстрым. Но если я попрошу вас найти всех, чье имя - "Томас", вам придется искать каждую страницу. Телефонная книга похожа на составной указатель (last_name
, first_name
). Поэтому, если ваш поиск не включает last_name
, вы должны прибегнуть к поиску методом перебора.
Вы также можете создать дополнительный индекс только для другого столбца, чтобы вы могли выполнить поиск, используя его в качестве критерия. Вам не нужен дополнительный индекс для одного столбца для первого столбца. Составной индекс является адекватным.
CREATE TABLE myC (
somethingid INT,
userid INT,
PRIMARY KEY (somethingid, userid),
KEY (userid)
);
Обычно, если этот столбец объявлен как внешний ключ, СУБД должна автоматически создать индекс. Однако в некоторых версиях некоторых продуктов СУБД вы должны самостоятельно создать индекс для столбца внешнего ключа как отдельное действие.