sadistic_son
15.12.2022, 09:52:53
Cześć. Wycinek prostego sklepu internetowego. W bazie są 3 rodzaje produktów: DVD, książki, meble. Dla wybranego produktu inne są pola je definiujące: dla DVD - MB, dla książki - ilość stron, dla mebli - wysokość, szerokość, głębokość. Jak najlepiej to przedstawić w bazie?
1) Tabela PRODUKTY i w niej kolumny typu: ID, nazwa, typ (DVD, książka, mebel), MB, ilość stron, szerokość, wysokość, głębokość.
czy
2) Tabela PRODUKTY i oddzielne tabele na dany typ produktu: tabela PRODUKTY_DVD, PRODUKTY_KSIAZKI, PRODUKTY_MEBLE.
Opcja druga wydaje mi się bez sensu i trudna w implementacji - poruszanie się po różnych pod tabelach...? Chyba niee. Ale za to opcja pierwsza wydaje się nieoptymalna, bo zawsze będą puste pola w tabeli.
Pomóżcie to wymyśleć.
Dzięki.
nospor
15.12.2022, 10:36:41
Obydwa zaproponowane przez ciebie rozwiazania sa zle.
Mniej wiecej tak to ma wygladac, pisane z palca
PRODUKT
id
nazwa
typ - kluczowe pole bo po typie bedziesz laczyl to z innymi tabelami
inne podstawowe dane produktu
WLASCIWOSC (w tej tabeli trzymasz jakie dodatkowe wlasciwosc ma dany typ)
id
typ
wlasciwosc
PRODUKT_WLASCIWOSC (tutaj beda trzymane konkretne wartosci wlasciwosci dla danego produktu)
produkt_id
wlasciwosc_id
value
To tylko pogladowe tabele

Ale ten typ tabel jest w miare uniwersalny, pozwla ci dodawac nowe typy produktow, nowe wlasciwosci bez dodawania nowych tabel czy kolumn
Salvation
15.12.2022, 10:57:59
Szczerze? To zrobiłbym dwie tabele: Product i ProductProperties
Product: id, name, type (typ pola Enum)
ProductProperties: id, productId, properties (typ pola JSON)
nospor
15.12.2022, 11:01:34
skoro wprowadzasz pole JSON, to po co w oogle ta druga tabela? Wtedy tylko jedna chyba wystarczy?
Product: id, name, type (typ pola Enum), properties (typ pola JSON)
Salvation
15.12.2022, 11:22:19
Można w jednej, wolę jednak rozbijać takie rzeczy, bo properties - pomimo, że wspólne per produkt - to jednak każdy typ ma inne. No i zapobiegasz "przypadkowemu" pobraniu wszystkich properties, musisz to zrobić świadomie, przez JOIN-a.
sadistic_son
15.12.2022, 11:23:22
Ok, zostawmy pola JSON proszę.
Nospor, więc będzie to wyglądać
tak?
Nie bardzo rozumiem jak teraz wypelnic dane.
W PRODUKT wpisuję konretne produkty:
1 | Krzyzacy | Ksiazka
2 | Szczęki | dvd
3 | Stolik nocny | mebel
A we właściwość co wpisuję?
1 | MB
2 | ilosc_stron
3 | szerokosc
4 | wysokosc
5 | dlugosc
Tak?
I teraz dla przykładu stolik będzie tak wyglądać w PRODUKT_WLASCIWOSC?
3 | 3 | 90
3 | 4 | 60
3 | 5 | 200
A dvd np tak?
2 | 1 | 128
Dobrze cię rozumiem?
nospor
15.12.2022, 11:54:59
kazda wlasciwosc to osobny rekord
wiec
1, dvd, mb
2, ksiazka, ilosc_stron
3, meble, wysokosc
4, meble, szerokosc
5, meble, glebokosc
No i PRODUKT_WLASCIWOSC
1,2,10 - Krzyacacy, ilosc stron 10
3,3,15 - Stolik nocny, wysokosc 15
3,4,20 - Stolik nocny, szerijisc 20
3,5,30 - Stolik nocny, glebokosc 30
itd
sadistic_son
15.12.2022, 13:03:27
Ok, zaczynam chwytać.
W takim razie po co w PRODUKT jeszcze podałeś kolumnę 'typ', skoro mamy ją już w tabeli WLASCIWOSC ?
nospor
15.12.2022, 13:20:51
Masz racje, w jednej z tabel jest niepotrzebna. Jak mowilem, pisalem z palca, jestem w pracy i chcialem na szybko tylko przygotowac ci tabele pogladowe a nie gotowy schemat bazy

Typ na dobra sprawe powinien byc tabela LOOKUP i tylko jego ID trzymac potem anie cala nazwe. I pewnie jakis pierd by sie znalazlo wiecej
Chwila moment. TYP jest potrzebny w obu tabelach bo przeciez rekordy w PRODUKT_WLASCIWOSC wkladasz na podstawie typu ktorego jest produkt. Jakbys to wywalil z produkt, to bys nie wiedzial jakie wlasciwosci masz brac.
sadistic_son
15.12.2022, 13:35:17
Skoro we WLASCIWOSC mam typ (np dla ID 1 jest to 'dvd' a dla 2 jest to 'ksiazka'), to przecież mając w PRODUKT_WLASCIWOSC dane 1,2,10 (Krzyacacy, ilosc stron 10) widzę, że wartość w kolumnie 'wlasciwosc_id' to 2, czyli jest to 'ksiazka' patrząc do tabeli WLASCIWOSC. Prawda? Więc może 'typ' jest w PRODUKT jednak zbędne.
nospor
15.12.2022, 14:05:48
Ale by wpierw zbudowac rekord
w PRODUKT_WLASCIWOSC dane 1,2,10 (Krzyacacy, ilosc stron 10)
to musisz wpierw wiedziec, ze PRODUKT to KSIAZKA
sadistic_son
15.12.2022, 14:14:47
No dobra, spróbuję tak jak piszesz, choć zapala mi się alarm, że nie powinno się duplikować wartości w bazie, a w takim rozwiązaniu mamy dokładnie to samo w 'typ' w tabeli PRODUKT oraz w WLASCIWOSC.
nospor
15.12.2022, 14:16:58
Wiedzialem ze to powiesz. To nie szkola/studia tylko prawdziwe zycie.
No proste pytanie: dostajesz produkt Krzyzacy. Skad bedziesz wiedzial ze dla tego produktu masz dodac wlasciwosc ILOSC STRON? Czemu akurat nie WYSOKOSC? Odpowiedz mi prosze na to pytanie
sadistic_son
15.12.2022, 14:22:51
Miałbym pole select które dane zasysa z tabeli WLASCIWOSC, usuwając duplikaty po name (czyli np żeby nie wyświetliło 3 razy 'mebel'). W zależności od tego co wybiorę to dynamicznie wyświetli się poniżej odpowiednie pole: np ilosc_stron - bo po wyborze 'ksiazka' sprawdzi w bazie we WLASCIWOSC że dla 'ksiazka' jest do wyświetlenia 'ilość_stron'. A dla wybranego 'mebel' wyświetli z WLASCIWOSC 3 wartosci - dlugosc, szerokosc i glebokosc.
nospor
15.12.2022, 14:28:34
Dobra, to pytanie ostatniej szansy:
masz w bazie 100mln rekordow,
Podaj mi teraz zapytanie, ktore policzy liczbe ksiazek w bazie
Albo jeszcze lepiej, ktore bedzie szukalo tylko po ksiazkach frazy "krzyzacy"
sadistic_son
15.12.2022, 14:40:34
Podaj mi teraz zapytanie, ktore policzy liczbe ksiazek w bazie
SELECT COUNT(`PRODUKT_WLASCIWOSC.id`) FROM `WLASCIWOSC`, `PRODUKT_WLASCIWOSC` WHERE 'PRODUKT_WLASCIWOSC.wlasciwosc_id' = 'WLASCIWOSC.typ' AND 'WLASCIWOSC.typ' = 'ksiazka'
Albo jeszcze lepiej, ktore bedzie szukalo tylko po ksiazkach frazy "krzyzacy"
SELECT 'PRODUKT_WLASCIWOSC.id' FROM `PRODUKT`, `PRODUKT_WLASCIWOSC` WHERE 'PRODUKT_WLASCIWOSC.wlasciwosc_id' = 'WLASCIWOSC.typ' AND 'PRODUKT.name' = 'Krzyzacy' AND 'WLASCIWOSC.typ' = 'ksiazka'
nospor
15.12.2022, 14:51:46
Przy zalozeniu, ze w bazie masz 30mln ksiazek, i ksiazka ma 5 wlasciwosci, zapytanie zwroci ze masz 150mln ksiazek

Drugie zapytanie tez ci zwroci 5 razy wiecej rekordow.
Nawet jesli poprawisz, zeby nie duplikowalo, to bedzie to wysoce nieoptymalne.
Ale rob jak uwazasz, ponoc najlepiej uczyc sie na wlasnych bledach

ps: a juz najlepszy bedzie przypadek, gdy bedziesz mial produkt bez ustawionej wlasciwosci. Wtedy to juz twoja aplikacja nie bedzie wiedziala czy to KSIAZKA czy UFO
sadistic_son
15.12.2022, 14:55:06
Nie upieram sie przy swoim - chcę zrobić najlepiej jak powinno być. No dobra, czyli lepiej powtorzyć w bazie 30mln razy słowo 'książka' niż mieć mniej optymalne wyszukiwanie? Jasne, że twoj sposob wydaje mi się łatwiejszy. Szukasz książki? Proszę - SELECT * FROM PRODUKT WHERE typ = ksiazka. Szukasz Krzyżaków? no problemo: SELECT * from PRODUCT WHERE name = 'krzyzacy' AND typ = 'ksiazka'. Czy to jest zgodne ze sztuką? Skoro twierdzisz, że tak, to ok, tą drogą pójdę.
nospor
15.12.2022, 15:01:05
Cytat
No dobra, czyli lepiej powtorzyć w bazie 30mln razy słowo 'książka' niż mieć mniej optymalne wyszukiwanie?
No i tak sie z toba gada. Mowilem, ze to tylko baza pogladowa a nie docelowa.
Napisalem tez w jednym z postow, ze ten TYP to powinienin byc tabela LOOKUP i wtedy nie trzymasz tekstu "ksiazka" tylko ID do ksiazka.
I tak, lepiej miec to type_id = 5 (ksiazka), powtorzone w tabeli PRODUKT 30MLN razy by baza pracowala optymalnie. Teoria ze szkoly/studow a praktyka przy normalnych projektach w prawdziwym zyciu, czesto nie ida w parze
Najlepszym przykladem jest strukura drzewiasta w bazie. Masz np. w serwisie kategorie, ktore maja subkategorie, te skolei maja subkategorie itd itd.
Logiczne wiec ze tworzysz taka strukture zgodnie ze sztuka:
Tabela CATEGORY
id
name
parent_id
banalne prawda? Niestey gdy masz w swoim serwisie 100 tys kategorii, nagle pracowanie na takiej strukturze zabija serwer, bo nie jestes w czasie rzeczywistym zrobic wiekszosci pracy na kategoriach anie produktach nalezacych do kategori. Wtedy wlasnie dodajesz kolejne pola, ze sciazka, z sasiadami i czym tam jeszcze, zalezy typu drzewka jakie chcesz uzywac. Tak,powielasz wtedy wpyte informacji, ale serwis chodzi jak ta lala
sadistic_son
15.12.2022, 15:06:40
ok, czaję, dzięki za wkład.
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.