Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: struktura bazy danych
Forum PHP.pl > Forum > PHP
Black-Berry
Od kilku wersji swojego oprogramowania męczę problem struktuyry elementów w CMS-sie. Dla przykładu mam takie elementy:

- kategoria
- artykuł
- news

I teraz chcę trzymać się następujących zasad:

- kategorie zawierają n podkategorii
- kazda kategoria zawiera newsy lub(i) artykuły

Jak to ustawić w bazie danych?
- Zmęczyłem kilka opcji i teraz mam taki pomysł żeby trzymać wszystko w 1 tabeli:

====================
id, type, name, parent_id
====================
1 | category | kategoria 1 | 0
2 | category | kategoria 1 | 0
3 | article | artykuł 1 | 0
4 | article | artykuł 2 | 1
5 | news | news 1 | 2

Czyli wszystko w jednej tabeli a drzewko tylko i wyłacznie na podstawie parent_id. Bez żadnego nested sets lub innego wymysłu który komplikuje sprawę tak bardzo że żaden projekt nie może być skończony w rozsądnym czasie. Bardzo proszę o opinie.
AxZx
to napisz jakiś projekt stosując takie rozwiązanie i zobaczysz, że się nie da.parent_id to za mało. musi być jeszcze możliwość ustawiania kolejności.
oprócz tego dużym problemem będzie pobieranie wszystkich 'dzieci'
nexis
Operowanie na różnych danych w strukturze jednej tabeli zdecydowanie nie jest dobrym rozwiązaniem. Dla rekurencyjncych kategorii wystarczy utworzyć tabelę tego typu:

category (id, parent, label)

Dla nadrzędnych kategorii "parent" jest NULL, a dla pozostałych kluczem nadrzędnej. Następnie artykuły mógłbyś przechowywać w kolejnej tabeli, np.:

news (id, categoryid, topic, content)
Black-Berry
@AxZx Kolejność to nie problem bo wystarczy dodać pole `succession` i po sprawie. Co do listy dzieci masz rację. 1-szy poziom pobiera się za to łatwiej. Wystarczy proste zapytanie na podstawie `parent_id`. Wydaje mi sie że problemy związane z pobieraniem wszystkich dzieci nie są aż tak duże jak w przypadku `nested sets`. Drzewo oparte o `left_id`, `right_id` jest tak wrażliwe że trzeba stosować transakcje. Wystarczy jeden zły wpis i cała struktura się wali.

@nexis Dlaczego 1 tabela to takie złe rozwiązanie. Tak naprawdę kategoria i artykuł mają ze sobą wspólne 90% pól. Czasami są nawet zgodne w 100% dlatego tych kilka nieużywanych byłoby poprostu pustych. Korzyści z takiego rozwiązania są wielkie. Zapytania są dziecinnie proste, nie trzeba stosować nigdzie JOIN, ustawianie w kolejności też jest proste. Wyobraź sobie taki przypadek że masz 2 np kategorię samochody a w niej 2 artykuły i 2 subkategorie. Dodatkowo klient życzy sobie żeby na liscie były one w takiej kolejnoisci:

- subkategoria 1
- artykuł 1
- subkategoria 2
- artykuł 2

Teraz gdyby atrykuły i kategorie były w innych tabelach to czeka cię masa pracy żeby kolejność z jednej tabeli była zależna od tej z innej tabeli. Totalna masakra.
mike
Cytat(Black-Berry @ 11.12.2008, 23:34:21 ) *
Bez żadnego nested sets lub innego wymysłu który komplikuje sprawę tak bardzo że żaden projekt nie może być skończony w rozsądnym czasie.
Głupi slogan. Skoro w idiotyczny sposób odrzucasz dobre rozwiązania to co mamy Ci zaproponować?
Masz jakieś poparcie dla tych tez? Bo ja na przykład ukończyłem wiele projektów, w których metoda nested set była wykorzystywana.
To, że czymś nie potrafisz się posługiwać to nie znaczy, że jest to złe.

A jeśli chodzi o powiązanie artykułów i newsów z kategoriami to zrób oddzielne tabele. Newsy i arykuły w jednej tabeli to poroniony pomysł, godzący w podstawowe zasady projektowania baz danych.
Później do połączenia tych obiektów z kategoriami użyj tabel w stylu:
categories_has_articles
category_id | article_id

categories_has_newses
category_id | news_id
Black-Berry
@mike W poscie wyżej napisałem:

"Drzewo oparte o `left_id`, `right_id` jest tak wrażliwe że trzeba stosować transakcje. Wystarczy jeden zły wpis i cała struktura się wali."

Mogę jeszcze dodać ze ogranicza to stosowanie wyszukiwania fulltekstowego i bardzo wydłuża czas dodawania wpisów do bazy. Zapytania SELECT też stają się ciut mniej wydajne. Zrobienie menu rozwijanego na podstawie neted_sets to kompletny koszmar. CO z tego ze mozna to zrobic 1 zapytaniem jesli piszesz odpowienia procedure generujacą 2 dni.

A co z problemem ustawiania w różnej kolejności? Musiałbym kolejność trzymać w osobnej tabeli. Jak bardzo jedna tabela godzi w ideologię baz danych? Bardzo utrudnia pracę ale nie widzę korzyści. Mogłbyś podać jakie daje zalety to o czym piszesz?
mike
Cytat(Black-Berry @ 12.12.2008, 11:13:48 ) *
"Drzewo oparte o `left_id`, `right_id` jest tak wrażliwe że trzeba stosować transakcje. Wystarczy jeden zły wpis i cała struktura się wali."

Mogę jeszcze dodać ze ogranicza to stosowanie wyszukiwania fulltekstowego i bardzo wydłuża czas dodawania wpisów do bazy. Zapytania SELECT też stają się ciut mniej wydajne. Zrobienie menu rozwijanego na podstawie neted_sets to kompletny koszmar. CO z tego ze mozna to zrobic 1 zapytaniem jesli piszesz odpowienia procedure generujacą 2 dni.
To wszystko to sa Twoje subiektywne odczucia na temat nartzędzia, które słabo potrafisz wykorzystać. Zapytań wcale nie pisze się dwa dni a problem insertów to żaden problem. Jak często to robisz i co złego widzisz w transakcjach?
Cytat(Black-Berry @ 12.12.2008, 11:13:48 ) *
A co z problemem ustawiania w różnej kolejności?
A co ma być? Nested set pozwala na ustawianie kolejności elementów.
Black-Berry
Sory ale my sie chyba nie rozumiemy. Nie zapytania pisze się 2 dni ale menu rozwijane. No chyba że podasz mi jakiś genialny algorytm albo link do algorytmu który coś takiego potrafi zrobić ze struktury nested sets w parenaście linijek:

Kod
<menu>
   <li><a>element<a></li>
   <li><a>element<a></li>
   <li><a>element<a>
   <menu>
        <li><a>element<a></li>
        <li><a>[b]element[/b]<a></li>
        <li><a>element<a></li>
        <li><a>element<a></li>
   </menu>
   </li>
   <li><a>element<a></li>
</menu>


Jak to dla Cibie za łatwe to spróbuj tak żeby było zgodne z W3C i renderowane z tabami. Po kliknięciu w element pogrubiony ma się rozwinąć niższy poziom a po ponownym zwinąć. No i oczywiście wszystko bez JS ale na zapytaniach do bazy i funkcji renderującej dokładnie taką strukturę. Idę o zakłąd że 10 razy szybciej zrobię to na 1 tabeli i w kilku zapytaniach niż największy pro na nested sets w 1 zapytaniu.
AxZx
tematów o strukturze drzewa w bazie było już sporo. poczytaj. takie niby proste rozwiązanie nie jest takie rewelacyjne, skoro powstało bardziej skomplikowane rozwiązanie oparte o left_id i right_id. coś w tym musi być:)
ameryki nie odkryjesz.
Black-Berry
AxZx Ja nie chce odkrywać ameryki tylko ułatwić sobie życie a nie robić czegoś temu że tak się przyjęło.
dr_bonzo
Masz kilka metod na drzewka, kazda ma zalety jak i wady, pobadaj wszystkie, okresl czego potrzebujesz i wybierz jedna
- samo parent id - prosciutkie w implementacji, brak sortowania (w podst. wersji), znalezienie przodkow == rekurencja (wiele SQLek), znalezienie potomstwa == rekurencja (wiele SQLek)
- drzewka IP - ograniczona glebokosc i szerokosc, proste w implementacji, latwo stworzyc breadcrumb (1 sql), znalezc dzieci (1 sql), cale potomstwo (1sql), mozna dodac kolumne sortowania (zamiast korzystac z samego ID)
- "drzewka depesza" - gdzies tutaj, http://www.depesz.com/various/various-sqlt...lementation.php , te z poziomem zaglebienia, nie pamietam dokladnie czym sie charakteryzuja, ale rozwiazywaly kilka problemow
- nested sets - sortowanko w standardzie, ale kosztowna edycja drzewka (co to za problem uzyc transakcji? do tego masz gotowe SQLki do operacji na netsted setsach, jak czesto dodajesz rekordy a jak czesto je odczytujesz? + mozesz dodac cache drzewka w postaci html czy innej)


edit: co do menu w NS, hmmm, po dodaniu parent_id bylo by prosciej, a takto musialbym pomyslec jak to ladnie wyciagnac
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.