2012-05-26 11 views
13

Mój profesor (który twierdził, że od wielu lat ma głębokie pojęcie o rozwoju systemów) i kłócę się o projekt naszej bazy danych.Normalizacja baz danych - kto ma rację?

Jako przykład: Mój profesor twierdzi, konstrukcja ta ma rację: (lista kolumn)

Subject_ID 
Description 
Units_Lec 
Units_Lab 
Total_Units 

etc ...

Wskazówka kolumna ogółem jednostek. Powiedział, że ta kolumna musi zostać uwzględniona. Próbowałem wyjaśnić, że nie jest to konieczne, ponieważ jeśli chcesz, po prostu zrób zapytanie, po prostu dodając dwa.

Pokazałem mu przykład znalazłem w książce, ale upiera się, że nie muszę polegać na książkach zbyt wiele, że nasz system. To samo odnosi się do podobnych przypadków, jak w tym jednym:

student_ID 
prelim_grade 
midterm_grade 
prefinal_grade 
average 

ect ...

Chciał, żebym to średnią! Gdziekolwiek pójdę, mogę przeczytać artykuły, które przekonują mnie, że jest to naruszenie normalizacji. Jeśli potrzebuję średniej, mogę łatwo obliczyć trzy stopnie. Wymienił kilka scenariuszy, w tym: "Hej, co, jeśli zapytanie zostało przypadkowo usunięte? Co zrobisz? To dlatego musisz uwzględnić to w swoim stole!")

Czy muszę zrekonstruować moją bazę danych (która składa się z około 40 tabel), aby spełnić to, czego chce? Czy jestem w błędzie i po prostu przeoczyłem te rzeczy?

EDIT:

Inną rzeczą jest to, że chciał obejmować całkowitą kwotę płatności w tabeli, która moim zdaniem jest niepotrzebne (Wystarczy obliczyć cenę jednostkową produktu i ilość.). Zaznaczył, że potrzebujemy tej kolumny do obliczania obciążeń i/lub kredytów, które są kluczowe dla ogólnego zarządzania systemem, które są potrzebne do równoważenia transakcji. Powiedz mi, co myślisz.

+3

To prawda, że ​​oferujesz bardziej znormalizowane rozwiązanie. Ale pamiętaj, że twój profesor oceni Twoje rozwiązanie. Możesz wywołać spór w konstruktywny sposób. Ale nie powinieneś odstępować od jego rozwiązania sporu. – Andomar

+0

@ redskins80 jest tutaj. Należy jednak zauważyć, że nigdy nie jest dobrym pomysłem dyskutować zbyt wiele ze swoim profesorem, jeśli chcesz uzyskać dobrą ocenę w swojej klasie. Nieważne, jak bardzo się myli ... –

+0

Andomar ma rację. Zrób to, co trzeba, aby dokonać oceny. Ale kiedy idziesz na rozmowy kwalifikacyjne (zobacz mój komentarz pod odpowiedzią poniżej), upewnij się, że odpowiadasz na to pytanie we właściwy sposób. –

Odpowiedz

11

Masz całkowitą rację! Jedną z zasad normalizacji jest redukcja tych atrybutów, które można łatwo wydedukować przy użyciu wartości innych atrybutów. tj. wykonując pewne obliczenia matematyczne. W twoim przypadku kolumnę całkowitych jednostek można uzyskać, po prostu dodając.

Powiedz swojemu profesorowi, że o ten konkretny kolumna pokaże wyraźne oznaki uzależnienia przechodniego i zgodnie z 3 zasadą normalizacji, jego zalecany w celu zmniejszenia tych.

+1

Zgadzam się z @ redskins80; W niektórych przypadkach korzystne jest denormalizowanie danych, ale tylko w przypadku optymalizacji w przypadkach, gdy jest to często potrzebne, a obliczanie za każdym razem ze źródeł jest bardzo kosztowne. – lanzz

+2

Jedynym możliwym wyjątkiem w tym przypadku - a ja rozciągam się nieco, aby * spróbować * dać temu profesorowi * jakąś * korzyść z wątpliwości - jest to, że według zasad biznesowych w systemie, Total_Units nie zawsze ma aby wyrównać sumę pozostałych dwóch kolumn ... powiedzmy na przykład, czy Total_Units może zawierać jednostki premiowe przyznawane według uznania profesora, który nie rozumie normalizacji bazy danych. :-) –

+0

@KP Taylor: BARDZO WAŻNY POINT Muszę powiedzieć! może być możliwe, z wyjątkiem tego, że uczeń musiał wiedzieć, czy tak było. Nie zapytałby inaczej. – arijeet

6

Oprócz znakomitej odpowiedzi redskins80, chcę wskazać, , dlaczego jest to zły pomysł: za każdym razem, gdy trzeba zaktualizować jedną z kolumn źródłowych, należy również zaktualizować kolumnę obliczeniową. To więcej pracy, która może łatwo zawierać błędy (być może rok później, gdy inny programista zmienia system).

Może zamiast tego możesz użyć kolumny obliczeniowej? Byłby to praktyczny środek.

Edycja: Denormalizacja ma swoje miejsce, , ale jest to ostatni krok, który należy podjąć. To jest jak chemioterapia: lekarz wstrzykuje wam truciznę, aby wyleczyć jeszcze większe zagrożenie dla zdrowia. To jest ostatni możliwy krok.

+0

... lub utwórz widok w tabeli zawierającej kolumnę Suma. –

+1

Nie mogę podkreślić, jak dobry jest użytkownik! Każda informacja, która musi być zsynchronizowana podczas aktualizacji baz danych, jest możliwym błędem, który czeka na wykonanie. – Gnosophilon

+1

Co gorsza: za każdym razem, gdy zmienia się rząd, średnie z ** wszystkich rzędów ** muszą zostać przeliczone. – wildplasser

1

Jeśli chcesz wdrożyć dobry, stary, klasyczny model relacyjny, myślę, że to, co robisz, jest właściwe.

Ogólnie rzecz biorąc, jest to kwestia filozofii. Niektóre systemy, na przykład Oracle, pozwalają nawet na rezygnację z tradycyjnego, relacyjnego modelu na rzecz obiektów, które (będąc złożonymi strukturami przechowywanymi w tabelach) naruszają 1. NF, ale dają moc modelu obiektowego (Ty może korzystać z dziedziczenia, zastępowania metod itd.), co w niektórych przypadkach jest wręcz cholernie niesamowite. Używany język to nadal SQL, tylko rozszerzony.

Wiem, że moja odpowiedź odsuwa się od tematu (biorąc pod uwagę zupełnie nowy typ bazy danych), ale pomyślałem, że jest to interesująca rzecz, którą można podzielić się przy okazji dość ogólnego pytania.

Projektowanie baz danych dla rzeczywistych aplikacji nie jest kwestią wyboru tabel. Obecnie istnieją niezliczone możliwości, jeśli chodzi o przechowywanie i przetwarzanie danych. Istnieją systemy relacyjne, które wszyscy znamy i kochamy, bazy danych obiektów (takie jak db4o), relacje obiektowo-relacyjne (nie mylić z mapowaniem relacyjnym obiektów, mam na myśli narzędzia takie jak Oracle 11g z jego obiektami), bazy danych xml (we eXist) , strumieniowe bazy danych (takie jak Esper) i obecnie dobrze prosperujące bazy danych NoSQL (niektórzy twierdzą, że nie powinny być nazywane bazami danych), takie jak MongoDB, Cassandra, CouchDB lub Oracle NoSQL

W przypadku niektórych z nich normalizacja traci sens. Każdy model ma zupełnie inny cel. Myślę, że termin "baza danych" ma znacznie szersze znaczenie niż kiedyś.

Jeśli chodzi o relacyjne bazy danych, zgadzam się z tobą, a nie z profesorem (chociaż nie jestem pewien, czy dobrze jest przeciwstawić mu się mocno).

Teraz, do rzeczy. Myślę, że możesz go przekonać, pokazując, że jesteś otwarty i że rozumiesz, że jest wiele opcji do wzięcia pod uwagę (w tym jego poglądy), ale sytuacja wymaga normalizacji danych.

Wiem, że moja odpowiedź jest dość strumieniem sumienia dla postu stackoverflow, ale mam nadzieję, że nie zostanie odebrany jako szalony bełkot.

Powodzenia w relacyjnej holownika wojny

+0

Dzięki, zrobię to, co powiedziałeś. Nawiasem mówiąc, używamy serwera sql. – Arman

12

Masz rację, kiedy mówisz rozwiązanie jest bardziej znormalizowane.

Istnieje jednak rzecz o nazwie denormalizacja (google to), która polega na celowym naruszaniu zasad normalizacji w celu zwiększenia wydajności zapytań.

Na przykład chcesz odzyskać pierwszych pięć obiektów (niezależnie od tego, jakie byłyby) uporządkowanych według malejącej liczby lub całkowitej liczby jednostek.

Twoje rozwiązanie wymagałoby pełnego skanowania na dwóch tabelach (subject i unit), dołączając do zestawów wyników i sortując dane wyjściowe.

Rozwiązanie twojego profesora wymagałoby właśnie zrobienia pierwszych pięciu rekordów z indeksu na total_units.

To oczywiście wiąże się z wyższymi kosztami utrzymania (zarówno pod względem zasobów obliczeniowych, jak i rozwoju).

Nie mogę powiedzieć, kto jest tutaj "właściwy": nic nie wiemy o samym projekcie, ilości danych, zapytaniach itp.Jest to decyzja, którą należy podjąć w przypadku każdego projektu (a dla niektórych projektów może to być podstawowa decyzja).

Chodzi o to, że profesor ma uzasadnienie dla tego wymogu, który może, ale nie musi być sprawiedliwy.

Dlaczego nie wyjaśnił wszystkiego samemu powyżej, jest inne pytanie.

+0

Wiem o denormalizacji przed rozpoczęciem projektu i nie sądziłem, że przyniesie to korzyści systemowi. Uzasadnieniem mojego profesora jest to, że: 1. Widoki mogą zostać usunięte przypadkowo. 2. Kwota debetu/kredytu musi być odpowiednio wyszczególniona (przeciwnie, po prostu zapytanie o wcześniejsze transakcje) – Arman

+0

@Arman: jakiej odpowiedzi oczekujesz od nas? Czy twoje rozwiązanie jest bardziej znormalizowane - tak, jest. Czy Twoje rozwiązanie jest bardziej wydajne - nie wiemy i nie możemy stwierdzić z ograniczonej ilości dostarczonych danych. Kto ma rację - "mu". – Quassnoi

+2

Świetna odpowiedź. Jeśli Normalizacja byłaby wszystkim, wszystkie bazy danych byłyby w 5. Normalnej formie, a prawie nigdy nie byłbyś w stanie wykryć problemów, które występują w programie, bez pisania ogromnego zapytania SQL z wieloma złączeniami. Pracowałem nad systemami, które były znormalizowane, i to była prawdziwa PITA. Pomiędzy normalizacją a łatwością użycia jest dobra płaszczyzna pośrednia. –

4

Należy dodać to, ponieważ odpowiedź na pytanie nie jest kompletna w mojej opinii. Pierwotne pytanie zostało dobrze odebrane, ale tutaj jest usterka. Więc biorę na koncie tylko dodaje pytanie cytowany poniżej:

Inną rzeczą jest to, że chciał to łączną kwotę w tabeli płatniczego, który moim zdaniem jest niepotrzebne (Wystarczy obliczyć jednostka cenę produktu i ilość.). Podkreślił, że potrzebujemy tej kolumny do obliczania obciążeń i/lub kredytów, które są krytyczne dla ogólnego zarządzania systemem, które są niezbędne do równoważenia transakcji . Powiedz mi, co myślisz.

Ta edycja jest interesująca. W oparciu o fakty, że jest to system transakcyjny dotyczący pieniędzy, musi być odpowiedzialny. Biorę kilka podstawowych terminów: transakcja, produkt, cena, kwota.

W tym sensie jest bardzo powszechne lub nawet wymagane do denormalizacji. Czemu? Ponieważ musisz być odpowiedzialny. Więc kiedy transakcja jest zarejestrowana, to jest to, nigdy nie może być modyfikowana. Jeśli chcesz to poprawić, dokonaj kolejnej transakcji.

Teraz tak, możesz obliczyć np. Cenę produktu * kwotę * podatki itp. Ma to sens w sensie normalizacyjnym. Ale wtedy będziesz potrzebował pełnego zamknięcia wszystkich powiązanych rekordów. Weźmy na przykład tabelę produktów: Jeśli zmienisz cenę przed transakcją, należy wziąć pod uwagę, gdy transakcja ma miejsce. Ale jeśli cena zmieni się później, nie wpłynie to na transakcję.

Niedopuszczalne jest dołączenie do pliku transaction.product_id = products.id, ponieważ ten produkt może się zmienić. Przykład:

2012-01-01 price = 10 
2012-01-05 price = 20 
Transaction happens here, we sell 10 items so 10 * 20 = 200 
2012-01-06 price = 22 

Teraz odnośnika transakcję 2012-01-10, więc robimy:

SELECT 
    transactions.amount * products.price AS totalAmount 
FROM transactions 
INNER JOIN products on products.id=transactions.product_id 

To dałoby 10 * 22 = 220, więc nie jest poprawna.

Więc masz 2 opcje:

  1. Nie dopuszczać aktualizacje w tabeli produktów. Więc sprawisz, że ta tabela będzie wersjonowana, więc dla każdego rekordu dodajesz nowy WSTAW zamiast aktualizacji. Tak więc transakcja wskazuje na odpowiednią wersję produktu.

  2. Lub po prostu dodajesz pola do tabeli transakcji. Więc dodaj totalAmount do tabeli transakcji i oblicz ją (w transakcji bazy danych) po włożeniu transakcji i zapisz ją.

Tak, jest denormalized, ale ma dobry powód, czyni go odpowiedzialnym. Po prostu wiesz i to jest weryfikowane za pomocą transakcji, blokad itp.że w momencie, w którym doszło do transakcji, dotyczy on opisanego produktu z ceną = 20 itd.

Co więcej, jest to po prostu dobra rzecz denormalizacji, gdy trzeba to zrobić, bardzo łatwo jest uruchomić raporty. Całkowita kwota transakcji w miesiącu, roku itd. Wszystko to jest bardzo łatwe do obliczenia.

Normalizacja ma dobre strony, na przykład brak podwójnego przechowywania, pojedynczy punkt edycji itp. Ale w tym przypadku po prostu nie chcesz tego pomysłu, ponieważ nie jest to dozwolone i nie jest preferowane w przypadku bazy danych transakcji.

Zobacz transakcję jako rejestrację czegoś, co wydarzyło się w realnym świecie. Stało się, zapisałeś to. Teraz nie możesz zmienić historii, została napisana tak jak była. Przyszłość tego nie zmieni, stało się.

1

Celem normalizacji jest wyeliminowanie nadmiarowości, aby wyeliminować anomalie aktualizacji, głównie w systemach transakcyjnych. Relacyjne wciąż jest najlepszym rozwiązaniem do przetwarzania transakcji, DW, danych podstawowych i wielu rozwiązań BI. Większość NOSQL ma wymagania niskiej integralności. Więc tracisz mój tweet - denerwujący, ale nie katastrofalny. Ale stracić milion dolarów handlu akcjami jest dużym problemem. Wybór nie jest NOSQL kontra relacyjny. NOSQL robi pewne rzeczy bardzo dobrze. Ale Relational nigdzie się nie wybiera. To wciąż najlepszy wybór dla rozwiązań transakcyjnych, zorientowanych na aktualizację. Wymagania dotyczące normalizacji można poluzować, gdy dane są przeznaczone tylko do odczytu lub do odczytu. Właśnie dlatego redundancja nie jest tak wielkim problemem w DW; nie ma żadnych aktualizacji.

1

Mówisz tutaj o danych historycznych i finansowych. Powszechne jest przechowywanie niektórych obliczeń, które nigdy się nie zmienią, ponieważ jest to koszt, który został w danym momencie naliczony. Jeśli wykonasz kalkulację ceny produktu *, a cena zmieniła się 6 miesięcy po transakcji, to masz nieprawidłową wartość. Twój profesor jest mądry, słuchaj go. Co więcej, jeśli wykonujesz wiele raportów poza bazą danych, nie chcesz często obliczać wartości, które nie mogą zostać zmienione bez innego rekordu wprowadzania danych. Po co wykonywać obliczenia wiele razy w historii aplikacji, gdy potrzebujesz jej tylko raz? To marnotrawstwo cennych zasobów serwera.

+0

"Twój prefektor jest sprytny"? Być może ma szczęście, że ma rację w tym konkretnym zagadnieniu. Chociaż, oczywiście, IIRC, możesz rozwiązać problem z historyczną ceną/tabelą produktów i oprzeć na niej sumę płatności, co zwykle sprawia wiele kłopotów, więc po prostu zapisywanie faktycznych kwot płatności jest często używane. – reiniero

+0

Odnośnie twoich uwag na temat raportowania: masz rację, że raporty dbs często są denormalizowane, gdy transakcyjne dbs są. PO nie wspomniał, które z nich zostały zaprojektowane. Bez dalszych informacji zakładałabym transakcyjne ... – reiniero

+0

@reiniero, nawet transakcyjne bazy danych zawierają raport z nich. Mówię o rzeczach, które nie; często zmieniają i wymuszają to, ponieważ baza danych jest lepsza pod względem wydajności niż obliczanie jej, zwłaszcza jeśli obliczenie jej oznacza, że ​​otrzymasz błędną odpowiedź, ponieważ bieżąca cena nie jest ceną, która została naliczona. Temporal dat isa specialc ase w projektowaniu baz danych. To nie jest denormalizacja, aby wykonać tego rodzaju obliczenia na danych czasowych, aby mieć zapis tego, co zostało naładowane w momencie transakcji. – HLGEM

Powiązane problemy