Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Elastyczne atrybuty - problem projektowy
Forum PHP.pl > Forum > Bazy danych
FiDO
Problem ten jest bardzo podobny do problemu elastycznych cech do produktow w sklepach (tzn rozne kategorie lub nawet produkty majace zupelnie rozne zestawy cech), jednak jest pewna "subtelna" roznica.
Chodzi o to, ze prowadze sobie systemik do prowadzenia rankingow. Poki co jest tylko jeden rodzaj, wiec nie ma wiekszego problemu, ale w najblizszym czasie zamierzam to przerobic tak, zebym bez przeszkod mogl obsluzyc ich wiele. No ale do sedna.. kazdy z tych rankingow posiada pewne wspolne cechy, ale sa tez atrybuty specyficzne dla kazdego z nich.
Do tej pory jest mniej wiecej tak samo jak w przypadku cech produktow w sklepie..
Jednak u mnie problem polega na tym, ze podczas wyswietlania wynikow musze pobrac wspolne cechy kazdego wpisu oraz cechy specyficzne dla wyswietlanego rankingu za jednym zamachem (w przypadku sklepu cechy pobiera sie dopiero po "wejsciu" w konkretny produkt, a nie podczas samego ich listowania, co znacznie ulatwia sprawe). Wywolywanie osobnego zapytania dla kazdego wyniku, zeby pobrac te elastyczne atrybuty z oczywistych wzgledow odpada.
Malo tego musi istniec mozliwosc sortowania i filtrowania po tych specyficznych atrybutach, wiec raczej nie moge sobie ich trzymac w jakims jednym polu w postaci zserializowanej tablicy. Zeby jeszcze nie bylo za latwo to niekoniecznie kazdy z tych specyficznych atrybutow musi byc ciagiem znakow.. rownie dobrze moze to byc liczba (i tylko te 2 typy wchodza w gre), a w przypadku liczb sortowanie wyglada inaczej jesli pole jest typu liczbowego i inaczej jesli jest to string.

Narazie jedyne co wymyslilem to cos takiego, ze mam dodatkowe tabelki do tych atrybutow. Jedna z ich "definicją" (tj. nazwa, typ, jakis opis etc.), druga z wartosciami (id atrybutu z pierwszej tabeli, id wyniku i dwa pola z wartoscia - jedno liczbowe, drugie tekstowe) i trzecia to juz tylko tabela laczaca pierwsza tabele z tabela rankingow. Wybieranie wynikow odbywalo by sie poprzez zapytanie generowane przez php, co spodowaloby koniecznosc wykonania tylko dwoch zapytan. To do pobrania definicji atrybutow dla danego rankignu mozna dodatkowo cachowac, bo nie bedzie sie to zmieniac w trakcie.

Pytanie brzmi oczywiscie: czy ktos ma lepsza wizje rozwiazania tego problemu ?

Wczesniej nie mialem do czynienia z podobnymi przypadkami, wiec najlepsze co do tej pory udalo mi sie wymyslic to to co podalem wyzej. Za wszelkie uwagi do powyzszego oraz proby pomocy z gory dziekuje smile.gif
Jabol
Wpisy:
id, nazwa, kategoria, cechy wspólne, bla, bla, bla

Cechy:
id_wpisu, nazwa_cechy, wartość

A potem możesz sobie dołączać tabelkę cechy dla każdej cechy jaką chcesz oddzielnie.

NP
  1. SELECT *
  2. FROM wpisy
  3. w LEFT JOIN cechy c_1 ON (w.id = c_1.id_wpisu) LEFT JOIN cechy c_2 ON (w.id = c_2.id_wpisu) WHERE kategoria = 'blabla' AND c_1.nazwa_cechy = 'cecha1' AND c_2.nazwa_cechy = 'cecha_2';


Co prawda nie rozwiązuje to problemu typów, ale mógłbyś zrobić np:
Cechy:
id_wpisu, nazwa_cechy, intval, strval;
I możesz zaimplementować większość cech!
A potem tylko
  1. SELECT w.*, c_1.intval, c_2.strval
  2. FROM wpisy
  3. w LEFT JOIN cechy c_1 ON (w.id = c_1.id_wpisu) LEFT JOIN cechy c_2 ON (w.id = c_2.id_wpisu) WHERE kategoria = 'blabla' AND c_1.nazwa_cechy = 'cecha1' AND c_2.nazwa_cechy = 'cecha_2';
Albo jakoś tak


Inaczej mówiąc tabela cechy byłaby czymś w rodzaju implementacji typu union z C. Jeżeli potrzebowałbyś wartości numerycznej to strval ustawiasz NULL i jest ok. A jeżeli potrzebowałbyś stringa to na odwrót.
tort
Gdybyś posługiwał się systemem bazodanowym, w który pole może byc tablicą (np. PostgreSQL coś takiego obsługuje), to nie miałbyś problemu, bo mógłbyś wtedy robić, co ci się żywnie podoba, włącznie z sortowaniem i filtrowaniem wg określonych warunków.
FiDO
Jabol: nie wiem czy przeczytales calego mojego posta, ale to co podales to uproszczona wersja rozwiazania, ktore podalem.

tort: niestety musi to dzialac na MySQL'u 4.1, wiec pole manewru jest troche ograniczone.
060156
Roziwazanie jest proste,
zaloz kolumne o type text i serialize
przy zapisie a przy odczycie unserialize objekt
ktory opisuje atrybuty i moze byc calkowicie innej dla kazdego row..
Objekt definujesz w php dla kazdego typu atrybutow albo zaprojektujesz
go jako meta obiekt i bedzie opisywal rozne atrybuty ..
FiDO
A przeczytales pierwszego posta w calosci ? Pisalem, ze po tych polach ma byc mozliwosc sortowania/filtrowania jeszcze na poziomie SQL'a, wiec serializacja odpada.
splatch
Poproszę schemat bazy, jakiś rysunek, diagram, cokolwiek. Skoro mówisz o projekcie to warto by było pokazać jakiś ogólnik. smile.gif Z tego co zrozumiałem masz bazę doprowadzoną do 3 postaci normalnej, zatem dla mnie ok.

Pozdrawiam.
FiDO
Tak jest teraz:

http://willow.iie.uz.zgora.pl/~ipatalas/1.png

A to moj pomysl:

http://willow.iie.uz.zgora.pl/~ipatalas/2.png

(zostawilem tylko tabele znaczace)

Opis wykorzystania tego pomyslu jest w pierwszym poscie.
splatch
Po chwili przeglądania zauważyłem, że result details nie ma klucza głównego. Reszty schematu nie zdążyłem przeanalizować, postaram się w najbliższym czasie poświęcić na tą strukturę kilka chwil.
To co mnie zastanawia - dlaczego nie zastosować zwykłego pola tekstowego?
Wg moich pomiarów:
Kod
Order by world DESC
D
c
B
a
3
2
1


Kod
Order by world ASC
1
2
3
a
B
c
D
FiDO
Cytat
Po chwili przeglądania zauważyłem, że result details nie ma klucza głównego.

Blad w schemacie .. tam jest klucz, tylko nie dostal pozwolenia na pokazanie sie na schemacie winksmiley.jpg Powinno byc tak samo jak na drugim schemacie.

Co do pola liczbowego.. spojrz na ten przyklad:
Kod
+--------+
| punkty |
+--------+
| 1      |
| 11     |
| 15     |
| 25     |
| 5      |
| 65     |
+--------+
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.