2009-10-15 30 views
8

Rozpocząłem nowy projekt i mają one bardzo znormalizowaną bazę danych. wszystko, co może być odnośnikiem, jest przechowywane jako klucz obcy w tabeli odnośników. to jest znormalizowane i dobrze, ale kończę robić 5 połączeń tabeli dla najprostszych zapytań.Denormalizacja dla zdrowia psychicznego lub wydajności?

from va in VehicleActions 
    join vat in VehicleActionTypes on va.VehicleActionTypeId equals vat.VehicleActionTypeId 
    join ai in ActivityInvolvements on va.VehicleActionId equals ai.VehicleActionId 
    join a in Agencies on va.AgencyId equals a.AgencyId 
    join vd in VehicleDescriptions on ai.VehicleDescriptionId equals vd.VehicleDescriptionId 
    join s in States on vd.LicensePlateStateId equals s.StateId 
    where va.CreatedDate > DateTime.Now.AddHours(-DateTime.Now.Hour) 
    select new {va.VehicleActionId,a.AgencyCode,vat.Description,vat.Code, 
vd.LicensePlateNumber,LPNState = s.Code,va.LatestDateTime,va.CreatedDate} 

Chciałbym polecić nam denormalizację niektórych rzeczy. jak kod państwa. Nie widzę zmian kodów stanu za mojego życia. podobna historia z 3-literowym kodem agencji. są one wydawane przez agencje agencji i nigdy się nie zmienią.

Kiedy zbliżyłem się do DBA z kwestią kodu stanu i 5 dołączeń do tabeli. otrzymuję odpowiedź, że "jesteśmy znormalizowani" i że "połączenia są szybkie".

Czy istnieje przekonujący argument do denormalizacji? Zrobiłbym to dla zdrowia, jeśli nic innego.

tej samej kwerendy w T-SQL:

SELECT VehicleAction.VehicleActionID 
     , Agency.AgencyCode AS ActionAgency 
     , VehicleActionType.Description 
     , VehicleDescription.LicensePlateNumber 
     , State.Code AS LPNState 
     , VehicleAction.LatestDateTime AS ActionLatestDateTime 
     , VehicleAction.CreatedDate 
FROM VehicleAction INNER JOIN 
    VehicleActionType ON VehicleAction.VehicleActionTypeId = VehicleActionType.VehicleActionTypeId INNER JOIN 
    ActivityInvolvement ON VehicleAction.VehicleActionId = ActivityInvolvement.VehicleActionId INNER JOIN 
    Agency ON VehicleAction.AgencyId = Agency.AgencyId INNER JOIN 
    VehicleDescription ON ActivityInvolvement.VehicleDescriptionId = VehicleDescription.VehicleDescriptionId INNER JOIN 
    State ON VehicleDescription.LicensePlateStateId = State.StateId 
Where VehicleAction.CreatedDate >= floor(cast(getdate() as float)) 
+0

+1. Dobre pytanie. – David

Odpowiedz

6

Nie wiem, czy mógłbym nawet nazwać to, co chcesz zrobić denormalizacji - wygląda bardziej na to, że po prostu chcesz zastąpić sztuczne klucze zagraniczne (StateId, AgencyId) naturalnymi kluczami zagranicznymi (Skrót Stanu, Kod Agencji) . Używanie pól varchar zamiast pól całkowitych spowolni działanie sprzężenia/zapytania, ale (a) jeśli nie musisz nawet dołączać do stołu przez większość czasu, ponieważ naturalne FK jest tym, czego chcesz, to nie jest wielka sprawa i (b) Twoja baza danych musiałaby być dość duża/mieć duże obciążenie, aby była zauważalna.

Ale djna ma rację, ponieważ potrzebna jest pełna wiedza na temat bieżących i przyszłych potrzeb przed wprowadzeniem takiej zmiany. Czy uważasz, że trzyliterowe kody agencji nigdy się nie zmienią, nawet za pięć lat? Naprawdę, naprawdę pewny?

+1

Byłem wielkim fanem elegancji, logiki i klarowności naturalnych kluczy obcych, ale one po prostu nie są warte ciągłych kłopotów z utrzymaniem. Zamiast tego stworzyłem eleganckie narzędzia do zarządzania sztucznymi kluczami i wszyscy są w domu na czas obiadu. – overslacked

3

ten poprzedni post do czynienia z podobnym problemie do tej, którą masz. Mam nadzieję, że będzie ci pomocna.

Dealing with "hypernormalized" data

Moje osobiste spojrzenie na normalizacji jest normalizacja jak najwięcej, ale denormalize tylko dla wydajności. I ewent. Denormalizacja wydajności jest czymś, czego należy unikać. Wybrałbym trasę profilowania, ustawiania poprawnych indeksów itp. Zanim zdenormalizuję.

Poczytalność ... To przereklamowane. Zwłaszcza w naszym zawodzie.

+0

+1 za dźwięk dźwięku "poczytalności". Umysł, jeśli czasami zacytuję cię? ;-) – sleske

+0

Wcale nie. Cytuj dalej. – David

6

Pewne denormalizacje mogą być potrzebne z powodów wydajności (i rozsądku) w niektórych momentach. Trudno powiedzieć bez wyświetlania wszystkich tabel/potrzeb itp.

Ale dlaczego nie po prostu zbudować kilka widoków wygody (zrobić kilka złączeń), a następnie użyć ich, aby móc pisać prostsze zapytania?

+1

+1 za pomysł poglądów ... Przydatna, prosta sugestia. – David

+0

Pomysł małych, prostych, wielokrotnego użytku funkcji powinien dotyczyć całego kodu, który mamy prawo, jeśli to możliwe. Dostaję wiele kilometrów z funkcji cenionych w tabelach i widoków takich rzeczy. A jako bonus, raportowanie staje się o wiele łatwiejsze. – overslacked

6

Uważaj na to, że chcesz kształtować rzeczy zgodnie z aktualnymi idiomami. W tej chwili nieznany kod wydaje się nieuczciwy i przeszkadza w zrozumieniu. Z czasem możliwe, że się zaaklimatyzujesz.

Jeśli bieżące (lub znane przyszłe) wymagania, takie jak wydajność, nie są spełnione, to zupełnie inny problem. Pamiętaj jednak, że wszystko może być dostrojone, celem nie jest robienie rzeczy tak szybko, jak to możliwe, ale szybkie ich ułożenie.

+1

+1 za wskazanie, że deweloperzy mają tendencję do wzrostu w czasie. Myślę, że w tej sytuacji lepiej nauczyć się radzić sobie z hiper-znormalizowanymi danymi i dostosowywać, a nie dostosowywać dane do tego, co nam odpowiada. – David

2

Argument (dla tej "normalizacji"), że trzyliterowe kody mogą ulec zmianie, nie jest bardzo przekonujący bez planu na to, co zrobisz, jeśli kody się zmienią, i jak twój sztuczny scenariusz zajmie się tym ewentualność lepsza niż używanie kodów jako kluczy. Jeśli nie wdrożyłeś w pełni schematu czasowego (który jest strasznie trudny do wykonania, a nie sugerowany przez twój przykład), nie jest dla mnie oczywiste, w jaki sposób twoja normalizacja przynosi ci korzyści. Teraz, jeśli pracujesz z agencjami z wielu źródeł i standardów, które mogą powodować kolizję nazw kodów, lub jeśli "stan" może w końcu oznaczać dwuliterowy kod dla stanu, prowincji, departamentu, kantonu lub estado, to już inna sprawa. Następnie potrzebujesz własnych kluczy lub potrzebujesz klucza dwukolumnowego z większą ilością informacji niż ten kod.

3

A co z występem? Jeśli wydajność jest w porządku, po prostu ustaw pięć stolików DOŁĄCZ do widoku i, dla zdrowia, WYBIERZ z widoku kiedy potrzebujesz danych.

Skróty stanu są jednym z przypadków, w których myślę, że sensowne klucze są w porządku. W przypadku bardzo prostych tabel wyszukiwania z ograniczoną liczbą wierszy i przy pełnej kontroli nad danymi (co oznacza, że ​​nie są one wypełniane z jakiegoś zewnętrznego źródła) czasami będę tworzyć znaczące cztery lub pięć klawiszy, tak aby kluczową wartością było proxy dla w pełni opisowej wartości wyszukiwania w niektórych zapytaniach.

3

Utwórz widok (lub wbudowaną funkcję wartości tabelarycznej, aby uzyskać parametryzację). W każdym razie zazwyczaj umieszczam cały mój kod w SP (generowany kod), niezależnie od tego, czy używają widoków, czy nie, i to jest to, że prawie zawsze piszesz link tylko raz.