• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Relacja tabeli produktow w sklepie internetowym

0 głosów
714 wizyt
pytanie zadane 18 sierpnia 2017 w SQL, bazy danych przez Wally Bywalec (2,840 p.)

Witam, zastanawiam się jak zaprojektować pewną rzecz. Nie że nie umiem, tylko myślę jak podejść do tego na wielu warstwach, jak dynamicznie to zrobić. Chcę napisać CRUD sklepu internetowego w ramach nauki.

Na stronie pewnego sklepu wyszukując produkty możemy filtrować po cechach smartfonów (system, wielkość ekranu), po cechach telewizora (obraz 3d, czy smart tv), po cechach pralki (wielkość bębna). Czyli z punktu OOP mamy class Product [id, nazwa, cena, ilosc w magazynie] i potem to inne klasy rozszerzają. W podobny sposób trzeba by było projektować tabele SQL.

W wielkim skrócie zastanawiam się, czy jestem w stanie to zrobić bardzo dynamicznie, że dodawanie nowych kategorii produktów, cech filtrowania byłoby możliwe runtime przez administratora na stronie web w panelu admina. Bez zmiany source kodu. Czy może to na etapie developmentu powinienem dodać nowy typ "SmartphoneProduct", tabelę stworzyć do tego i wystawić odpowiednie API RESTowe, które pozwala filtrować po tych cechach. Czyli zmiana source kodu.

Myślę, że z powyższego akapitu wybieram opcję drugą - gdy dodajemy nowe kategorie produktów do sklepu, jest wymagana zmiana kodu backend (w moim wypadku java spring + sql, akurat za pośrednictwem java hibernate). Tylko jak to zakodować?
- główna tabela `products` (id, nazwa, cena, ilosc w magazynie)
a potem wraz z dodawaniem nowych kategorii, tworzyć kolejno tabele
- `products_smartphones` (products.id, cechy: system operacyjny, wielkosc pamieci, ekran, ...)
- `products_zelazka` (products_id, cechy: rodzaj zelazka, rodzaj stopy, moc)

Teraz na stronie glownej jak wyswietlic chociaz dostepne kategorie produktow?
- hardcodować, czyli we warstwie frontu kopiowac model jaki mamy w backend, napisac kolejno smartfony, zelazka, telewizory - brzydkie rozwiazanie. W przypadku potem tworzenia apki mobilnej, apki TV - przy dodawaniu nowej kategorii w systemie, musze kilka frontów modyfikować
- pobrac dostepne kategorie (pobraz model z backendu), ale co, mam SQL pobrac nazwy wszystkich tabel i przefiltrowac te ktore w nazwie maja "products_*" ? Dylematy mam, bo to jakby warstwa struktury bazy i wyciaganie modelu dostepnych kategorii na podstawie pobrania nazw tabel kłóci mi się, bardziej powinna byc jakas tabela `categories`

Do tego dołóżmy fakt, że kategorie mają być rekurencyjne:
- Komputery
- - Podzespoły
- - - Procesory
- - - Ram
- - - Karty graficzne
- - Klawiatury
- - Myszki
- Telewizory
- AGD

Finalnie, mój pomysł na to, to tabela `products` z (id, nazwa, cena, sztuki w magazynie, opis produktu, categories_id), kolejne tabele `products_smartphones`, `products_keyboards`, ktore maja relacje do glownego `products`. Te rozszerzajace posiadaja tylko cechy dla produktu. A jako ze korzystam w systemie z Hibernate, to odpowiednikiem tych tabel bede mial javowe klasy i dla propertiesów klasy SmartphoneProduct - moge im nadac adnotacje wymyslona np. @Filterable, dzieki czemu w backendzie wiem po czym dany typ moge filtrowac (system operacyjny, wielkosc ekranu).
Również potrzebuje tabeli `categories` (id, nazwa, parent_category_id) żeby móc zrobić takie drzewko jak tam akapit wyżej. Trzeba by też związać produkty z tymi kategoriami.

I wydaje mi się że to jest OK. Choć gdybym teraz chciał pobrać wszystkie produkty z bazy wraz z ich szczegółowymi danymi w jednym zapytaniu, to nie jest to możliwe, bo im więcej kategorii produktów, tym więcej tabel. Ale nie ma takiej potrzeby. Za to mogę pobrać wszystko, z podstawowymi danymi. Na stronie sklepu przeglądamy kategorie, szukamy produktu i jeśli już szukamy czegoś, to mamy dokładne wyniki ze wszystkimi cechami dla jednego typu - np smartfony. Nie potrzebujemy wyświetlać pralek i smartfonów na jednej stronie ze wszystkimi ich dokładnymi cechami. 

Co myślicie o tym sposobie myślenia? Może coś powinienem inaczej pomyśleć. Długi post, trochę posłużyło to jako metoda gumowej kaczki. Jak po przeczytaniu tego coś komuś się wyraźnie na myśl ciśnie że coś powinienem inaczej, albo czegoś brakuje to chętnie posłucham. 

1 odpowiedź

+1 głos
odpowiedź 18 sierpnia 2017 przez Ehlert Ekspert (215,210 p.)

Tabele w stylu products_smartphones to zły pomysł, gdyż po roku na produkcji będziesz mieć 1000 tabel. Musisz zrobić jedną tabelę produktów i tak ją rozwijać żeby dawała radę i żelazkom i telefonom. 

Co do rekurencji kategorii to sprawa prosta. Tabela Categories i pola:

  1. Id -  wiadomo
  2. Name - wiadomo
  3. Parent_id - id kategorii rodzica z tej samej tabeli. 

Co do admina... Dodawanie kategorii będzie bardzo łatwe. Kwestia Inputa. Dodawanie kryteriów wyszukiwań to cięższa sprawa ponieważ musisz stworzyć coś, co będzie dynamicznie generować sql.  

komentarz 18 sierpnia 2017 przez Wally Bywalec (2,840 p.)
edycja 18 sierpnia 2017 przez Wally

Hm, no to jesli jedna tabela produktow (id, nazwa, cena, sztukWMagazynie, opis) co jest cecha wspolna dla wszystkich, to do tego trzeba by dodac jedno wielkie pole string i te cechy dla roznych upchac w tym jednym rozdzielone jakims znakiem '|'.

Np jakis rekord ze smartfonem mialby tego stringa takiego "5.0|android|7.1|snapdragon 830|4|350". W backendzie javy mialbym patterny jak rozszyfrowac te stringi w roznych kategoriach, tutaj byloby to kolejno: przekatna ekranu | system | wersja | procesor | ilosc ram | ppi. W kwesti OOP jakis package na te typy. Przykladowo klasa Smartphone, mialaby metode na dekodowanie tego stringu z bazy. Plus wiedzialaby co filtrowac i jak filtrowac.

W backendzie, gdy dostane jakikolwiek produkt z bazy, to po product.category_id, z tabeli category wiem ze to Smartfon i w javie gdy ten pobrany raw produkt zmieniam na obiekt javy Product, moge ustawic jemu (Product.jakiesPole) ten filtr/whatever z akapitu wyzej ze to Smartphone i wyodrebnic dane szczegolowe, wszystko.

Da sie zrobic. Tylko teraz potencjalny klient chce na stronie zobaczyc wszystkie telefony z 4GB ramu i androidem w wersji 6, 7, oraz 7.1. Spokojnie w backendzie zapytanie to wygeneruje na podstawie tego co klasa Smartphone akapit wyzej mowilem. Tylko baza danych musi wykonac takie specyficzne filtrowanie w zwiazku z tym jednym polem. Klauzula WHERE + REGEX na to pole string. Wydajnosc? Bedzie dobrze? :)

A gdyby teraz wrocic do poczatku i zastanowic sie co sie chce osiagnac, to ta procedura dodania nowego typu produktu do sklepu wymaga zmiany w kodzie. Ale moze to jest ok. Daloby sie moze bez zmiany kodu. Tylko wiecej rzeczy by trzeba bylo w bazie trzymac. Pytanie czy robie skrypt dla swiata jako produkt na sprzedaz (ala wordpress) - postaw zaawansowany sklep paroma kliknieciami, czy konkretnie pod jakis sklep/firme robie soft.

komentarz 18 sierpnia 2017 przez Ehlert Ekspert (215,210 p.)
Nie zajmuj się szczegółami. Od początku powinieneś zacząć od kartki i ołówka.

Kategorie, problem z głowy. Id|name|Parent_id

Teraz ogarnij cechy. Każda cechą musi mieć rodzica. Id odnoszące się do kategorii. Tabela feature:

Id|name|Category_id.
komentarz 18 sierpnia 2017 przez Wally Bywalec (2,840 p.)
Ok, racja. Pomysle jeszcze nad tym i sprobuje wymyslec.

Tabela `features` - spoko, kategorie produktow wiedzą jakie cechy posiada.

A wartości trzymać w dużym polu string w tabeli products czy osobna tabela? W sumie chyba ta osoba by była lepsza.

Czyli dodaje smartfona do bazy sklepu, cech on ma ze 30 (hardware, wymiary, bateria, czuwanie, czujniki, ...) to taki jeden smartfon to 30 wierszy w jakiejś tabeli `featues_values`. Ale to tylko przy dodawaniu tak dużo idzie zapytań.

Podobne pytania

0 głosów
2 odpowiedzi 432 wizyt
0 głosów
1 odpowiedź 266 wizyt
+1 głos
1 odpowiedź 829 wizyt

93,772 zapytań

142,730 odpowiedzi

323,382 komentarzy

63,369 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Twierdza Linux. Bezpieczeństwo dla dociekliwych

Aby uzyskać rabat -10%, użyjcie kodu pasja-linux, wpisując go w specjalne pole w koszyku.

...