Neprovedl jsem formální studii, ale z vlastní zkušenosti bych odhadl, že více než 80 % nedostatků v návrhu databáze je generováno návrhem s výkonem jako nejdůležitějším (ne-li jediným) hlediskem.
Pokud dobrý návrh vyžaduje více tabulek, vytvořte více tabulek. Nepředpokládejte automaticky, že spojení je něco, čemu je třeba se vyhnout. Jen zřídka jsou skutečnou příčinou problémů s výkonem.
Primárním hlediskem, a to především ve všech fázích návrhu databáze, je integrita dat. „Odpověď nemusí být vždy správná, ale můžeme vám ji dostat velmi rychle“ není cíl, ke kterému by měl každý obchod pracovat. Jakmile bude integrita dat uzamčena, pokud se někdy výkon stane problémem , dá se to řešit. Neobětujte integritu dat, zejména při řešení problémů, které nemusí existovat.
S ohledem na to se podívejte na to, co potřebujete. Máte pozorování, která si musíte uložit. Tato pozorování se mohou lišit v počtu a typech atributů a mohou to být věci, jako je hodnota měření, upozornění na událost a změna stavu, mimo jiné a s možností přidávat budoucí pozorování.
Zdá se, že to zapadá do standardního vzoru „typ/podtyp“, přičemž položka „Pozorování“ je typem a každý typ nebo druh pozorování je podtypem a navrhuje určitou formu pole indikátoru typu, například:
create table Observations(
...,
ObservationKind char( 1 ) check( ObservationKind in( 'M', 'E', 'S' )),
...
);
Ale napevno zakódování seznamu jako je tento v kontrolním omezení má velmi nízkou úroveň udržovatelnosti. Stává se součástí schématu a lze jej změnit pouze pomocí příkazů DDL. Není to něco, na co se váš DBA bude těšit.
Mějte tedy druhy pozorování v jejich vlastní vyhledávací tabulce:
ID Name Meaning
== =========== =======
M Measurement The value of some system metric (CPU_Usage).
E Event An event has been detected.
S Status A change in a status has been detected.
(Pole char by stejně tak mohlo být int nebo smallint. Pro ilustraci zde používám char.)
Poté vyplňte tabulku Observations s PK a atributy, které by byly společné pro všechna pozorování.
create table Observations(
ID int identity primary key,
ObservationKind char( 1 ) not null,
DateEntered date not null,
...,
constraint FK_ObservationKind foreign key( ObservationKind )
references ObservationKinds( ID ),
constraint UQ_ObservationIDKind( ID, ObservationKind )
);
Může se zdát divné vytvořit jedinečný index na kombinaci pole Kind a PK, který je sám o sobě jedinečný, ale mějte chvilku se mnou.
Nyní každý druh nebo podtyp dostane svou vlastní tabulku. Všimněte si, že každý druh pozorování dostane tabulku, nikoli datový typ.
create table Measurements(
ID int not null,
ObservationKind char( 1 ) check( ObservationKind = 'M' ),
Name varchar( 32 ) not null, -- Such as "CPU Usage"
Value double not null, -- such as 55.00
..., -- other attributes of Measurement observations
constraint PK_Measurements primary key( ID, ObservationKind ),
constraint FK_Measurements_Observations foreign key( ID, ObservationKind )
references Observations( ID, ObservationKind )
);
První dvě pole budou stejná pro ostatní druhy pozorování kromě toho, že kontrolní omezení vynutí hodnotu na příslušný druh. Ostatní pole se mohou lišit číslem, názvem a typem dat.
Podívejme se na příklad n-tice, který může existovat v tabulce měření:
ID ObservationKind Name Value ...
==== =============== ========= =====
1001 M CPU Usage 55.0 ...
Aby tato n-tice existovala v této tabulce, musí nejprve existovat odpovídající položka v tabulce Pozorování s hodnotou ID 1001 a hodnotou druhu pozorování 'M'. Žádná jiná položka s hodnotou ID 1001 nemůže existovat ani v tabulce Pozorování, ani v tabulce Měření a nemůže existovat vůbec v žádné jiné z „druhových“ tabulek (Události, Stav). Toto funguje stejným způsobem pro všechny druhy tabulek.
Dále bych doporučil vytvořit pohled pro každý druh pozorování, který poskytne spojení každého druhu s hlavní tabulkou pozorování:
create view MeasurementObservations as
select ...
from Observations o
join Measurements m
on m.ID = o.ID;
Jakýkoli kód, který pracuje pouze s měřeními, by musel zasáhnout pouze toto zobrazení namísto podkladových tabulek. Použití pohledů k vytvoření stěny abstrakce mezi kódem aplikace a nezpracovanými daty výrazně zlepšuje udržovatelnost databáze.
Nyní vytvoření jiného druhu pozorování, jako je "Error", zahrnuje jednoduchý příkaz Insert do tabulky ObservationKinds:
F Fault A fault or error has been detected.
Samozřejmě musíte vytvořit novou tabulku a pohled pro tato pozorování chyb, ale to nebude mít žádný dopad na existující tabulky, pohledy nebo kód aplikace (samozřejmě kromě psaní nového kódu pro práci s novými pozorováními) .