Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Unikanie nadmiarowości danych
who?
post 20.09.2006, 20:30:39
Post #1





Grupa: Zarejestrowani
Postów: 47
Pomógł: 0
Dołączył: 4.05.2005

Ostrzeżenie: (0%)
-----


Witam,
Problem generalnie stary jak bazy danych w związku z czym sposobów na radzenie sobie z nadmiarowością również nie brakuje. Jednakże ostatnio doszedłem do wniosku, że o ile eliminowanie nadmiarowości w teorii wygląda na sprawę dość łatwą (a jeśli nie łatwą to przynajmniej jasno opisaną) o tyle w praktyce nie jest już tak różowo.

Rozważmy taki prosty z "życia wzięty" przypadek. Mamy bazę danych, w której istnieją trzy tabele: klienci, towary i faktury. Tabela faktury ma przechowywać wszystkie faktury wystawione dla danych klientów na dane towary. Oczywiście sprawa wygląda na wręcz banalną. Książkowe rozwiązanie tego problemu to utworzenie w tabeli faktury kluczy obcych tabeli klientow i tabeli towarów (plus oczywiście dodatkowe pola charakteryzujące daną faturę jak numer, data wystawienia itd.). Dzięki takiemu rozwiązaniu unikamy wspomnianej nadmiarowości ponieważ nigdzie nie powielamy danych. W praktyce jednak takie rozwiązanie średnio nas zadowala ponieważ jeśli wystawimy dla danego użytkownika kilka faktur, a później zedytujemy jego dane, to dane te również zmienią się na fakturach wystawionych przed edycją danych klienta (taka operacja jest niedpopuszczalna).

I tutaj zaczynają się schody - jak rozwiązać ten problem unikając nadmiarowości, a jednocześnie nie komplikując zbytnio bazy, a tym samym aplikacji? Oczywiście najprościej było by stworzyć ogromną tabelę faktury, która zawiera pola tabeli klienci i tabeli towary i przy dodawaniu nowej faktury kopiować wszystkie dane z tych tabel. Takie jednak tworzenie "super tabel" kłuci się generalnie z ideą relacyjności (nie mówiąc już nawet o nadmiarowości) dlatego wolałbym tego unikać. Z drugiej jednak strony tak się zastanawiam czy jest sens starać się za wszelką cenę eliminować tego typu nadmiarowość kosztem komplikacji systemu, w bazach gdzie będzie góra kilka tysięcy rekordów? Jakie jest wasze zdanie na ten temat i jak wy sobie radzicie z tym problemem?

Pozdrawiam,
who?
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 17)
SongoQ
post 20.09.2006, 20:46:00
Post #2





Grupa: Przyjaciele php.pl
Postów: 2 923
Pomógł: 9
Dołączył: 25.10.2004
Skąd: Rzeszów - studia / Warszawa - praca

Ostrzeżenie: (0%)
-----


Poruszyles dosc powazny problem, powiem CI tylko tyle ze z tym problemem kiedys sie meczylem, jest kilka mozliwosci, to jaka jest najlepsza trudno troche stwierdzic. W jedenj tabeli no fakt nadmiarowosc pewna jest.

Rozwiazanie jakie przychodzi mi do glowy to takie ze obecna struktura sie nie zmienia lecz edycja danych klienta powoduje dodanie nowego rekordu i ustawienie flagi obecnego klienta na nieaktywna lub wstawienie id do nowego klienta. Wtedy masz historie klienta (jego danych) nie masz nadmiarowosci i wszystko ladnie pieknie, problem pojawia sie wtedy jesli z id klienta masz podejmowane jakies operacje np konata bankowe numery faktur i inne rzeczy ktore na poczatku trudno przewidziec.
Wtedy mozna podzielic dane klienta jako id potrzebne inforamcje takie ktore sie nie zmienia a moga go zidentyfikowac a dane kontaktowe, ktore jak wiadomo moga sie zmieniac i wtedy faktura moze byc przypisania do danych jakie pojawia sie na fakturze i do tabeli tego klienta. Mozliwosci jest wiele, ktora jest najlepsza trudno powiedziec. Rozrysuj sobie, zastanow sie co naprawde kiedys bedzie w aplikacji (nieraz nieda sie przewidziec) ale podzial na tabele pozniej lepiej jest wprowadzac nowe rzeczy.


--------------------
Go to the top of the page
+Quote Post
nospor
post 20.09.2006, 21:22:23
Post #3





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Wydaje mi sie, iż pomysł z historią klienta, to dobry pomysl.
Cytat
problem pojawia sie wtedy jesli z id klienta masz podejmowane jakies operacje np konata bankowe numery faktur i inne rzeczy ktore na poczatku trudno przewidziec.
A tutaj nie wiem w czym problem. Moge prosic o wyjasnienie problemu? winksmiley.jpg

No i dodatakowa sprawa to to, iż dane klienta nie za czesto sie zmieniają, jesli wogole. Oczywiscie moze ktos zmienic miejsce zamieszkania, tudziez nazwisko, ale za czesto to sie nie odbywa


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
SongoQ
post 20.09.2006, 21:43:47
Post #4





Grupa: Przyjaciele php.pl
Postów: 2 923
Pomógł: 9
Dołączył: 25.10.2004
Skąd: Rzeszów - studia / Warszawa - praca

Ostrzeżenie: (0%)
-----


Cytat
A tutaj nie wiem w czym problem. Moge prosic o wyjasnienie problemu?

Np identyfikator uzytkownika (klienta) wplywa na logowanie (identyfikator potrzebny do zalogowania) czy numer rachunku bankowego.

Mam nadzieje ze moja wczesniejsza wypowiec naprowadzila Cie na pewien trop myslenia.


--------------------
Go to the top of the page
+Quote Post
nospor
post 21.09.2006, 07:17:26
Post #5





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
Np identyfikator uzytkownika (klienta) wplywa na logowanie (identyfikator potrzebny do zalogowania) czy numer rachunku bankowego.
No ok, ale co z tego? Zmienil sie login, to sie bedzie na nowy logowal. Zmienil sie numer rachunku - kasa bedzie szla na nowy


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
batman
post 21.09.2006, 07:30:30
Post #6





Grupa: Moderatorzy
Postów: 2 921
Pomógł: 269
Dołączył: 11.08.2005
Skąd: 127.0.0.1




Przykład z fakturami nie jest zbyt trafny. Przecież faktura zamawiana przez Kowalskiego może być wystawiona na Nowaka. W tabeli z fakturami i tak trzeba trzymać imię, nazwisko (ew. nazwa firmy), adres, nip itd winksmiley.jpg

A co do nadmiarowości. Czasami trzeba trzymać w kilku tabelach te same dane, chociażby ze względu na wydajność. Jeśli masz trzy tabele, a w każdej po kilkadziesiąt (kilkaset) tysięcy wierszy, wówzcas łączenie tych tabel, by wyjąć np. adres email staje się zadaniem bardzo zamulającym aplikację. Najlepiej trzymać ten adres email w kilku tabelach. Ponadto jeśłi zmieni się adres tez się zmieni w tabeli z użytkownikami nie musimy tworzyć historii, logów, itp o tym co kiedy było na jaki adres wysłane, ponieważ mamy to w interesującej nas tabeli.


--------------------
I would love to change the world, but they won't give me the source code.
My software never has bugs. It just develops random features.
Go to the top of the page
+Quote Post
SongoQ
post 21.09.2006, 08:35:07
Post #7





Grupa: Przyjaciele php.pl
Postów: 2 923
Pomógł: 9
Dołączył: 25.10.2004
Skąd: Rzeszów - studia / Warszawa - praca

Ostrzeżenie: (0%)
-----


Cytat
No ok, ale co z tego? Zmienil sie login, to sie bedzie na nowy logowal. Zmienil sie numer rachunku - kasa bedzie szla na nowy

To akurat zly przyklad byl.

Cytat
Przykład z fakturami nie jest zbyt trafny. Przecież faktura zamawiana przez Kowalskiego może być wystawiona na Nowaka. W tabeli z fakturami i tak trzeba trzymać imię, nazwisko (ew. nazwa firmy), adres, nip itd

Do tego sa 2 pola, laczysz id nabywcy i id platnika

Cytat
Najlepiej trzymać ten adres email w kilku tabelach.

Po co i aktualizacja wszystkich pol. Po to sa relacje zeby je wykorzystywac. Mechanizmy baz danych sa do tego celu stworzone a nie poto zeby operowac na jedenj tabeli.


--------------------
Go to the top of the page
+Quote Post
Zbłąkany
post 21.09.2006, 08:38:43
Post #8


Administrator serwera


Grupa: Developerzy
Postów: 521
Pomógł: 13
Dołączył: 2.04.2004
Skąd: 52°24' N 16°56' E

Ostrzeżenie: (0%)
-----


To może ja dodam swoje trzy grosze, ponieważ ostatnio miałem taki sam problem smile.gif . Jest aplikacja, w której każdy może się zarejestrować i wykupić na pewien czas usługę. Oczywiście zapłacić za nią może firma i osoba prywatna. Jeśli ktoś się zarejestruje i wykupi powiedzmy na miesiąc usługę i zakładając, że po tym miesiącu będzie chciał przedłużyć wynajem tej usługi to co wtedy? Może płacić ta sama osoba, albo ktoś inny to co wtedy? Więc stwierdziłem, że nie jest to zbyt ekonomiczne, ale ułatwi znacznie problem przejrzystości danych i dodałęm pola do faktury: imię i nazwisko, adres, nip i telefon. Ma to swoje plusy i minusy smile.gif . Jeśli za daną usługę płaci wciąż ta sama osoba, to chcąc nie chcąc będziemy powielać wciąż jej dane chyba, że często zmienia adres zamieszkania winksmiley.jpg . Z drugiej strony jeśli co któryś raz za usługę płaci inna osoba, bądź firma to wtedy nadmiarowości zbytniej nie ma. Oczywiście ten problem można rozwiązać dodając odpowiednie tabele do bazy danych. Oczywiście osoba, bądź firma, która opłaca usługę, nie musi chcieć faktury smile.gif .
@batman
Dobra baza powinna sobie z tym poradzić, bez większego problemu smile.gif


--------------------
Środowisko: Gentoo 2008.0 | Apache | PHP5 | PostgreSQL | MySQL | Postfix
Workstation: Gentoo 2008.0 | Firefox
Thomas Alva Edison: "Aby coś wynaleźć wystarczy odrobina wyobraźni i sterta złomu ..."
Odpowiedź na każde pytanie typu "Jak ...": "Nie da się, to nie PostgreSQL"
Go to the top of the page
+Quote Post
batman
post 21.09.2006, 09:11:01
Post #9





Grupa: Moderatorzy
Postów: 2 921
Pomógł: 269
Dołączył: 11.08.2005
Skąd: 127.0.0.1




Cytat
Po co i aktualizacja wszystkich pol. Po to sa relacje zeby je wykorzystywac. Mechanizmy baz danych sa do tego celu stworzone a nie poto zeby operowac na jedenj tabeli.


W podanym przykładzie niedopuszczalne jest edytowanie danych w zapłaconych fakturach. A tworzenie dodatkowych tabel na historię będzie duplikować dane.

Cytat
Po co i aktualizacja wszystkich pol. Po to sa relacje zeby je wykorzystywac. Mechanizmy baz danych sa do tego celu stworzone a nie poto zeby operowac na jedenj tabeli.


Całkowicie się z Tobą zadzam, ale nie ma sensu trzymać się dokładnie teoretycznych rozważań, tylko po to, by się ich trzymać winksmiley.jpg Jeśli coś ma działać bardziej wydajnie, warto to zastosować. Nie twierdzę, że w każdej tabeli powielać wszystkei dane. Chodzi mi o to, że jeśli używasz jakiegoś pola często, to nie ma sensu ciągłe łącznie kilku tabel. Zamiast tego masz wszystko w jednym miejscu. A do aktualizacji tych danych - po to są triggery.


--------------------
I would love to change the world, but they won't give me the source code.
My software never has bugs. It just develops random features.
Go to the top of the page
+Quote Post
nospor
post 21.09.2006, 09:18:15
Post #10





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
W podanym przykładzie niedopuszczalne jest edytowanie danych w zapłaconych fakturach
Zgadza sie.
Cytat
A tworzenie dodatkowych tabel na historię będzie duplikować dane.
Kto mowi o tworzeniu dodatowych tabel na historie?

Uzywajac histori, nie nie bedziesz edytowal danych w fakturze, nie bedziesz tworzyl dodatkowej tabeli.
Masz rekord klienta. Ma on swoje ID (id rekordu) i ID klienta.
Faktura jest przypisana do ID rekordu. Gdy zmieniaja sie dane klienta, tworzony jet nowy rekord tego klietna, z innym ID rekordu ale z tym samym ID klienta. Tak wiec stare faktury wskazuja na inne dane klienta, ale ciagle na tego samego klienta. Nowe faktury beda juz podpinane do nowych danych (do nowego rekordu klienta).
Chcac przesledzic historie klienta, pobierasz wszsystkie rekordy o jego ID. (nie ID rekordu tylko ID klienta)

proste smile.gif


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
batman
post 21.09.2006, 09:39:53
Post #11





Grupa: Moderatorzy
Postów: 2 921
Pomógł: 269
Dołączył: 11.08.2005
Skąd: 127.0.0.1




A co w przypadku jeśli usuniemy klienta z bazy? Jeśli mamy ograniczenie on delete restirct, wówczas nie usuniemy klienta - klucz obcy. A jeśli mamy cascade, to usuniemy z obu tabel.


--------------------
I would love to change the world, but they won't give me the source code.
My software never has bugs. It just develops random features.
Go to the top of the page
+Quote Post
nospor
post 21.09.2006, 09:42:47
Post #12





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




No zazwyczaj jesli mamy faktury, to nie powinno sie pozwalac na usuwanie klientow. To sa dane niezbedne do księgowosci.


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
SongoQ
post 21.09.2006, 09:55:00
Post #13





Grupa: Przyjaciele php.pl
Postów: 2 923
Pomógł: 9
Dołączył: 25.10.2004
Skąd: Rzeszów - studia / Warszawa - praca

Ostrzeżenie: (0%)
-----


Cytat
A co w przypadku jeśli usuniemy klienta z bazy?

Wtedy mozna ustawic flage ktora okresla ze klient nie figuruje w naszej bazie.

To co przedstawil @nospor jest jak najbardziej prawidlowym schematem.


--------------------
Go to the top of the page
+Quote Post
batman
post 21.09.2006, 10:05:41
Post #14





Grupa: Moderatorzy
Postów: 2 921
Pomógł: 269
Dołączył: 11.08.2005
Skąd: 127.0.0.1




W przypadku faktur proste, ale co jeśli będzie to inna aplikacja, np sklep internetowy (klient zamawia produkty i chce na nie faktury winksmiley.jpg ). Jesli mamy koszyk trzymany w bazie, a w koszyku tylko iduser i idproduct (oraz jakieś dodatkowe parametry, takie jak ilość, parametry, itd) i chcemy wyciągnąć jakieś info o klienci, wówczas musimy łączyć się z inną tabelą. A jeśli w koszyku trzymane będą informacje o produkcie i użytkowniku, wtedy unikniemy niepotrzebnego łączenia z dodatkowymi tabelami.

A co jeśli w trakcie chodzenia po sklepie użytkownik zmieni dane - trigger.


--------------------
I would love to change the world, but they won't give me the source code.
My software never has bugs. It just develops random features.
Go to the top of the page
+Quote Post
nospor
post 21.09.2006, 10:13:42
Post #15





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
Jesli mamy koszyk trzymany w bazie, a w koszyku tylko iduser i idproduct (oraz jakieś dodatkowe parametry, takie jak ilość, parametry, itd) i chcemy wyciągnąć jakieś info o klienci, wówczas musimy łączyć się z inną tabelą.
A czemu ty sie boisz tego lączenia z inna tabela? Przeciez to nie boli,a juz na pewno nie w takiej sytuacji.

POzatym dane klienta mozesz se w sesji trzymac jak ci one sa potrzebne


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
batman
post 21.09.2006, 10:26:54
Post #16





Grupa: Moderatorzy
Postów: 2 921
Pomógł: 269
Dołączył: 11.08.2005
Skąd: 127.0.0.1




@nospor

Nie boję się łączenia tabel winksmiley.jpg . Chodzi mi tylko o to, że w pewnych przypadkach, znacznie lepiej jest trzymać te same dane w kilku tabelach.


--------------------
I would love to change the world, but they won't give me the source code.
My software never has bugs. It just develops random features.
Go to the top of the page
+Quote Post
nospor
post 21.09.2006, 10:29:10
Post #17





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Tak, zgadzam się z Tobą: "W pewnych przypadkach."
Ale ten przypadek raczej do tych "pewnych " sie nie kwalifikuje.


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
batman
post 21.09.2006, 10:36:14
Post #18





Grupa: Moderatorzy
Postów: 2 921
Pomógł: 269
Dołączył: 11.08.2005
Skąd: 127.0.0.1




Cieszę się, że doszliśmy do porozumienia winksmiley.jpg Podany przykład miał za zadanie pokazać, że nadmiarowość danych nie jest złem wcielonym winksmiley.jpg. Fakt przykład może nie najlepszy. W każdym bądź razie należy unikać nadmiarowości danych ale nie za wszelką cenę, a tym bardziej nie za cenę wydajności aplikacji.


--------------------
I would love to change the world, but they won't give me the source code.
My software never has bugs. It just develops random features.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 19.07.2025 - 17:18