Krótka wersja
Muszę dodać stałą liczbę dodatkowych właściwości do każdej pary w istniejącym złączeniu wiele do wielu. Przechodząc do poniższych schematów, który z wariantów 1-4 jest najlepszym sposobem, jeśli chodzi o zalety i wady, aby to osiągnąć poprzez rozszerzenie przypadku podstawowego? Czy jest lepsza alternatywa, której tutaj nie rozważałem?
Dłuższa wersja
Obecnie mam dwie tabele w relacji wiele do wielu za pośrednictwem pośredniej tabeli łączenia. Teraz muszę dodać dodatkowe linki do właściwości należących do pary istniejących obiektów. Mam ustaloną liczbę tych właściwości dla każdej pary, chociaż jeden wpis w tabeli właściwości może dotyczyć wielu par (lub nawet może być użyty wiele razy dla jednej pary). Próbuję ustalić najlepszy sposób na zrobienie tego i mam problem z ustaleniem, jak myśleć o sytuacji. Semantycznie wydaje się, że równie dobrze mogę to opisać jako jedno z poniższych:
- Jedna para połączona z jednym zestawem stałej liczby dodatkowych właściwości
- Jedna para powiązana z wieloma dodatkowymi właściwościami
- Wiele (dwóch) obiektów powiązanych z jednym zestawem właściwości
- Wiele obiektów powiązanych z wieloma właściwościami
Przykład
Mam dwa typy obiektów, X i Y, każdy z unikalnymi identyfikatorami, a łączący tabelę objx_objy
z kolumnami x_id
i y_id
, które razem tworzą klucz podstawowy dla łącza. Każdy X może być powiązany z wieloma Y i odwrotnie. To jest konfiguracja dla mojej istniejącej relacji wiele do wielu.
Podstawowa skrzynka
Teraz dodatkowo mam zestaw właściwości zdefiniowanych w innej tabeli oraz zestaw warunków, w których dana para (X, Y) powinna mieć właściwość P. Liczba warunków jest stała i taka sama dla wszystkich par. Mówią w zasadzie: „W sytuacji C1 para (X1, Y1) ma właściwość P1”, „W sytuacji C2 para (X1, Y1) ma właściwość P2” i tak dalej, dla trzech sytuacji / warunków dla każdej pary w złączeniu stół.
opcja 1
W mojej obecnej sytuacji istnieją dokładnie trzy takie warunki, a nie mam żadnego powodu, by oczekiwać, że w celu zwiększenia, więc jedną z możliwości jest dodanie kolumny c1_p_id
, c2_p_id
i c3_p_id
do featx_featy
, określając dla danego x_id
a y_id
, którego właściwość p_id
do stosowania w każdym z trzech przypadków .
Nie wydaje mi się to świetnym pomysłem, ponieważ komplikuje on SQL, aby wybrać wszystkie właściwości zastosowane do funkcji i nie łatwo skaluje się do większej liczby warunków. Wymusza jednak wymóg pewnej liczby warunków na parę (X, Y). W rzeczywistości jest to jedyna opcja, która to robi.
Opcja 2
Utwórz tabelę warunków cond
i dodaj identyfikator warunku do klucza podstawowego tabeli łączenia.
Jednym minusem tego jest to, że nie określa liczby warunków dla każdej pary. Innym jest to, że gdy rozważam tylko początkowy związek z czymś takim jak
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
Następnie muszę dodać DISTINCT
klauzulę, aby uniknąć powielania wpisów. Wydaje się, że stracił to fakt, że każda para powinna istnieć tylko raz.
Opcja 3
Utwórz nowy „identyfikator pary” w tabeli łączenia, a następnie umieść drugą tabelę łączy między pierwszą a właściwościami i warunkami.
Wydaje się, że ma to najmniej wad, oprócz braku wymuszania określonej liczby warunków dla każdej pary. Czy ma sens tworzenie nowego identyfikatora, który identyfikuje jedynie identyfikatory istniejące?
Opcja 4 (3b)
Zasadniczo to samo co opcja 3, ale bez tworzenia dodatkowego pola identyfikatora. Odbywa się to poprzez umieszczenie obu oryginalnych identyfikatorów w nowej tabeli łączenia, aby zawierała x_id
i y_id
pola zamiast xy_id
.
Dodatkową zaletą tego formularza jest to, że nie zmienia on istniejących tabel (choć nie są one jeszcze w produkcji). Jednak zasadniczo powiela całą tabelę wiele razy (lub tak też się wydaje), więc też nie wydaje się idealny.
streszczenie
Mam wrażenie, że opcje 3 i 4 są na tyle podobne, że mógłbym wybrać jedną z nich. Prawdopodobnie miałbym do tej pory, gdyby nie wymóg małej, stałej liczby linków do właściwości, co sprawia, że Opcja 1 wydaje się bardziej rozsądna niż byłaby w innym przypadku. Opierając się na niektórych bardzo ograniczonych testach, dodanie DISTINCT
klauzuli do moich zapytań nie wydaje się wpływać na wydajność w tej sytuacji, ale nie jestem pewien, czy Opcja 2 reprezentuje sytuację, podobnie jak inne, z powodu nieodłącznego duplikowania spowodowanego umieszczeniem te same pary (X, Y) w wielu wierszach tabeli łączy.
Czy jedna z tych opcji jest moim najlepszym rozwiązaniem, czy też jest inna struktura, którą powinienem rozważyć?
DISTINCT
klauzuli, myślałem o zapytaniu jak ten na koniec # 2, który linki x
i y
dzięki xyc
ale nie odnosi się do c
... więc jeśli mam (x_id, y_id, c_id)
ograniczone UNIQUE
z wierszy (1,1,1)
i (1,1,2)
, następnie SELECT x.id, y.id FROM x JOIN xyc JOIN y
, będę wracać dwóch identycznych wiersze (1,1)
i (1,1)
.