Ocena bazy danych i wzorzec projektowy

Ocena bazy danych i wzorzec projektowy

Wątek przeniesiony 2021-04-23 22:59 z Java przez flowCRANE.

B9
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 dni
  • Postów:65
0

Hej,

Piszę projekt na zaliczenie na studia, a także jako "pokaz" umiejętności dla potencjalnego pracodawcy. Jest to uproszczony sklep internetowy. Technologie to angular, spring boot, hibernate, postgresql. Pytania zapiszę poniżej dla lepszej czytelności:

  1. Czy baza danych jest sensownie zaprojektowana, czy warto pozmieniać jakieś rzeczy (może błędnie wykonany diagram).
    -Jeżeli chodzi o opis do produktu, to zakładam, że opis na stronie składa się z kilku sekcji, dlatego dodatkowa tabela.
    -Tabela product_details powinna zawierać wszystkie możliwe pola dla każdego typu produktu (np. telefon ma przekątną ekranu, ale karta graficzna już nie, więc byłoby to pole jako null). Nie wiem czy to dobre rozwiązanie, ale product_type, rozbija to na wiele klas w javie.

  2. Prosiłbym o podpowiedź jaki wzorzec projektowy tutaj zastosować. Jeszcze się w nich nie orientuję do końca, który pasowałby do tego modelu. Budowniczy, byłby przy tworzeniu nowego produktu (tak mi się wydaję).

2021-04-23_194952.png

bakunet
W czym robiłeś schemat relacji?
abrakadaber
abrakadaber
  • Rejestracja:ponad 12 lat
  • Ostatnio:7 miesięcy
  • Postów:6610
3
  1. billing i shipping_address to praktycznie to samo - część wspólna, czyli adres, powinna być w osobnej tabeli i powinna być powiązana z userem i z zamówieniem (jeśli dopuszczamy "pamiętanie" różnych adresów dostawy a jeśli nie to wystarczy z userem)
  2. order_row - średnia nazwa tabeli z pozycjami zamówienia
  3. do opinii można dodać tylko jedno zdjęcie
  4. nie widzę informacji o kwocie, jaką zapłacił klient (wcale nie musi być taka sama jak wartość zamówienia)
  5. brakuje: uwagi do zamówienia, sposób dostawy, koszt dostawy,
  6. co jeśli będę chciał zamówić np. 3 sztuki danego towaru
  7. product_details jak dla mnie jest nieakceptowalne - takie rzeczy robi się pionowo a nie poziomo (tzn. że zamiast dodawać nowe kolumny do tabeli opisujące nowe cechy dodaje się nowe rekordy)
  8. można jeszcze dodać warianty produktu (np. rozmiar albo kolor z taką samą ceną albo za dodatkową opłatą)

Chcesz pomocy - pokaż kod - abrakadabra źle działa z techniką.
B9
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 dni
  • Postów:65
0

Jutro poprawię i wrzucę poprawiony schemat. Nie rozumiem tylko z tym adresem. Jeżeli adres dostawy będzie inny niż rozliczenia, to wtedy mamy 2 rekordy w 2 tabelach. Jeżeli faktura nie będzie na inna osobę lub firmę, to wtedy bierzemy dane z dostawy na fakturę.

flowCRANE
Dyskusję prowadzimy w postach — komentarze są do off-topu.
nalik
A jak są takie same to duplikujesz dane.
nalik
  • Rejestracja:około 9 lat
  • Ostatnio:prawie 2 lata
  • Postów:1039
0

Ja się jeszcze dopytam, bo bazodanowiec ze mnie słaby, czy status nie powinien być w order?

edytowany 1x, ostatnio: nalik
B9
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 dni
  • Postów:65
0

@nalik: Chyba nie, operację na stringach trwają dłużej i zajmują więcej pamięci. Wolę mieć osobną tabelę z możliwymi statusami (żeby ktoś nie wprowadził błędnego z obsługi) i ewentualnie wykonywać szybki join.

@abrakadaber: Poprawiłem rzeczy o których wspomniałeś, dodałem także encję category o której zapomniałem. Teraz prezentuje się to tak:
2021-04-24_111804.png

TR
  • Rejestracja:ponad 7 lat
  • Ostatnio:około miesiąc
  • Lokalizacja:700m n.p.m.
  • Postów:677
1

W variant i product_details mieszasz różne rzeczy - tzn cechy produktu niezwiązane ze sprzedażą, z cechami produktu dotyczącymi sprzedaży.

Variant niepotrzebnie w ogóle jest osobną tabelą.

Ja w swoim silniku sklepu zrobiłem to trochę inaczej, stosując klasy produktów.

Co do klas:

  • Relacja na właściwości: nazwa właściwości, typ (tekst, liczba, data)
  • Relacja na klasę
  • Relacja łącząca klasę z właściwościami (wielu-do-wielu) - aby określić z jakich właściwości składa się klasa
  • Dodanie klucza obcego w relacji produktów do relacji klasy
  • Relacja łącząca produkt z właściwościami (wielu-do-wielu): oczywiście dokładnie tymi które wynikają z wybranej klasy. W tej relacji określa się wartości właściwości produktów wynikające z klasy.
    • zmiana klasy / określenie z pustej na niepustą: stworzenie powiązań w tej relacji dla danego produktu na podstawie tych właściwości które są związane z wybraną klasą
    • usunięcie klasy w produkcie (określenie na NULL): usunięcie powiązań z tej relacji

Masz tu też więcej problemów - np. produkt może należeć tylko do jednej kategorii, a powinno być tak, że powinien móc należeć do wielu kategorii ale tylko do jednej klasy (IMO).

Czyli kategorie to powinna być jedna relacja, produkty druga i trzecia relacja wielu-do-wielu łącząca dowolnie kategorie z produktami.


DRY > SOLID (nie bierz tego zbyt poważnie)
edytowany 5x, ostatnio: TomRZ
MA
  • Rejestracja:ponad 8 lat
  • Ostatnio:prawie 2 lata
  • Postów:337
0

@abrakadaber: czemu dane w product details powinny być zrobione per rekord a nie kolumnowo? Co nam to daje? Osobiście bym to wrzucił w arraya propertiesów w polu.

Description i product details to dla mnie powinna być jedna szeroka tabela, nie widzę osobiście zysku z rozbicia.

TR
  • Rejestracja:ponad 7 lat
  • Ostatnio:około miesiąc
  • Lokalizacja:700m n.p.m.
  • Postów:677
2
MuadibAtrides napisał(a):

Description i product details to dla mnie powinna być jedna szeroka tabela, nie widzę osobiście zysku z rozbicia.

Jesteś pewien?

Co w sytuacji kiedy masz w sklepie setki tysięcy produktów, z setek różnych branż? Musiałbyś mieć tabelę z ponad tysiącem kolumn, żeby te wszystkie cechy uwzględnić. LOL


DRY > SOLID (nie bierz tego zbyt poważnie)
B9
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 dni
  • Postów:65
0

@TomRZ: Faktycznie to co zrobiłem z wariantem nie ma większego sensu. Zrobiłem na klasach produktów, daj znać czy to miałeś na myśli, przykład:

  1. Produkt należy do klasy produktów smartfon
  2. Klasa smartfon ma przypisane specyfikację np. przekątna itd.
  3. Relacja produkt - specyfikacja pozwala uzupełnić wartości tych specyfikacji, tylko dla tej danej klasy.

W tym wypadku jeżeli chcemy np. 3 warianty kolorystyczne to będą 3 osobne produkty, ze zmienioną 1 specyfikacją. Czy może lepiej zrobić dodatkowe pole "różnica w cenie" w tabeli specyfikacja_produkt i jeżeli dla danego produktu będzie powielać się dana specyfikacja to wtedy będziemy możliwość dodania, lub odjęcia ceny dla konkretnie wybranej. Dzięki temu nie duplikujemy produktów ze zmienionym tylko np. kolorem.

Chyba że kompletnie nie o to chodziło.

Ps: Historie produktów potem poprawie, bo teraz nie ma sensu. Kategorie również.

2021-04-24_221004.png

edytowany 1x, ostatnio: brus97
TR
PS. jeżeli to co piszę jest pomocne to kciuk w górę poproszę
TR
  • Rejestracja:ponad 7 lat
  • Ostatnio:około miesiąc
  • Lokalizacja:700m n.p.m.
  • Postów:677
1
  • Relacja "produc_class_specification" jest niepotrzebna
  • Zamiast "specification_id" ma być "product_class_id" -> określasz do jakiej klasy nalezy produkt
  • To jakie będą powiązania w "product_specification" zależy od powiązań klasy w "product_class_specification" - oczywiście to już należy do logiki aplikacji, ponieważ do "product_specification" możesz wrzucić wszystko i dowolnie sobie określać cechy produktu w ogóle w oderwaniu od tego do jakiej klasy należy. Dlatego to logik aplikacji dba o to, żeby była spójność między tym jaka jest definicja klasy a jakie ma przydzielone cechy produkt należący do tej klasy. Powinien mieć tylko te które są dla klasy zdefiniowane - żeby był porządek.
  • W "specification" (czyli cesze) powinieneś dodać jaki to jest typ cechy - np. liczba, tekst, data
  • W "product_specification" powinieneś odpowiednio dodać kolumny dla typu wartości: np."value_int" -> jeżeli cecha jest liczbą calkowitą, "value_date" -> jeżeli datą, "value_varchar" - jeżeli to tekst. I tak dalej - ja u siebie mam jeszcze typ "enum" gdzie można wybrać z kilku zdefiniowanych cech, ale to dodatkowa komplikacja, na później ewentualnie.

DRY > SOLID (nie bierz tego zbyt poważnie)
edytowany 1x, ostatnio: TomRZ
B9
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 dni
  • Postów:65
0

Jak rozumiem w aplikacji będę posiadał interfejs klasa z podstawowymi metodami np. finalPrice(). Interfejs ten, będą rozszerzać dane klasy produktów np. telefon z dodatkowymi polami. Telefon rozszerzy telefon stacjonarny i domowy i każda z tych klas będzie miała swoje specyfikację.

Teraz pytanie jak rozwiązać problem powielania produktów np. smartfon xyz zielony albo niebieski, z tym że zielony kosztuje 20zł drożej. W polu specyfikacja dodać specyfikację dodatkowa cena np. 20zł i w aplikacji obliczać cenę od głównej? Jeżeli tak, to jak obliczać promocję np. na kolor niebieski tylko. W aplikacji pobiorę kolor zielony i niebieski, ale nie będę wiedział do którego przynależy promocja.

Czy faktycznie nie bawić się i tworzyć za każdym razem produkt, choćby miał on się powielić w 99%. Ułatwia to zarządzanie historią.

2021-04-24_225450.png

MA
  • Rejestracja:ponad 8 lat
  • Ostatnio:prawie 2 lata
  • Postów:337
0
TomRZ napisał(a):
MuadibAtrides napisał(a):

Description i product details to dla mnie powinna być jedna szeroka tabela, nie widzę osobiście zysku z rozbicia.

Jesteś pewien?

Co w sytuacji kiedy masz w sklepie setki tysięcy produktów, z setek różnych branż? Musiałbyś mieć tabelę z ponad tysiącem kolumn, żeby te wszystkie cechy uwzględnić. LOL

@TomRZ popraw mnie jeśli się mylę, ale według diagramu rozumiem, że zakładamy, że każdy produkt może mieć N wariantów i każdy wariant ma swój opis i detale - bo tak wynika z poprowadzenia linii w 1 poscie. Chyba, że tutaj jest błąd i ten opis przez product id powinien być połączony z głównym produktem?

Czy źle rozumiem details i defacto yo generyczne atrybuty do produktu per wiersz?

edytowany 1x, ostatnio: MuadibAtrides
B9
Cały diagram jest do oceny, jeżeli są lepsze rozwiązania to staram dostosowywać/zmieniać początkowe.
TR
  • Rejestracja:ponad 7 lat
  • Ostatnio:około miesiąc
  • Lokalizacja:700m n.p.m.
  • Postów:677
2

@brus97: ja u siebie to tak zrobiłem że po prostu grupuję wybrane produkty, które różnią się jedynie cechą X, wg. różnic tej cechy.

Może to być kolor, długość, cokolwiek z cech które są zdefiniowane w specification.

Dla każdego produktu osobno tworzysz listę cech, nawet jeżeli się powtarzają, robienie jakichś algorytmów i rozwiązań żeby zaoszczędzić trochę miejsca generalnie się nie opłaca.

Tworzysz sobie np. relację "product_specifcation_group": id, specification_id, gdzie określasz cechę do grupowania, a potem relację gdzie będziesz miał product_specifcation_group_id oraz product_id - i w ten sposób możesz zgrupować np. 8 prouktów a potem system w sklepie powinien pozwalać na szybkie przechodzenie między wariantami wg. specification_id

Co do reszty to nie patrzyłem już na diagram bo późno, może w poniedziałek.

@MuadibAtrides:
Tak, i Ty byś chciał to zrealizować dodając za każdym razem nową kolumnę do relacji na produkty, kiedy trzeba dodać jakąś nową cechę?

Np. zaczęliśmy sprzedawać pralki i trzeba określić np. prędkość wirowania, więc dodajesz na to nową kolumnę do relacji na produkty?

Nie tędy droga, to byłaby jakaś masakra.


DRY > SOLID (nie bierz tego zbyt poważnie)
edytowany 1x, ostatnio: TomRZ
ED
  • Rejestracja:około 7 lat
  • Ostatnio:prawie 4 lata
  • Postów:16
1

Witam serdecznie, poprawiona baza danych mi się podoba dodałbym jednak kluczowe elementy dla sklepu to znaczy wartość podatku. (jest to konieczne) i zastanowiłbym się nad dodaniem
cen sprzedaży oraz zakupu. Ponieważ mają ceny sprzedaży oraz zakupu później w łatwy sposób z CSV wygenerujesz zysk per każde zamówienie. Do tego doliczasz inne koszta i możesz dosyć łatwo rozliczyć się. (Szczególnie ważne w modelu dropshippingu) gdzie nie posiadasz produktów własnych i faktur na masowe zamówienia a setki bądź tysiące pojedynczych.

MA
  • Rejestracja:ponad 8 lat
  • Ostatnio:prawie 2 lata
  • Postów:337
0

@TomRZ: ja w NoSQL siedzę i tam to co Ty tutaj proponujesz zrobić na relacji przez nowe wiersze robi się po prostu structem / tablicą w encji. Ja bym dążył do jak najmniejszej liczby tabel i jeśli ma to sens złączał w 1 szersze tabele tam gdzie można.

TR
  • Rejestracja:ponad 7 lat
  • Ostatnio:około miesiąc
  • Lokalizacja:700m n.p.m.
  • Postów:677
1

@MuadibAtrides: autor pyta o bazę relacyjną a nie NoSQL, nie wiem czy tutaj kogoś interesuje jak Ty byś to zrobił w bazie nierelacyjnej - mnie to nie obchodzi.


DRY > SOLID (nie bierz tego zbyt poważnie)
B9
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 dni
  • Postów:65
0

Hej, sorka za przestój, plusiki rozdałem, tutaj ostateczna wersja bazy danych (dodane rzeczy od Emila). Resztę będę poprawiał w trakcie tworzenia stronki.

@TomRZ Z grupowaniem jeszcze przemyślę potem :d

Jeszcze ostateczne pytanie, lepiej zostawić tabelę status i payment, czy zrobić ich jako enum po stronie aplikacji i wrzucić pola do order.

2021-05-07_222418.png

edytowany 1x, ostatnio: brus97
TR
Dzisiaj to nie mam czasu, może jutro sobie popatrzę na Twój najnowszy diagram.
B9
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 dni
  • Postów:65
0

@TomRZ, wytłumaczyłbyś raz jeszcze, bo czegoś nie zrozumiałem. Każdy produkt ma zestaw specyfikacji, które określa logika aplikacji, na podstawie klasy produktu. W takim razie po co nam kategoria, skoro to samo robi klasa?

Ja to rozumiem tak:

  1. Mam produkt, smartfon.
  2. Logika aplikacji na podstawie kategorii pozwala utworzyć smartfon z danymi polami specyfikacji.

Innym razem mam monitor led. Jego kategoria to monitory, monitory led. Robię te same kroki co ze smartfonem. W takim razie co określa klasa produktu?

TR
  • Rejestracja:ponad 7 lat
  • Ostatnio:około miesiąc
  • Lokalizacja:700m n.p.m.
  • Postów:677
2

Produkt ma określoną klasę - tylko jedną, natomiast może należeć do wielu kategorii.

Możesz mieć np. damską suszarkę do włosów i wtedy:

  • ma klasę "suszarki"
  • należy np. do kategorii:
  1. AGD
  2. AGD->DO ŁAZIENKI
  3. AGD->DO ŁAZIENKI->SUSZARKI
  4. PRODUKTY WG. PŁCI
  5. PRODUKTY WG. PŁCI -> DAMSKIE

każda z tych 5-ciu kategorii to osobna kategoria - jeżeli robimy je rekurencyjnie w strukturze drzewa.


DRY > SOLID (nie bierz tego zbyt poważnie)
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)