it-swarm-eu.dev

Správné používání vyhledávacích tabulek

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!

25
Brad Turner

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.

  • Pohlaví samo popisuje (řekněme 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)
  • Křestní jméno „John“ není součástí omezené, omezené sady dat: potenciální sada dat je masivní do té míry, že je skutečně neomezená, takže by nemělo být vyhledáváním.

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

  1. kde máte ve sloupci konečná, ale rozšiřitelná data sady
  2. kde se nepopisuje
  3. vyhnout se anomálie úpravy dat
8
gbn

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

"Moudří člověk mi jednou řekl," normalizujte, dokud to nebude bolet, denormalizujte, dokud to nebude fungovat ".

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.

5
kevinsky