Коротка версія
Я маю додати фіксовану кількість додаткових властивостей до кожної пари в існуючому об'єднанні багато-до-багатьох. Переходячи до діаграм нижче, який із варіантів 1-4 є найкращим способом, з точки зору переваг та недоліків, досягти цього шляхом розширення базової справи? Або є краща альтернатива, яку я тут не розглядав?
Більш довга версія
В даний час у мене є дві таблиці у відносинах "багато до багатьох" через проміжну таблицю приєднання. Тепер мені потрібно додати додаткові посилання на властивості, які належать до пари існуючих об'єктів. Я маю фіксовану кількість цих властивостей для кожної пари, хоча один запис у таблиці властивостей може застосовуватися до декількох пар (або навіть використовуватись кілька разів для однієї пари). Я намагаюся визначити найкращий спосіб зробити це, і у мене виникають проблеми з розбиранням, як думати про ситуацію. Семантично здається, ніби я однаково добре можу описати його як будь-яке з наступних:
- Одна пара пов'язана з одним набором фіксованої кількості додаткових властивостей
- Одна пара пов'язана з багатьма додатковими властивостями
- Багато (два) об'єкти, пов'язані з одним набором властивостей
- Багато об’єктів пов'язані з багатьма властивостями
Приклад
У мене є два типи об'єктів, X і Y, кожен з унікальними ідентифікаторами, і таблиця зв’язку 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 (3b)
В основному те саме, що варіант 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)
.