Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: projekt nietypowej bazy danych
Forum PHP.pl > Forum > Bazy danych
nowy_pehapowiec
Mam zrobić bazę danych do małego sklepu internetowego. Ale wymagania są dość nietypowe:

A) Produkty mają być umieszczone w drzewie kategorii, z którego będzie robione menu - proste.

cool.gif System tagów i wyszukiwarka po tagach - proste.

C) Produkty mają być umieszczone w drzewie2 producentów i ich kategorii, z którego będzie robione kolejne menu. Czyli jeśli producent X ma u siebie jakieś produkty w jakiś kategoriach to cały ten schemat ma być odwzorowany w tym moim drzewie2. Czyli poziom 0 to nazwy producentów, poziom 1 to najbardziej ogólne kategorie u danego producenta i tak dalej. Mi się to nie podoba ale ponoć ma to ułatwiać szukanie produktów jeśli wcześniej szukało się ich na stronie jakiegoś producenta. I z tym mam problem. Zrobiłem drugie drzewo i dodawany do bazy produkty trzeba umieścić i w pierwszym drzewie (kategorii) i w drugim (producentów). I jakoś to działa ale pojawił się problem ze ścieżką nawigacyjną (taką w stylu "tu jesteś"). Przy jednym drzewie sprawdzałem id wyświetlanego produktu albo grupy produktów i sprawdzałem w bazie co jest nadrzędne (kilka razy) i dostawałem ścieżkę. Ale teraz jest niejednoznaczność. Jeden produkt występuje w 2 drzewach i w zależności od tego czy został wybrany poprzez nawigowanie po drzewie 1 czy drzewie 2 powianiem wyświetlać różne ścieżki. Ale mam tylko id i nie wiem w które menu kliknął user, żeby otworzyć stronę produktu z tym konkretnym id.

D) Do tego ma dojść jeszcze trzecie drzewo co już zupełnie miesza.

E) Jeszcze odnośnie tagów, chciałbym, żeby po wybraniu wyświetlenia produktów z jakimś tagiem, te produkty wyświetlały się nie jako lista ale właśnie jako jedno z drzew. I tu problem taki, że dodanie do select prostego warunku where nie zadziała po kategorie nie mają dodawanych tagów.

F) Inne sposoby szukania produktów. Co poza pełno tekstowym wyszukiwaniem produktów można dodać? Na razie dodałem wybór tagów z listy.

G) Jeśli pozwolę na dopisywanie tagów przez każdego usera (jedno polowy formularz) to pewnie roboty będą dopisywać śmieci. Jak poza captcha można się zabezpieczyć przed tym.


Może ktoś łaskawie pomógłby mi się uporać z projektem takiej bazy? Byłoby fajowo. Każda dobra rada na wagę złota.

pozdro
jmail
lol?

o tego przecież jest nazwa RELACYJNA baza danych

dodaj do produktu id_producenta i id_kategorii oraz id_kategorii u producenta i przekazuj przez GET parametrami - jak będzie id_producenta i jego kategoria to wiesz jak wyświetlić?
nowy_pehapowiec
No ale to bez sensu. Zastanów się. Każdy produkt może wystąpić w każdym drzewie kategorii dowolną ilość razy. Czyli u producenta może pojawić się w kilku miejscach i w drugim drzewie też. Czyli nie mogę mieć w jednej tabeli id produktu i id kategorii1 i jeszcze id kategorii2.

Jakieś inne pomysły?


pozdro
jmail
to trzeba utworzyć osobne tabele na dowiązania producentów i na kategorie

robisz tabelę produkty_producenci

id_produktu
id_producenta

i drugą tabelę produkty_kategorie

id_produktu
id_kategorii
Riklaunim
Cytat(nowy_pehapowiec @ 6.10.2009, 14:01:29 ) *
No ale to bez sensu. Zastanów się. Każdy produkt może wystąpić w każdym drzewie kategorii dowolną ilość razy. Czyli u producenta może pojawić się w kilku miejscach i w drugim drzewie też. Czyli nie mogę mieć w jednej tabeli id produktu i id kategorii1 i jeszcze id kategorii2.

Jakieś inne pomysły?


pozdro


Potrzebujesz relacji wiele do wielu, którą powyżej opisał jmail. Jeżeli projektujesz strukturę bazy danych to warto najpierw zapoznać się z powszechnie stosowanymi relacjami między tabelami smile.gif
nowy_pehapowiec
Chwilunia, ja wime co to są relacje w bazach danych. Ale chyba coś źle napisałem. Nie ma problemu w zrobieniu tabeli products, tabeli category1, tabeli products_to_category1. Podobnie mogę zrobić tabelęcategory2, tabelę products_to_category2. Żaden problem. Ale tak jak pisałem, mam już kilka takich drzew-struktur. Jeszcze raz podkreśle chodzi o struktury z głębokością a nie płaskie połączenie produktu z tagami. Problem jest w tworzeniu ścieżki "tu jesteś". Produkt w całym systemie strony jest identyfikowany po identyfikatorze id. Odnośniki do produktów mają tylko wartość id. Przy jednej strukturze products_to_category wybierałbym po prostu rodzica a potem rodzica rodzica i w ten sposób powstawałaby taka ścieżka. Ale tutaj id nie niesie informacji o numerze struktury. Czyli miejsce produktu jest zapisane w strukturze ale struktur jest dwie a za tydzień będą 3. Czy macie jakiś pomysł na uniknięcie takiej niejednoznaczności?

A co moglibyście mi powiedzieć o tych moich pytaniach E, F G szczególnie E i G

pozdro
jmail
G - SMS płatny :F

E - całkowicie nie rozumiem

F - wyszukiwanie po producencie, po parametrach itp

Co do Twojego problemu z lokalizowaniem.

- Założmy, że przechodzisz w drzewku na kategorię o id 1 przekaż sobie jako zmienną GET kategorię w postaci kat = 1
- Załóżmy, że przechodzisz w drzewku na kategorię PRODUCENTA o id 2 przekaż sobie jako zmienną GET kategorię w postaci katPr = 2
- Założmy, że przechodzisz w drzewku na producenta o id 3 przekaż sobie jako zmienną GET kategorię w postaci prod = 3

Dzięki temu zachowujesz wszystko całą ścieżkę dostępu.

Wybranie producenta - URL będzie ?prod=1
Wybranie kategorii producenta - URL będzie ?prod=1;katPr=1

Dzięki takiem rozdzieleniu będziesz wiedział gdzie w danym momencie jesteś.

Tylko dobrze rozplanuj zmienne GET i co one oznaczają - nie zgubisz się
nowy_pehapowiec
G - sms płatny raczej odpada biggrin.gif Ale jakaś weryfikacja być musi. A nie chcę z tego rezygnować, bo fajnie jeśli userzy mogą dodawać tagi. Oczywiście trzeba byłoby je później przeglądać i wywalać te najbardziej 'śmieszne'. Ale jeśli nie będzie żadnej weryfikacji to roboty będą wpisywać masę śmieci - muszę jakoś tego uniknąć.

E - Poniżej przykładowy fragment struktury:
cat1-subcat3-subsubcat12-product75
i problem w tym, że product ma przypisany tag ale kategorie już nie mają tagów. W tabeli products są i kategorie i produkty, niczym się różnią poza tym, że pierwsze mają potomków a drugie nie. Mogę oczywiście pobrać z tabeli products wszystkie te produkty które mają (w innej tabeli) zapisany jakiś tag. Ale wtedy dostaje płaską listę a nie drzewo. A właśnie drzewo chciałbym. Dlatego pisałem, że nie mogę pobierać wprost drzewa z elementami posiadającymi jakiś tag bo tagi mają tylko produkty. Jedyne co mi przychodzi do głowy to rekurencyjne dodawanie tagów od produktu w górę. Czyli dodaje tag 'super' do product75 i potem od razu rekurencyjnie jest on dopisywany do wszystkich przodków ( cat1, subcat3, subsubcat12 ). Ale może można jakoś inaczej?

Wiesz z tą lokalizacją to myślałem, że można sobie poradzić może przez sesje i wokół tego krążyłem. Ale jak są dwa takie linki do tego samego produktu, tyle, że z różnego menu, to się nie da. Rozwiązanie ze zmiennymi get mam teraz prostsze. Przekazuje nazwę tabeli ze struktura i id produktu index.php?str=tree2&id=98 Wtedy przodków do ścieżki mam z tabeli tree2 a produkt o id=98 z tabeli products. Jedynie jeśli product występuje kilka razy w jednym drzewie to się sypie. Ale tutaj chyba adres IPadress byłby lepszy? index.php?str=tree2&ipadress=1.9.23.56.236

Co o tym myślisz?

pozdro
jmail
tak tak. moze jeszcze użytkownika i hasło do bazy przekaż zmiennymi GET winksmiley.jpg

prosta droga do włamu <:F>

sesja jest fajna, ale i tak kliknięcie musisz do sesji postem albo getem przekazać. Co do Twojej struktury to jeszcze pomyślę
nowy_pehapowiec
Sam widzisz, że baza jest zakręcona. Moim zdaniem niepotrzebnie bo starczyłoby jedno drzewo i rozbudowany system tagów, ale to nie ode mnie zależy.

Nie wiem o jakim włamie mówisz, nie jarze o co chodzi. Jeśli mówisz o przekazywaniu getem zmiennej tree, to raczej jestem spokojny. Bo strona ma dostęp do bazy tylko do odczytu. Cała administracja jest na tym samym serwerze ale na innym ip, no i jest jeszcze hasło do bazy. A poza tym jeśli ktoś się włamie do bazy do nazwy tabel sobie już sam odczyta biggrin.gif

I nie wiem jak inaczej to zrobić, przekazanie kategorii w której jest produkt niewiele daje. bo nie wiadomo z którego drzewa jest ta kategoria. A w różnych drzewach mogą być te same kategorie, nawet jednym mogą być (n do n).

No i jeszcze te tagi, jak przed spamem się uchronić i czy muszę dopisywać tagi do kategorii, inaczej nie wiem jak wyświetlać produkty w drzewie mające okreslony tag. Gdyby to miałabyć lista to byłoby prosto ale tu ma być drzewo z poziomami.

Jeśli masz albo ktoś inny ma jakiś pomysł jak to dobrze zaprojektować to śmiało piszcie, bardzo na was licze.

pozdro


Żadnych pomysłów? Nawet najmniejszych?

questionmark.gif?
VegetaSSJ
Nie rozumiem po co tworzysz 2 drzewa. Dla mnie do zrealizowania tego starczy jedno drzewo kategorii, reszta to kwestia obróbki danych.
Tworzysz drzewo kategorii, przypisujesz do nich produkty.
Tworzysz liste producentów, przypisujesz do nich produkty.

Aby utworzyć drzewo kategorii dla danego producenta: pobierasz id produktów dla danego producenta. Na podstawie id produktów pobierasz liste kategorii, na podstawie listy kategorii tworzysz strukturę drzewiastą kategorii. Analogicznie dla tagów.

Pracuję na codzień przy sklepach.
jmail
vegeta - kategorie w sklepie != kategorie producentów.....

czytamy ze zrozumieniem
nowy_pehapowiec
No niestety drzewa są różne, dzisiaj już 3. Również nie każdy produkt występuje we wszystkich drzewach. Cholerenie cięzko się z tym pracuje. Sam insert do bazy to poza meta danymi to również wybranie 3 rodziców. W adresie produktu przekazuje adres ip produktu i nazwę tabeli z drzewem. Jakoś działa.

Jest jeszcze jeden problem do rozwiązania. Chodzi o jakiś prosty warunek typu WHERE przy wyszukiwaniu produktów. Produkty po takim wyszukiwaniu mają wyświetlać się w drzewie kategorii. Ale jeśli produktowi przypisze jakiś tag, a nie przypisze go do jego rodzica to zarówno rodzic jak i jego wszyscy potomkowie nie zostaną wyświetleni, mimo, że powinni. Jak to rozwiązać? Przy pobieraniu drzewa sprawdzać rekurencyjnie kolejne poziomy potomków czy któryś nie spełnia odpowiedniego warunku i wtedy wyświetlać jego przodków? Zupełnie nie wiem jak to dobrze zrobić sad.gif

pozdro

jmail
  1.  
  2. WHERE
  3. produkt_tag = tag OR rodzic_tag = tag OR rodzic_rodzic_tag = tag i tak dalej
  4.  
vokiel
G). Pozwól na dopisywanie tylko zarejestrowanym, poza tym zrób np limit wpisów.

F). Po czym możesz wyszukiwać? Po producencie, nazwie produktu, tagach, opisie, cenie, parametrach. Poza opisami pełnotekstowe wyszukiwanie nie będzie nigdzie potrzebne

E). Wyszukując produkt po tagu, dla każdego odnalezionego musisz pobrać resztę ścieżki w górę, potem wyniki pogrupować od góry, od kategorii najszerszego znaczenia, do tej najzwięźlejszej.

D). Po co tyle tych drzew?

C-A). Aby dać sobie możliwość wyświetlenia breadcrumbs'ów musisz jakoś poinformować skrypt z której ścieżki (drzewa) ma korzystać. Bo w takim, że tak to ujmę mętliku sam się nie połapie. Jeśli produkt może podlegać pod ścieżkę producenta->kategorii->subkategorii, lub producenta->tagu, etc, to musisz jakoś przekazać do skryptu gdzie ma tego szukać. Albo możesz co najwyżej pobrać pierwszą pasującą opcję.

Czy nie możesz ograniczyć tego do drzewa kategorii a producenta umieścić jako jeden z atrybutów (właściwości) produktu?
Przynależność do kategorii może być różna, bo monitor lcd 22" może należeć do głównej kategorii monitory, subkategorii lcs, lub subkategorii 22", anyway producenta ma jednego.

Jak ja to widzę, właśnie jedno drzewo. Nie stracisz na funkcjonalności, bo nadal będziesz mógł utworzyć drzewko menu według producenta, po prostu stworzysz drzewko po drzewku dla każdego producenta. Tak samo z resztą funkcjonalności, które przedstawiłeś.

Poza tym jest w bazach danych pojęcie redundancji danych. No i robiąc kilka drzewek ze względu na najbardziej ogólny podział łamiesz tą zasadę. Każdy produkt występuje tyle razy ile masz drzewek, pomimo, że jest to ten sam produkt. (chyba, że źle zrozumiałem Twój opis - popraw mnie jeśli się pomyliłem).

W przypadku bazy opartej o drzewie większość działań będzie polegała na chodzeniu po drzewie w tą i z powrotem, niestety nie unikniesz tego.
nowy_pehapowiec
Cytat(jmail @ 19.10.2009, 14:14:56 ) *
  1. WHERE
  2. produkt_tag = tag OR rodzic_tag = tag OR rodzic_rodzic_tag = tag i tak dalej


A nie odwrotnie?
  1. WHERE
  2. produkt_tag = tag OR dziecko_tag = tag OR dziecko_dziecko_tag = tag i tak dalej

Drzewo pobieram i wyświetlam od góry. Czyli powonieniem sprawdzać czy tag występuje u jakiegokolwiek dziecka? Czy można to jakoś zrobić bez rekurencji?
Bo pobieranie tagów dziecka i ich sprawdzanie, potem pobieranie tagów dziecka dziecka i ich sprawdzanie masakrycznie zwolni bazę. Jak to zrobić?


Cytat(vokiel @ 19.10.2009, 19:11:44 ) *
E). Wyszukując produkt po tagu, dla każdego odnalezionego musisz pobrać resztę ścieżki w górę, potem wyniki pogrupować od góry, od kategorii najszerszego znaczenia, do tej najzwięźlejszej.

Nie rozumiem. Myślałem, że będę pobierać drzewo od góry. Wtedy właśnie ten problem mi się pojawił z rodzicami nie mającymi tagu dzieci. Jakbym pobierał produkty spełniające tag to nie byłoby tego wcześniejszego problemu. Ale jak je później wyświetlić w postaci drzewa? Zupełnie nie wiem jak się za to zabrać.

Cytat(vokiel @ 19.10.2009, 19:11:44 ) *
D). Po co tyle tych drzew?

Wiem, że to jest głupie ale to nie mój pomysł i nie mogę go zmienić.

Cytat(vokiel @ 19.10.2009, 19:11:44 ) *
C-A). Aby dać sobie możliwość wyświetlenia breadcrumbs'ów musisz jakoś poinformować skrypt z której ścieżki (drzewa) ma korzystać. Bo w takim, że tak to ujmę mętliku sam się nie połapie. Jeśli produkt może podlegać pod ścieżkę producenta->kategorii->subkategorii, lub producenta->tagu, etc, to musisz jakoś przekazać do skryptu gdzie ma tego szukać. Albo możesz co najwyżej pobrać pierwszą pasującą opcję.

Już sobie z tym poradziłem smile.gif

Cytat(vokiel @ 19.10.2009, 19:11:44 ) *
Czy nie możesz ograniczyć tego do drzewa kategorii a producenta umieścić jako jeden z atrybutów (właściwości) produktu?
Przynależność do kategorii może być różna, bo monitor lcd 22" może należeć do głównej kategorii monitory, subkategorii lcs, lub subkategorii 22", anyway producenta ma jednego.

Niestety nie mogę, bo podział w drzewie producentów ma być dokładnie taki jak an stronie danego producenta (każdy ma inny). Kolejny niefunkcjonalny bezsens sad.gif
A tak przez ciekawość, jeśli mam kategorie nierozróżnialne od produktów to czy lepiej dopisywać producenta do tabeli z produktami (wtedy kategorie będą miały NULL w tej kolumnie), czy lepiej stworzyć osobną tabelę z producentami i tabele product-producer? A może wpisać producentów jako tagi? I tylko w dodatkowej tabeli trzymać samą listę producentów (żeby odróżnić od tagów)? Które rozwiązanie uważasz za lepsze?

Cytat(vokiel @ 19.10.2009, 19:11:44 ) *
Jak ja to widzę, właśnie jedno drzewo. Nie stracisz na funkcjonalności, bo nadal będziesz mógł utworzyć drzewko menu według producenta, po prostu stworzysz drzewko po drzewku dla każdego producenta. Tak samo z resztą funkcjonalności, które przedstawiłeś.

Też o tym myślałem, ale nie zależy to teraz ode mnie. Czy dobrze myślę, że wyświetlanie drzewa z podziałem na producentów trzeba byłoby wtedy zrobić tak jak wyświetlanie drzewa produktów posiadających jakiś tag?

Cytat(vokiel @ 19.10.2009, 19:11:44 ) *
Poza tym jest w bazach danych pojęcie redundancji danych. No i robiąc kilka drzewek ze względu na najbardziej ogólny podział łamiesz tą zasadę. Każdy produkt występuje tyle razy ile masz drzewek, pomimo, że jest to ten sam produkt. (chyba, że źle zrozumiałem Twój opis - popraw mnie jeśli się pomyliłem). Drzewka

mają być podobne, różnice marginalne. Wiem, bez sensu sad.gif

Cytat(vokiel @ 19.10.2009, 19:11:44 ) *
W przypadku bazy opartej o drzewie większość działań będzie polegała na chodzeniu po drzewie w tą i z powrotem, niestety nie unikniesz tego.

Z chodzeniem po drzewie od góry do dołu jakoś sobie radzę. Ale w drugą stronę już nie. Jeśli możesz to napisz jak przechodzić po drzewie w górę i potem grupować wyniki, tak, żeby potem znowu otrzymać drzewo?






Zapomniałem się jeszcze zapytać, czy drzewo z bazy lepiej jest pobierać jednym zapytaniem, czy wieloma? Teraz pobieram wieloma zapytaniami. Po kolei wszystkie dzieci jakiegoś rodzica, potem dzieci dzieci. Czyli bardzo dużo pytań SELECT, między którymi wyświetlam listę nieuporządkowaną w html. Czy jeśli szybkość jest nadal na akceptowalnym poziomie, to warto zmienić tą moją metodę? Np pobrać tabelę z drzewem do PHP i później w samym PHP generować z niej odpowiednią strukturę drzewa? Byłoby dużo więcej roboty ale może warto?


pozdro
Zyx
Na stronie powinna być wykonywana w miarę stała liczba zapytań. W szczególności niebezpieczna jest sytuacja taka, jak opisujesz, czyli pobieranie drzewa setkami zapytań. Zaimplementuj sobie drzewka przy pomocy jakiegoś popularnego algorytmu (np. nested sets + parent_id - bardzo łatwo pobrać ścieżkę do elementu; wyświetlenie całego drzewa to dwa zapytania), a na ich dole daj po prostu dowiązania do produktów. Innymi słowy, produkty dodajesz niezależnie, a później dowiązujesz je w określone punkty drzewa.
nowy_pehapowiec
Nie mogę się połapać w tym co napisałeś.
Mam w jednej tabeli drzewo z adresami IP, dodatkowo mam parentID i depth. W innej tabeli mam dane produktów. Do tego oczywiście tabele pośrednie do tabel ze zdjęciami i innymi plikami.

I teraz, żeby uniknąć wielu pytań SELECT mógłbym pobrać (posortowaną w MYSQL według np IP) tabelę z drzewem. Ale nie bardzo wiem co dalej. Musiałbym chyba napisać sobie własne funkcje działające jak SELECT z MYSQL. Potem w pętli wyświetlać jako listę kolejne dzieci, dzieci dzieci, dzieci dzieci dzieci. Ale to się sprowadza do napisania własnego SQL. Chyba nie o to chodzi? Więc czy mógłbyś jakoś dokładniej napisać o co chodzi?

pozdro
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.