Допустим, в какой-нибудь таблице естественным образом возникает возможность использовать составной ключ.
Какие я вижу преимущества использования вместо составного ключа искусственного ключа (auto_increment):
— удобнее адресовать записи в базе (например, передавать через строку в браузере)
— меньше места занимают таблицы, ссылающиеся на эту
Эти достоинства относятся и к достоинствам искусственных ключей по сравнению с, вообще, естественными.
Но в данный момент меня интересуют именно составные ключи — например, состоящие из пары-тройки полей типа int.
Есть ли какие-то недостатки подхода, в котором вторая часть или некоторая кроме первой части составного ключа делается индексом?
Есть ли какие-либо особенности, если используется составной ключ в связывающей таблице
(есть таблицы t1, t2, ..., tn c ключом id, есть таблица r с ключом (t1_id, t2_id, ..., tn_id)).
Здравствуйте, Аноним, Вы писали:
А>Эти достоинства относятся и к достоинствам искусственных ключей по сравнению с, вообще, естественными. А>Но в данный момент меня интересуют именно составные ключи — например, состоящие из пары-тройки полей типа 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>Вот связывающие таблицы это пожалуй единственный случай, где составные ключи возникают "естественным образом".
У меня как раз связывающие таблицы. Я выбрал в пользу составного (естественного).
Но у меня небольшой опыт в проектировании БД, поэтому я подумал — нет ли чего избыточного в том, что (для многих задач) приходится вторую часть ключа делать индексом. Пару, по которой строится составной ключ упорядочил таким образом, что чаще решается задача, в которой будет использоваться выбор по первой часть ключа. Правда там не только пары — иногда тройки даже. Боюсь — потому что если допущу ошибку на этой стадии то потом трудно будет её исправить.
Ещё естественный ключ может быстро таким перестать — вдруг к связи добавится ещё какой-нибудь атрибут, например "сила связи". Тогда прийдётся включать это поле в ключ. Хотя это вряд ли доставит проблем.
А>Ещё естественный ключ может быстро таким перестать — вдруг к связи добавится ещё какой-нибудь атрибут, например "сила связи". Тогда прийдётся включать это поле в ключ. Хотя это вряд ли доставит проблем.
В этом случае как раз не придется. "Сила связи" скорее всего не будет включаться в ключ.
А от изменений вообще никто не застрахован — твоя связь двух сущностей может превратиться в связь трех сущностей.
Считаю, что логика тут должна быть примерно такая.
Если таблица хранит нечто, напоминающее объект — то должен буть суррогатный ключ.
Если таблица хранит нечто, больше напоминающее значение — то естественный ключ.
Вот связующие таблицы — хранят, по сути значения. Это разного рода регистры (типа 1С-ных), связи многие-ко-многим, какие-нибудь цены товаров по городам и по категориям покупателей (связь трех сущностей) — очень хорошо идентифицируются именно естественным композитным ключом. Суррогатный ключ тут — лишняя трата дискового пространства, более того, возможный источник проблем.
Но как только то, что мы храним в таблице, приобретает некоторый особый смысл объекта, например, на него начинает ссылаться кто-то, у него появляются разновидности-потомки, вылазят какие-то альтернативные ключи меньшего размера — становится удобнее работать с этим, именно как с объектом, и вводить суррогатный ключ.
Пример. Пусть у нас есть сущности торговое предприятие (ТП) и торговый центр (ТЦ). Сначала мы говорим, что в ТЦ представлены различные ТП, и одно ТП может быть представлено в нескольких ТЦ.
На этом уровне абстракции и постановки задачи нам нужна самая обычная развязочная таблица с двумя полями — ТЦ_ID и ТП_ID.
На следующей итерации мы узнаем, что модель детализировалась — ТП представлено в ТЦ торговыми точками (ТТ). И эта развязка ТЦ-ТП производится именно торговой точкой, которая имеет свой адрес, телефон, другие характеристики, на которую ссылается сущность "покупка". Обнаруживаем, что и старый ключ (ТЦ, ТП) перестал быть ключом — в одном ТЦ может быть несколько ТТ одного ТП. И тогда смело переделываем таблицу-развязку в полноценный справочник ТТ со своим суррогатным ключом.
Можно ли говорить о том, что первоначальная схема была неверной или не расчитанной на будущие изменения. Никак нет. Просто изменилась модель.
Можно рассматривать такое изменение как рефакторинг структуры данных, если от этого кому-то станет легче
P.S. Если же причина маниакального создания суррогатных ключей в любых таблицах лежит в том, что ваш любимый ORM не умеет работать иначе — остается только посочуствовать и посоветовать подбирать инструмент под задачу, а не наоборот.
P.P.S. Еще один повод создания суррогатных ключей везде — это различного рода механизмы репликации, журналирования изменений и т. п. Тут хочется отметить, что это операции принципиально более низкого уровня — не уровня модели, а уровня хранения и обработки записей БД. Если вы решили использовать такой механизм — сделайте для него уникальный ключ a la ROW_ID, но не ищите в нем смысла идентификатора сущности модели. Пусть остается идентификатором записи.
Здравствуйте, Аноним, Вы писали:
А>Допустим, в какой-нибудь таблице естественным образом возникает возможность использовать составной ключ. Суррогатные или естественные
Здравствуйте, wildwind, Вы писали:
W>Здравствуйте, Аноним, Вы писали:
А>>Эти достоинства относятся и к достоинствам искусственных ключей по сравнению с, вообще, естественными. А>>Но в данный момент меня интересуют именно составные ключи — например, состоящие из пары-тройки полей типа int.
W>Из этого следует, что между естественными и искуственными ключами ты выбрал в пользу естественных, верно? Потому что искуственные составными не делают.
Это кто тебе такое сказал?
Составные первичные ключи могут иметь очень большие преимущества перед тривиальным одноколоночным индексом. У нас юзается (ID,CLASS), обеспечивающий уникальную идентификацию данных в рамках базы данных.
W>Предлагаю тотализатор — после какого поста тема перейдет в чистый флейм. Делайте ставки, господа! W>(Моя ставка — 5-6)
"Всех убъю, один останусь"
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, Аноним, Вы писали:
А>Но в данный момент меня интересуют именно составные ключи — например, состоящие из пары-тройки полей типа int.
Преимущество подобных составных ключей — имхо — заключается в основном в двух деталях:
1) В некоторых случаях они удобнее для поддержки целостности. Простой пример: допустим, есть сущности "Таблицы", "Поля таблиц", "Отчеты (над таблицами)", "Поля в отчетах". Задача: поля в отчет могут выбираться только из той таблицы, над которой строится отчет. С составными ключами это ограничение естественным образом описывается foreign key-ями; без них придется писать код.
2) По сути это некий вид денормализации, и как любая денормализация, составной ключ в таблице может привести к уменьшению количества таблиц в запросе, как следствие облегчить написание запросов.
Соответственно, там, где эти преимущества оказываются важными, применение составных ключей оправданно.
Лично я обычно использую составные ключи в развязках, на которые никто не ссылается. В таблицах, на которые ссылаются — думаю над каждым случаем отдельно, но чаще использую собственный id.