Mám potíže přijít na to, jak přesně stanovit, kdy a kde použít vyhledávací tabulky v databázi. Většina zdrojů, na které jsem se podíval, říká, že nikdy nemám příliš mnoho, ale v určitém okamžiku se zdá, že by se databáze rozčlenila na tolik kusů, že i když to může být efektivní, není již možné spravovat. Zde je uveden společný příklad toho, s čím pracuji:
Řekněme, že mám tabulku s názvem Zaměstnanci:
ID LName FName Gender Position
1 Doe John Male Manager
2 Doe Jane Female Sales
3 Smith John Male Sales
Předstírejte, že data jsou složitější a obsahují stovky řádků. Nejviditelnější věcí, kterou vidím, že by se dalo přesunout na vyhledávací stůl, by byla Pozice. Mohl bych vytvořit tabulku nazvanou Pozice a vložit cizí klíče z tabulky Pozice do tabulky Zaměstnanci ve sloupci Pozice.
ID Position
1 Manager
2 Sales
Ale jak daleko mohu pokračovat v rozdělování informací na menší vyhledávací tabulky, než se stanou nezvládnutelnými? Mohl bych vytvořit tabulku Pohlaví a mít 1 korespondenci s mužem a 2 odpovídat ženě v samostatné vyhledávací tabulce. Dokonce jsem mohl dát LNames a FNames do tabulek. Všechny položky „John“ jsou nahrazeny cizím klíčem 1, který ukazuje na tabulku FName, která říká, že ID 1 odpovídá Johnovi. Pokud však tuto králičí díru sestoupíte příliš daleko, váš stůl Zaměstnanců se pak zmenší na nepořádek cizích klíčů:
ID LName FName Gender Position
1 1 1 1 1
2 1 2 2 2
3 2 1 1 2
I když to může nebo nemusí být efektivnější pro zpracování serveru, je to určitě nečitelné pro normální osobu, která se možná snaží udržet ji a ztěžuje to vývojáři aplikace, který se k ní snaží získat přístup. Moje skutečná otázka tedy zní, jak daleko je příliš daleko? Existují pro tento druh věcí „osvědčené postupy“ nebo někde dobrá sada pokynů? Nemohu najít žádné informace online, které by opravdu přinesly dobrý, použitelný soubor pokynů pro tento konkrétní problém, který mám. Návrh databáze je pro mě starým kloboukem, ale DOBRÝ návrh databáze je velmi nový, takže nad mou hlavou mohou být příliš technické odpovědi. Jakákoli pomoc by byla oceněna!
Ale jak daleko mohu pokračovat v rozdělování informací na menší vyhledávací tabulky, než se stanou nezvládnutelnými? Mohl bych vytvořit tabulku Pohlaví a mít 1 korespondenci s mužem a 2 odpovídat ženě v samostatné vyhledávací tabulce.
Mícháte dva různé problémy. Jedním problémem je použití tabulky „vyhledávání“; druhým je použití náhradních klíčů (identifikačních čísel).
Začněte touto tabulkou.
ID LName FName Gender Position
1 Doe John Male Manager
2 Doe Jane Female Sales
3 Smith John Male Sales
Pro takovéto pozice můžete vytvořit tabulku vyhledávání.
create table positions (
pos_name varchar(10) primary key
);
insert into positions
select distinct position
from employees;
alter table employees
add constraint emp_fk1
foreign key (position)
references positions (pos_name);
Vaše původní tabulka vypadá přesně jako před vytvořením tabulky vyhledávání. A tabulka zaměstnanců vyžaduje žádné další spojení, aby z nich byla získána užitečná, lidsky čitelná data.
Pomocí tabulky „vyhledávání“ se toto sníží: Vyžaduje vaše aplikace kontrolu nad vstupními hodnotami, které poskytuje reference cizího klíče? Pokud ano, můžete vždy použít tabulku vyhledávání. (Bez ohledu na to, zda používá náhradní klíč.)
V některých případech budete moci tuto tabulku naplnit v době návrhu. V ostatních případech musí být uživatelé schopni přidat řádky do této tabulky za běhu. (A pravděpodobně budete muset zahrnout některé administrativní procesy, abyste mohli zkontrolovat nová data.) Pohlaví, které má ve skutečnosti norma ISO , může být v době návrhu zcela naplněno. Názvy ulic pro mezinárodní online objednávky produktů je pravděpodobně nutné přidat za běhu.
V tabulce Zaměstnanci bych vyhledal pouze „Pozici“, protože se jedná o omezený soubor dat, který lze rozšířit.
M
nebo F
), je omezeno na 2 hodnoty a může být vynuceno omezením CHECK. Nebudete přidávat nové pohlaví (ignorování blokování politické korektnosti)Pokud chcete přidat novou pozici, jednoduše přidejte řádek do vyhledávací tabulky. To také odstraní anomálie úpravy dat , což je jeden bod normalizace
Jakmile budete mít milion zaměstnanců, pak je efektivnější uložit tinyint PositionID než varchar.
Přidejme nový sloupec „platová měna“. Použil bych zde vyhledávací tabulku s klíčem CHF, GBP, EUR, USD atd.: Nepoužil bych náhradní klíč. To by mohlo být omezeno omezením CHECK jako Gender, ale je to omezená, ale rozšiřitelná sada dat, jako je Position. Uvedu tento příklad, protože bych použil přirozený klíč, i když se objeví v milionech řádků údajů o zaměstnancích, přestože je char (3), spíše než tinyint
Pro shrnutí tedy použijete vyhledávací tabulky
Odpověď zní „záleží“. Není to příliš uspokojivé, ale existuje mnoho vlivů, které tlačí a táhnou design. Pokud máte programátory aplikací, kteří navrhují databázi, struktura, jako jste popsali, pro ně funguje, protože ORM skrývá složitost. Když píšete zprávy, vytrhnete si vlasy a musíte se připojit k deseti stolům, abyste získali adresu.
Konstrukce pro použití, zamýšlené použití a pravděpodobné budoucí použití. Zde přichází vaše znalost obchodního procesu. Pokud navrhujete databázi pro veterinární firmu, existují rozumné předpoklady o velikosti, použití a směrech funkčnosti, které budou zcela odlišné od high-tech start-up.
Chcete-li znovu použít oblíbenou nabídku
Někde tam je sladké místo. Moje zkušenost byla taková, že mít identifikátor klíče ve více než jedné tabulce není tak závažný zločin, jak si někteří myslí, pokud nikdy nezměníte primární klíče.
Vezměte tento zkrácený příklad vysoce normalizovaných tabulek ze skutečného systému
CREATE TABLE PROPERTY
(ID NUMBER(9) NOT NULL);
CREATE TABLE PROPERTY_TYPE
(ID NUMBER(9) NOT NULL);
CREATE TABLE PROPERTY_LOCALE
PROPERTY_ID NUMBER(9) NOT NULL,
(LOCALE_ID NUMBER(9) NOT NULL, --language
VALUE VARCHAR2(200) NOT NULL);
CREATE TABLE PROPERTY_DEPENDENCY
(PROPERTY_ID NUMBER(9) NOT NULL,
PARENT_PROPERTY_ID NUMBER(9) ,
PROPERTY_TYPE_ID NUMBER(9) NOT NULL);
Tyto tabulky nastavují propojený seznam jednotlivých vlastností a nadřazených podřízených vlastností a zde si zvyknou
CREATE TABLE CASE_PROPERTY
(ID NUMBER(9) NOT NULL,
PARENT_ID NUMBER(9),
CASE_ID NUMBER(9) NOT NULL,
PROPERTY_ID NUMBER(9),
PROPERTY_TYPE_ID NUMBER(9) NOT NULL);
To vypadá dobře: získejte všechny případy pomocí vlastnosti property_id v jednom výběru
Pojďme si vybrat seznam
Select pl.value, pd.property_id
from property_locale pl, property_dependency pd
where pl.property_id = pd.property_id
and pd.property_type_id = 2; --example number
Nyní zkuste vybrat všechny vlastnosti případu, pokud má vlastnost_typy 3 a 4 a 5, nebo ne ...
SELECT cp2.case_id,
(SELECT pl.VALUE
FROM case_property cp, property_locale pl
WHERE cp.property_id = pl.property_id
AND CP.PROPERTY_TYPE_ID = 2
AND pl.locale_id = 2
AND cp.case_id = cp2.case_id)
AS VALUE1,
(SELECT pl.VALUE
FROM case_property cp, property_locale pl
WHERE cp.property_id = pl.property_id
AND CP.PROPERTY_TYPE_ID = 34
AND pl.locale_id = 2
AND cp.case_id = cp2.case_id)
AS VALUE2,
(SELECT pl.VALUE
FROM case_property cp, property_locale pl
WHERE cp.property_id = pl.property_id
AND CP.PROPERTY_TYPE_ID = 4
AND pl.locale_id = 2
AND cp.case_id = cp2.case_id)
AS VALUE3
FROM case_property cp2
WHERE cp2.case_id = 10293
To jen bolí ... i když použijete elegantnější způsoby, jak se s tím vypořádat. Nicméně přidejte trochu de normalizace rozdělením vlastností, pro které bude mít případ pouze jeden název_ vlastnosti a to by mohlo být mnohem lepší.
Chcete-li zjistit, kdy máte příliš mnoho tabulek nebo není dostatek, zkuste dotazovat databázi otázkami, které aplikace použije, sestavu a roční analýzu.