Составные ключи - плохо или хорошо?
От: Аноним  
Дата: 21.02.06 16:55
Оценка:
Допустим, в какой-нибудь таблице естественным образом возникает возможность использовать составной ключ.

Какие я вижу преимущества использования вместо составного ключа искусственного ключа (auto_increment):
— удобнее адресовать записи в базе (например, передавать через строку в браузере)
— меньше места занимают таблицы, ссылающиеся на эту

Эти достоинства относятся и к достоинствам искусственных ключей по сравнению с, вообще, естественными.
Но в данный момент меня интересуют именно составные ключи — например, состоящие из пары-тройки полей типа int.

Есть ли какие-то недостатки подхода, в котором вторая часть или некоторая кроме первой части составного ключа делается индексом?
Есть ли какие-либо особенности, если используется составной ключ в связывающей таблице
(есть таблицы t1, t2, ..., tn c ключом id, есть таблица r с ключом (t1_id, t2_id, ..., tn_id)).
Re: Составные ключи - плохо или хорошо?
От: wildwind Россия  
Дата: 21.02.06 17:33
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Эти достоинства относятся и к достоинствам искусственных ключей по сравнению с, вообще, естественными.

А>Но в данный момент меня интересуют именно составные ключи — например, состоящие из пары-тройки полей типа int.

Из этого следует, что между естественными и искуственными ключами ты выбрал в пользу естественных, верно? Потому что искуственные составными не делают.

А>Есть ли какие-либо особенности, если используется составной ключ в связывающей таблице

А>(есть таблицы t1, t2, ..., tn c ключом id, есть таблица r с ключом (t1_id, t2_id, ..., tn_id)).

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



Предлагаю тотализатор — после какого поста тема перейдет в чистый флейм. Делайте ставки, господа!
(Моя ставка — 5-6)
Re[2]: Составные ключи - плохо или хорошо?
От: Аноним  
Дата: 21.02.06 17:55
Оценка:
Здравствуйте, wildwind, Вы писали:

W>Здравствуйте, Аноним, Вы писали:


А>>Эти достоинства относятся и к достоинствам искусственных ключей по сравнению с, вообще, естественными.

А>>Но в данный момент меня интересуют именно составные ключи — например, состоящие из пары-тройки полей типа int.

W>Из этого следует, что между естественными и искуственными ключами ты выбрал в пользу естественных, верно? Потому что искуственные составными не делают.


А>>Есть ли какие-либо особенности, если используется составной ключ в связывающей таблице

А>>(есть таблицы t1, t2, ..., tn c ключом id, есть таблица r с ключом (t1_id, t2_id, ..., tn_id)).

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


У меня как раз связывающие таблицы. Я выбрал в пользу составного (естественного).
Но у меня небольшой опыт в проектировании БД, поэтому я подумал — нет ли чего избыточного в том, что (для многих задач) приходится вторую часть ключа делать индексом. Пару, по которой строится составной ключ упорядочил таким образом, что чаще решается задача, в которой будет использоваться выбор по первой часть ключа. Правда там не только пары — иногда тройки даже. Боюсь — потому что если допущу ошибку на этой стадии то потом трудно будет её исправить.

Ещё естественный ключ может быстро таким перестать — вдруг к связи добавится ещё какой-нибудь атрибут, например "сила связи". Тогда прийдётся включать это поле в ключ. Хотя это вряд ли доставит проблем.
Re[3]: Составные ключи - плохо или хорошо?
От: Igor Trofimov  
Дата: 21.02.06 19:24
Оценка: 70 (3) +1
А>Ещё естественный ключ может быстро таким перестать — вдруг к связи добавится ещё какой-нибудь атрибут, например "сила связи". Тогда прийдётся включать это поле в ключ. Хотя это вряд ли доставит проблем.

В этом случае как раз не придется. "Сила связи" скорее всего не будет включаться в ключ.
А от изменений вообще никто не застрахован — твоя связь двух сущностей может превратиться в связь трех сущностей.

Считаю, что логика тут должна быть примерно такая.

Если таблица хранит нечто, напоминающее объект — то должен буть суррогатный ключ.

Если таблица хранит нечто, больше напоминающее значение — то естественный ключ.
Вот связующие таблицы — хранят, по сути значения. Это разного рода регистры (типа 1С-ных), связи многие-ко-многим, какие-нибудь цены товаров по городам и по категориям покупателей (связь трех сущностей) — очень хорошо идентифицируются именно естественным композитным ключом. Суррогатный ключ тут — лишняя трата дискового пространства, более того, возможный источник проблем.

Но как только то, что мы храним в таблице, приобретает некоторый особый смысл объекта, например, на него начинает ссылаться кто-то, у него появляются разновидности-потомки, вылазят какие-то альтернативные ключи меньшего размера — становится удобнее работать с этим, именно как с объектом, и вводить суррогатный ключ.

Пример. Пусть у нас есть сущности торговое предприятие (ТП) и торговый центр (ТЦ). Сначала мы говорим, что в ТЦ представлены различные ТП, и одно ТП может быть представлено в нескольких ТЦ.

На этом уровне абстракции и постановки задачи нам нужна самая обычная развязочная таблица с двумя полями — ТЦ_ID и ТП_ID.

На следующей итерации мы узнаем, что модель детализировалась — ТП представлено в ТЦ торговыми точками (ТТ). И эта развязка ТЦ-ТП производится именно торговой точкой, которая имеет свой адрес, телефон, другие характеристики, на которую ссылается сущность "покупка". Обнаруживаем, что и старый ключ (ТЦ, ТП) перестал быть ключом — в одном ТЦ может быть несколько ТТ одного ТП. И тогда смело переделываем таблицу-развязку в полноценный справочник ТТ со своим суррогатным ключом.

Можно ли говорить о том, что первоначальная схема была неверной или не расчитанной на будущие изменения. Никак нет. Просто изменилась модель.

Можно рассматривать такое изменение как рефакторинг структуры данных, если от этого кому-то станет легче

P.S. Если же причина маниакального создания суррогатных ключей в любых таблицах лежит в том, что ваш любимый ORM не умеет работать иначе — остается только посочуствовать и посоветовать подбирать инструмент под задачу, а не наоборот.

P.P.S. Еще один повод создания суррогатных ключей везде — это различного рода механизмы репликации, журналирования изменений и т. п. Тут хочется отметить, что это операции принципиально более низкого уровня — не уровня модели, а уровня хранения и обработки записей БД. Если вы решили использовать такой механизм — сделайте для него уникальный ключ a la ROW_ID, но не ищите в нем смысла идентификатора сущности модели. Пусть остается идентификатором записи.
Re: Составные ключи - плохо или хорошо?
От: pkarklin  
Дата: 22.02.06 06:29
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Допустим, в какой-нибудь таблице естественным образом возникает возможность использовать составной ключ.

Суррогатные или естественные
Re[2]: Составные ключи - плохо или хорошо?
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 22.02.06 06:46
Оценка:
Здравствуйте, wildwind, Вы писали:

W>Здравствуйте, Аноним, Вы писали:


А>>Эти достоинства относятся и к достоинствам искусственных ключей по сравнению с, вообще, естественными.

А>>Но в данный момент меня интересуют именно составные ключи — например, состоящие из пары-тройки полей типа int.

W>Из этого следует, что между естественными и искуственными ключами ты выбрал в пользу естественных, верно? Потому что искуственные составными не делают.


Это кто тебе такое сказал?

Составные первичные ключи могут иметь очень большие преимущества перед тривиальным одноколоночным индексом. У нас юзается (ID,CLASS), обеспечивающий уникальную идентификацию данных в рамках базы данных.



W>Предлагаю тотализатор — после какого поста тема перейдет в чистый флейм. Делайте ставки, господа!
W>(Моя ставка — 5-6)

"Всех убъю, один останусь"
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re: Составные ключи - плохо или хорошо?
От: Softwarer http://softwarer.ru
Дата: 22.02.06 13:19
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Но в данный момент меня интересуют именно составные ключи — например, состоящие из пары-тройки полей типа int.


Преимущество подобных составных ключей — имхо — заключается в основном в двух деталях:

1) В некоторых случаях они удобнее для поддержки целостности. Простой пример: допустим, есть сущности "Таблицы", "Поля таблиц", "Отчеты (над таблицами)", "Поля в отчетах". Задача: поля в отчет могут выбираться только из той таблицы, над которой строится отчет. С составными ключами это ограничение естественным образом описывается foreign key-ями; без них придется писать код.

2) По сути это некий вид денормализации, и как любая денормализация, составной ключ в таблице может привести к уменьшению количества таблиц в запросе, как следствие облегчить написание запросов.

Соответственно, там, где эти преимущества оказываются важными, применение составных ключей оправданно.

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