Укороченная версия
Мне нужно добавить фиксированное количество дополнительных свойств для каждой пары в существующем соединении «многие ко многим». Переходя к диаграммам ниже, какой из вариантов 1-4 является наилучшим способом с точки зрения преимуществ и недостатков, чтобы достичь этого путем расширения базового варианта? Или есть лучшая альтернатива, которую я здесь не рассматривал?
Более длинная версия
В настоящее время у меня есть две таблицы в отношении многие ко многим через промежуточную таблицу соединений. Теперь мне нужно добавить дополнительные ссылки на свойства, которые принадлежат к паре существующих объектов. У меня есть фиксированное количество этих свойств для каждой пары, хотя одна запись в таблице свойств может применяться к нескольким парам (или даже использоваться несколько раз для одной пары). Я пытаюсь определить лучший способ сделать это, и мне трудно разобраться, как думать о ситуации. С семантической точки зрения кажется, что я могу описать это как любое из следующего с одинаковой точностью:
- Одна пара связана с одним набором фиксированного числа дополнительных свойств
- Одна пара связана со многими дополнительными свойствами
- Многие (два) объекта связаны с одним набором свойств
- Многие объекты связаны со многими свойствами
пример
У меня есть два типа объекта, х и у, каждый с уникальными идентификаторами, и связывающую таблицу objx_objy
с колоннами x_id
и y_id
, которые вместе образуют первичный ключ для ссылки. Каждый X может быть связан со многими Ys, и наоборот. Это установка для моих существующих отношений «многие ко многим».
Базовый вариант
Теперь дополнительно у меня есть набор свойств, определенных в другой таблице, и набор условий, при которых данная пара (X, Y) должна иметь свойство P. Число условий является фиксированным и одинаковым для всех пар. Они в основном говорят: «В ситуации C1 пара (X1, Y1) имеет свойство P1», «В ситуации C2 пара (X1, Y1) имеет свойство P2» и т. Д. Для трех ситуаций / условий для каждой пары в соединении стол.
Опция 1
В моей нынешней ситуации есть ровно три такие условия, и у меня нет никаких оснований ожидать , что для увеличения, поэтому одна возможность заключается в том, чтобы добавить столбцы c1_p_id
, c2_p_id
и c3_p_id
к featx_featy
, указав для данного x_id
и y_id
, что свойство p_id
для использования в каждом из трех случаев ,
Это не кажется мне хорошей идеей, потому что это усложняет SQL для выбора всех свойств, применяемых к объекту, и не может легко масштабироваться для большего количества условий. Тем не менее, он обеспечивает выполнение определенного количества условий для каждой пары (X, Y). Фактически, это единственный вариант, который делает это.
Вариант 2
Создайте таблицу условий cond
и добавьте идентификатор условия в первичный ключ таблицы соединений.
Одним из недостатков этого является то, что он не определяет количество условий для каждой пары. Другое дело, что, когда я рассматриваю только начальные отношения, с чем-то вроде
SELECT objx.*, objy.* FROM objx
INNER JOIN objx_objy ON objx_objy.x_id = objx.id
INNER JOIN objy ON objy.id = objx_objy.y_id
Затем я должен добавить DISTINCT
пункт, чтобы избежать повторяющихся записей. Кажется, это утратило тот факт, что каждая пара должна существовать только один раз.
Вариант 3
Создайте новый «идентификатор пары» в соединительной таблице, а затем добавьте вторую таблицу ссылок между первой и свойствами и условиями.
Кажется, это имеет наименьшее количество недостатков, кроме отсутствия принудительного применения фиксированного количества условий для каждой пары. Имеет ли смысл создавать новый идентификатор, который не идентифицирует ничего, кроме существующих идентификаторов?
Вариант 4 (3б)
В основном так же, как вариант 3, но без создания дополнительного поля идентификатора. Это достигается путем помещения обоих исходных идентификаторов в новую таблицу соединений, чтобы она содержала x_id
и y_id
поля, а не xy_id
.
Дополнительным преимуществом этой формы является то, что она не изменяет существующие таблицы (хотя они еще не работают). Тем не менее, он в основном дублирует всю таблицу несколько раз (или чувствует себя так, во всяком случае), поэтому также не кажется идеальным.
Резюме
Я чувствую, что варианты 3 и 4 достаточно похожи, чтобы я мог пойти с любым из них. Я бы, наверное, уже имел, если бы не требовалось небольшое фиксированное количество ссылок на свойства, что делает Вариант 1 более разумным, чем в противном случае. Основываясь на некотором очень ограниченном тестировании, добавление DISTINCT
предложения в мои запросы, похоже, не влияет на производительность в этой ситуации, но я не уверен, что вариант 2 представляет ситуацию так же, как и другие, из-за собственного дублирования, вызванного размещением одинаковые (X, Y) пары в нескольких строках таблицы ссылок.
Является ли один из этих вариантов моим лучшим способом продвижения вперед, или я должен рассмотреть другую структуру?
DISTINCT
статьи, я думал о запросе , как один в конце # 2, ссылка x
и y
через , xyc
но не относится к c
... Так что, если я (x_id, y_id, c_id)
ограничен UNIQUE
рядам (1,1,1)
и (1,1,2)
, затем SELECT x.id, y.id FROM x JOIN xyc JOIN y
, я вернусь два идентичных строки (1,1)
, и (1,1)
.