Specyfikacje produktów - najlepsze rozwiązanie

0

Cześć!
Robię coś w rodzaju sklepu internetowego i buduję schemat bazy danych. Mam co do niego wątpliwości, dlatego proszę o pomoc. Oto tabele:

+----------------------------------------------------+
| products                                           |
+----+---------+----------+-------+---------+--------+
| id | type_id | brand_id | model | variant | option |
+----+---------+----------+-------+---------+--------+

+--------------------------------------------------+
| offers                                           |
+----+---------+----------+-------+---------+------+
| id | type_id | brand_id | model | variant | slug |
+----+---------+----------+-------+---------+------+

+----------------------+
| specification_fields |
+----+------+----------+
| id | name | type     |
+----+------+----------+

+----------------------------------+
| specification_rows               |
+----+----------+----------+-------+
| id | offer_id | field_id | value |
+----+----------+----------+-------+

type_id to typ produktu, np. procesor, płyta główna, etc.
Teraz moje wątpliwości:

  1. Tabele products i offers połączone są 4-kolumnowym kluczem obcym. To dużo. Kolumny type_id i brand_id wystarczy, że będą 1-bajtowe, ale model i variant to już varchar. Można to jakoś zoptymalizować czy nie ma się czym przejmować? Produktów na pewno nie będzie milion, co najwyżej kilka tysięcy.
  2. Specyfikacje. To co pokazałem to prościej chyba się nie da. Tylko zastanawia mnie czy nie ma lepszego rozwiązania. Tych rekordów będzie przybywać baardzo szybko. Myślałem o zapisywaniu specyfikacji całego produktu jako np. JSON. Problem w tym, że będę chciał zrobić filtrowanie wg. określonych pól specyfikacji. Nie kojarzę (przynajmniej w MySQL) mechanizmu, którym mógłbym to zrobić. Czy w takim razie zrobić to po stronie PHP?
  3. Pola specyfikacji chciałbym móc grupować. Jakiś lepszy pomysł niż kolejna tabela i klucz obcy w specification_rows group_id?
  4. Waga. Teoretycznie powinna być częścią specyfikacji, ale może zależeć od option, więc wydaje się to słabym pomysłem.
  5. Kolor. Też jako część specyfikacji czy osobno? Dlaczego?

Dodam, że planuję to zrobić na MySQL, ale jeśli inny typ bazy lepiej spełni moje wymagania to wdzięczny będę niezmiernie za informacje.
Jak to się robi w takich sklepach jak morele?

2

Z tego co pokazujesz dla specyfikacji idziesz w kierunku bazy typu EAV, to może skorzystaj z Magento, które umożliwia takie podejście. Druga opcja to kolumny dynamiczne dostępne w od wersji 5.3 MySQL(MariaDB), które są zapisywane w formacie JSON na polu BLOB, ale dają możliwość szukania po ich wartościach bezpośrednio w zapytaniach SQL. Tutaj możesz poczytać

1

Po pierwsze - nie wiem, po co trzymasz w tabeli OFFERS informacje o szczegółach produktu. Ja bym tam tylko dał ID produktu z tabeli PRODUCTS oraz ewentualnie inne dane dotyczące ZAMÓWIENIA a nie PRODUKTU - jak cena czy ilość. Cała reszta zawiera się już w tabeli z produktami, więc po co ją powielać? Poza tym jak pojawi się jakaś zmiana, to zamiast zmieniać w wielu miejscach, poprawiasz w tabeli z atrykułami i wszystko w temacie. Może to, o czym piszesz to jest ten twój klucz obcy, ale szczerze mówiąc nie wiem, czy jest sens to robić kluczem, czy nie lepiej po prostu na etapie odczytu zrobić JOIN'a.

Po drugie - często się stosuje rozbicie dokumentów na dwie tabele - jedna z nagłówkiem, a druga z zawartością. W ten sposób, tworząc nowe zamówienie najpierw tworzysz "nagłówek" dokumentu - czyli jego numer, datę, odbiorcę itp, a potem mając ID nagłówka, do drugiej tabeli zapisujesz treść zamówienia w postaci "ID, ID-NAGLOWKA, ID-TOWARU, ILOŚĆ, CENA" czy co tam będzie Ci konkretnie potrzebne.

Po trzecie
- odnośnie specyfikacji i parametrów - zamiast robić dla każdej pozycji osobne wpisy, ja bym raczej zrobił słownik z cechami i wypełniał jedynie te, które dotyczą danego produktu. W ten sposób możesz np. wyfiltrować wszystko, co działa z DDR3 - czy to same kości, czy też płyty główne. Ale żeby taki warunek był spełniony, musisz mieć słownik cech. I do tego pytanie do rozważenia - czy parametry wpisywać ręcznie, czy też w oparciu o słownik. Na pewno opcja słownikowa jest bezpieczniejsza - wpisując ręcznie możesz wpisać DRD3 zamiast DDR3 i wtedy już dopasowywarka parametrów Ci tego nie znajdzie, a mając słownik po prostu wybierasz pozycję z listy (a jeśli jej tam nie ma, to po prostu dodajesz do słownika).

Po czwarte - odnośnie pytania o kolor: jeśli nie masz powodów, żeby zrobić inaczej, kolor powinien być jednym z parametrów opisanych powyżej. Nie widzę powodów, żeby zrobić to inaczej. A jeżeli Ty masz jakieś powody, żeby kolor traktować inaczej, to podziel się :P

Waga. Teoretycznie powinna być częścią specyfikacji, ale może zależeć od option, więc wydaje się to słabym pomysłem. - wyjaśnij proszę o co tu chodzi, bo średnio rozumiem.

0

często jest tak ze po wyszukaniu produktu w sklepie masz do wyboru opcje koloru lub rozmiaru bezpośrednio na stronie danego produktu więc jest sens żeby te parametry traktować inaczej, informacja o wybranym kolorze znajduje się w pozycji zamówienia, ale resztę informacji jak napisało @cerrato bierzemy z tabeli products

0

@Miang: Ale to o czym piszesz przecież jest raczej po stronie frontu - dajesz wybrane 2 parametry do zmiany/określenia przez klienta, ale w bazie mogą być trzymane tak samo, jak wszystkie inne cechy. Moim zdaniem możliwość zmienienia koloru i tak nie uzasadnia innego traktowania tego parametru.

0

musisz mieć jakoś zapisane że te dwa produkty (te same o różnym kolorze) są w rzeczywistości jednym

Tutaj raczej zahaczamy o ewentualne pilnowanie stanów magazynowych. Bo to, o czym piszesz, moim zdaniem właśnie powoduje zamieszanie. Znaczy - robiąc kolor jako parametr, nie mamy wątpliwości, że produkt X w kolorze czerwonym oraz białym to jest to samo, tylko w innej barwie. A potem kolor będzie potrzebny jedynie do obsługi zamówienia i realizacji wysyłki (oczywiście zakładamy, że cena jest niezależna od koloru). Dlatego bym traktował kolor jak każdy inny parametr, a jedynie można od strony logiki palikacji wymusić, aby pewne pola (np. kolor) MUSIAŁY być wypełnione. Czyli - wczytujemy z listy parametrów wszystko, co jest przypisane do danego produktu, ale jednocześnie każemy użytkownikowi wybrać podczas składania zamówienia kolor, jaki chce dostać. Ale kolor jest normalnym parametrem, a jego wartość jest wskazywana w oparciu o dostępny słownik kolorów.

0

no właśnie o to mi chodzi, żeby rozróżnić parametry przypisane na stałe do produktu i parametry zmienne dla danego produktu, które użytkownik se wybiera jeśli tylko dany kolor czy rozmiar jest w magazynie, a jak nie to proponujemy mu jakiś domyślny

0

OK, coś się nie dogadaliśmy ;)
Tak, masz rację - teraz wiem o co Ci chodzi. Można to zrobić tak, jak pisałem, ale Twój sposób też jest OK. Chociaż w sumie to sprowadza się do tego samego - ja chciałem wymusić wybór koloru z poziomu logiki, a Ty chcesz z racji możliwości wyboru ten parametr traktować inaczej, niż pozostałe.
Niezależnie od wybranego sposobu, i tak trzeba jakoś pilnować stanów, żeby się nie okazało, żę czerwonych nie ma/zostały wycofane, ale ludzie mogą nadal zamawiać ;)

0

Na początku przepraszam za zamieszanie, ale teraz dopiero widzę jak niefortunnie nazwałem tabele. Otóż:
products - to tabela magazynu. Tutaj przechowuję informację o produktach i ich ilościach (akurat kolumnę quantity pominąłem). Przykład: typ: Buty, brand: VANS, model: ISO, variant: Black/Black, option: 38.
offers - to tabela na podstawie której tworzę strony produktowe. Dlatego klucz obcy składa się aż z 4 kolumn (wydaje mi się, że kolumnę type_id mógłbym pominąć). Dzięki takiej konstrukcji mogę mieć różne strony dla różnych variant, gdzie będę mógł wybrać option.

Jeśli chodzi o kolory, to typowo pod wyszukiwanie. Powiedzmy, że szukam w sklepie spodni, szarych. Mogę mieć na magazynie spodnie szaro-czarne, więc te też chciałbym zaproponować. Tylko przydałaby mi się jeszcze jedna informacja, czyli jaką część produktu zajmuje określony kolor. Jeśli mam na magazynie spodnie szare i czarno-szare, chciałbym najpierw wyświetlić te 100% szare.

Dziękuję @cs, kolumny dynamiczne to może być to czego potrzebuję :) EAV też ciekawy temat, biorę się za jego zgłębianie.
Dziękuję @cerrato, co prawda namieszałem i odpowiedziałeś mi w większości na pytania, których nie zadałem, ale to też cenne informacje :) Pokombinuję jeszcze z tymi słownikami.

PS. Nadałem nazwę offers, ponieważ traktuję to jako moje oferty dla klientów ;) Dla zamówień dałbym raczej orders.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0