Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wspólna tablica łącząca
Forum PHP.pl > Forum > Bazy danych
orson
Witam ...

eksperymentując i rozmyślając nad założeniami bazy wpadłem na pewien pomysł ... elementy łączy się ze sobą przy pomocy tablic które zawierają relacje 1:1, n:m i 1:n ... takie coś jest wygodne, w miarę wydajne i nie powoduje dublowania się danych (wszystko w teorii oczywiście :roll2: )

a gdyby tak połączyć tabele łączące w jedną ... już wyjaśniam o co chodzi ...

mamy kilka standardowych tabel: users, groups, content, params ... oraz jedną tabelę o nazwie con ... składa się ona z kolumny: type, relation, id1, id2 oraz priority ... i teraz przy pomocy różnych kombinacji type oraz relation łączymy ze sobą elementy id1 i id2 ... np: (po kolei: type, relation, id1, id2 - priority jest narazie nie ważne)
doc author 1 2 - dokument o id = 1 którego auterm jest user o id = 2
doc author 1 5 - dokument o id = 1 którego auterm jest user o id = 5
doc related_doc 1 3 - dokument o id = 1 który jest powiązany z dokumentem o id = 3
doc attachment 1 88 - plik o id = 88 jest załącznikiem do dokumentu o id = 1
doc related_news 1 66 - news 66 związany z dokumentem o id = 1
doc cat 1 4 - dokument 1 w kategorii 4
doc cat 1 9 - dokument 1 w kategorii 9

w ten sposób można pobierać dane na temat elementów przy pomocy jednego zapytania ... wszystkie informacje o dokumencie są dostępne odrazu ... potem stosując proste zapytania (brak joinów za każdym razem z tabelą pośrednią ... ) również bardziej skąplikowane elementy (np. ten użytkownik napisał też: i dokumenty napisane przez usera - wszystkie tytuły pobrane jednym zapytaniem, bo id przecież mamy), wszystkie komentarze do dokumentu itp ...

co do priority: jego zastosowanie jest oczywiste i chyba nie wymaga wyjasnień ...

i teraz pytanie co o tym sądzicie - celowo nie podaje żadnych create table bo taka koncepcja może zostać wykorzystana w każdym silniku danych.

pozdrawiam
Aztech
Wydaje mi się, że ta tabela mnożyłaby byty, mnóstwo type oraz relation powodują wystepowanie sporej ilości kombinacji.
A tak na marginesie, czemu miałoby to służyć? Uproszczeniu składni zapytań czy optymalizacji czasu wykonania zapytań?
orson
witam ...

i temu i temu ... wiadomo przecież że jak w zapytaniu nie ma joinów to wykonuje się ono szybciej ... do tego jeszcze wybór po znanych id (które mają klucze)

co do mnożenia bytów ... to przecież dokument ma autora, kilka dokumentów powiązanych, jeden-dwa załączniki, znajduje się w jednej-dwóch kategoriach i tyle ... to przecież odpowiada rekordom z tabel con_UserDoc, con_DocCat, con_DocDoc itp ... bardzo upraszcza to projekt bazy ...
ze wstępnych pomiarów na zbliżonych systemach (prosty cms z łączeniami w osobnych tablicach vs. ten sam cms przerobiony na jedną wspólną + zapytania o konkretne elementy) przyrost wydajności jest od 10 do 40% Rkingsmiley.png w zależności od wyświetlonej strony (nie liczyłem poszczególnych zapytań) ...
pomiar ab 1000 zapytań ...

pozdrawiam
splatch
Hm.. a jak to się ma do teorii normalizacji bazy danych? Z tego co mi wiadomo używanie tabel pośredniczących przy relacjach m:n jest czymś normalnym.
Jeśli nie chce bawić się z joinami, ponieważ jest ich dużo (np. łącze parametr-wartości-użytkownik) to tworzę widok.. Wtedy również mam tylko jedno zapytanie. smile.gif
U Ciebie w dalszym ciągu są 3 tabelki: news - relacje - dokumenty.Jedyne uproszczenie jakie jest to to, że nie masz większej ilości tabel pośredniczących. Co do joinów - w mysql konstrukcja ta jest na tyle szybka, że nie widzę potrzeby jej "zastępowania".
Co do przyśpieszenia - wątpię by było ono wieczne, wraz ze zwiększaniem objętości tabeli wydajność będzie spadać.
Teraz zasadnicze pytanie - co jakiś system obsłuży szybciej? Jedną otyłą tabelę czy trzy lekkie tabelki?
dr_bonzo
Kolejnym ograniczeniem jest to ze klucze musza byc identycznym typem dla kazdej tabeli.



Przyklad zapytania: znajdz mi autorow dokumentu o ID = 1
* JOINY
  1. SELECT autors.name, autors.id
  2. FROM autors
  3. LEFT JOIN documents_authors ON documents_authors.author_id = authors.id WHERE documents_authors.document_id = 1


* twoim rozwiazaniem
  1. SELECT id2
  2. FROM relacje
  3. WHERE type = 'doc' AND relation = 'author' AND id1 = 1

dostane ID autorow, zeby pobrac ich dane musze wykonac JOINA lub kolejne zapytania
(moze cos przeoczylem, zle zrozumialem?)
orson
witam ...

wykonujesz kolejne zapytanie do tablicy z userami ... przy kilku tysiącach userów i kilkuset dokumentach różnica w wydajności jest widoczna ...

pozdrawiam
splatch
Co z kluczami obcymi? Dzięki nim możesz w bardzo wygodny sposób zachowywać spójność danych. Stosując Twoje rozwiązanie mogę dodać dokument, który nie istnieje, przypisać użytkownika do grupy która nie istnieje i tak dalej. Dzięki kluczom obcym mogę obsłużyć takie przypadki, ponieważ creole wywali mi wyjątek z odpowiednią informacją - "Foreign key constraint fails".
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.