Witam. Mam problem. Tworzę bazę mysql pod system obsługujący firmę ISP. Mam problem z poprawnym wyznaczeniem encji.
Pytanie jakie tabelki stworzyć, aby było jak najlepiej. Mam w firmie zwykłych klientów, pracowników(z których niektórzy są również klientami) i użytkowników mojego systemu(każdy użytkownik jest pracownikiem). Bardzo proszę o pomoc w rozpisaniu zależności. Dzięki.
Coś w tym rodzaju:
tab_osoba
osoba_id PK (autoinc)
nazwisko
imie
pesel
...
tab_klient
klient_id PK
...
tab_pracownik
pracownik_id PK
rodzaj_umowy_oprace
godziny_pracy
...
tab_user
user_id PK
login
haslo/ hash hasla itd.
uprawnienia
...
Zakładasz sobie rekord w tab_osoba. Jeżeli osoba jest:
- klientem to do tabeli tab_klient dodajesz rekord, gdzie klient_id=osoba_id
- pracownikiem to do tabeli tab_pracownik dodajesz rekord, gdzie pracownik_id=osoba_id
- userem to do tabeli tab_user dodajesz rekord, gdzie user_id=osoba_id
W ten sposób masz znormalizowaną bazę, każda osoba może występować w różnych rolach jednocześnie
ale po co aż 4 tabele?? jedna z klientami i jedna z pracownikami.
Są użytkownicy. każda tabela będzie miała własne kolumny. Jakbyś miał 2 tabele z klientami i pracownikami, z których ta sama osoba jest zarówno pracownikiem i klientem, musiałbyś powielać dane (redundancja), a to nie jest dobre.
enix napisał(a):
musiałbyś powielać dane (redundancja), a to nie jest dobre.
W niektórych przypadkach jest to wskazane...
Np. dane odbiorcy na fakturze - po zmianie adresu nabywcy, adres na duplikacie faktury MUSI pozostać taki sam (chyba, że właśnie dlatego jest duplikat wystawiany)
Marcin.Miga napisał(a):
enix napisał(a):
musiałbyś powielać dane (redundancja), a to nie jest dobre.
W niektórych przypadkach jest to wskazane...
Np. dane odbiorcy na fakturze - po zmianie adresu nabywcy, adres na duplikacie faktury MUSI pozostać taki sam (chyba, że właśnie dlatego jest duplikat wystawiany)
To nigdy nie jest wskazane. Funkcjonalność o której piszesz nie powinna być osiągana "na około" w postaci redundancji danych, tylko za pomocą wersjonowania rekordów. Przykładowo:
tab_adresy
id PK
data_od PK
data_do
dane adresowe...
Jeżeli chcemy pobrać obowiązujący na dany moment adres pytamy wówczas:
SELECT * FROM tab_adresy WHERE data_od<=data_dany_moment AND data_dany_moment<data_do
Na tabeli buduję się trigger, który niezauważalnie w tle wersjonuje rekordy, z tabelą pracuje się normalnie używając insert i update. Klucz główny tworzy ID i data_od.
Normalizacja bazy danych nie jest tylko akademicką teorią, warto ją stosować w praktyce, im większy projekt tym łatwiej dostrzec jej zalety.
Tabela faktur powinna mieć kolumny przechowujące wszystkie faktyczne wartości, a nie referencje do innych tabel.
enix napisał(a):
To nigdy nie jest wskazane. Funkcjonalność o której piszesz nie powinna być osiągana "na około" w postaci redundancji danych, tylko za pomocą wersjonowania rekordów.
[...]
Normalizacja bazy danych nie jest tylko akademicką teorią, warto ją stosować w praktyce, im większy projekt tym łatwiej dostrzec jej zalety.
Mam pytanie - napisałeś kiedyś aplikację, której ktoś używał do wystawiania faktur i nie poszedł za to do więzienia?
Rozwiązania na około są bardzo fajne, szkoda tylko, że niepotrzebnie komplikują logikę aplikacji i niepotrzebnie obniżają wydajność. Archiwizację rekordów stosować można w prostych przypadkach, nie w takich, które mogą implikować jakieś prawne konsekwencje.
A poza tym, żadna porządna firma nie trzymałaby raczej programisty, który wymyśla rozwiązania na około zamiast robić po ludzku.
A jeśli faktycznie "redundancja nigdy nie jest wskazana", to idź kasować wszystkie hurtownie danych na tym świecie. ;)
somekind napisał(a)
Tabela faktur powinna mieć kolumny przechowujące wszystkie faktyczne wartości, a nie referencje do innych tabel.
Gdzie tak uczą? Tę szkołę trzeba czym prędzej zamknąć!
[...]
Rozwiązania na około są bardzo fajne, szkoda tylko, że niepotrzebnie komplikują logikę aplikacji i niepotrzebnie obniżają wydajność. Archiwizację rekordów stosować można w prostych przypadkach, nie w takich, które mogą implikować jakieś prawne konsekwencje.
A poza tym, żadna porządna firma nie trzymałaby raczej programisty, który wymyśla rozwiązania na około zamiast robić po ludzku.
A jeśli faktycznie "redundancja nigdy nie jest wskazana", to idź kasować wszystkie hurtownie danych na tym świecie. ;)
[...]
"Prawne konsekwencje archiwizacji rekordów" - ciekawa rzecz ;)
Hurtownie danych zawierają zagregowane dane tylko do odczytu, nie stawią redundancji.
AdamPL napisał(a):
Gdzie tak uczą? Tę szkołę trzeba czym prędzej zamknąć!
Szkołę? Jeju, nie wiedziałem, że do szkoły jeszcze chodzisz i na wszystko z tej perspektywy patrzysz. [głaszcze]
Jeszcze nigdy w działającej aplikacji nie spotkałem się z wstawianiem do tabeli faktur np. referencji do tabeli adresów klientów. Zawsze wygodniej jest wstawić faktyczne wartości. Ale jeśli znasz inne bezpieczne i wygodne implementacje, to może je opisz, zamiast wstawiać infantylne zaczepki.
enix napisał(a):
"Prawne konsekwencje archiwizacji rekordów" - ciekawa rzecz ;)
Jeśli uważasz, że można manipulować treścią wystawionych dokumentów fiskalnych, to życzę powodzenia. (Tylko uważaj przy schylaniu po mydło.)
Hurtownie danych zawierają zagregowane dane tylko do odczytu, nie stawią redundancji.
W hurtowni wszystko jest oparte właśnie na redundancji.
A nawet hurtowni nie trzeba, w wielu aplikacjach w celach raportowych stosuje się widoki zmaterializowane. To też nie jest redundancja? [rotfl]
somekind napisał(a)
Szkołę? Jeju, nie wiedziałem, że do szkoły jeszcze chodzisz i na wszystko z tej perspektywy patrzysz. [głaszcze]
Jeszcze nigdy w działającej aplikacji nie spotkałem się z wstawianiem do tabeli faktur np. referencji do tabeli adresów klientów. Zawsze wygodniej jest wstawić faktyczne wartości. Ale jeśli znasz inne bezpieczne i wygodne implementacje, to może je opisz, zamiast wstawiać infantylne zaczepki.
Implementacja została już opisana w tym wątku, więc nie będę się powtarzał.
AdamPL napisał(a):
Implementacja została już opisana w tym wątku, więc nie będę się powtarzał.
Chodzi o tą trzymającą w jednej tabeli rekordy aktualne i historyczne?
No może jest to jakieś rozwiązanie, może i gdzieś stosowane, niemniej jednak w moim odczuciu jest przekombinowane, i zapewne spowalniające wszelkie operacje.
somekind napisał(a):
Chodzi o tą trzymającą w jednej tabeli rekordy aktualne i historyczne?
No może jest to jakieś rozwiązanie, może i gdzieś stosowane, niemniej jednak w moim odczuciu jest przekombinowane, i zapewne spowalniające wszelkie operacje.
Takie rozwiązanie jest stosowane w ERP dużej polskiej firmy. Sprawdzone w boju, w dużych firmach z różnych sektorów oraz w wielu sieciach, w których nie raz robiłeś zakupy. Z tego co wiem, nikt jeszcze za to nie siedzi :)
Czy ktoś uważa, że powinno być to inaczej zrobione niż enix zaproponował (na 4 tabelach)? Jeśli tak to bardzo proszę o opis, bo się bałagan w dyskusji zrobił.