sql >> Databáze >  >> RDS >> Oracle

Jak nejlépe spravovat historické vyhledávací hodnoty v databázi?

Existuje technika zvaná verzování, která existuje již mnoho let, ale z několika důvodů je z velké části nepoužitelná. Existuje však podobná technika, kterou nazývám Version Normal Form a kterou jsem shledal jako velmi užitečnou. Zde je příklad s použitím tabulky Zaměstnanci.

Nejprve je vytvořena statická tabulka. Toto je hlavní tabulka entit a obsahuje statická data o entitě. Statická data jsou data, u kterých se neočekává, že by se během životnosti entity změnily, jako je datum narození.

create table Employees(
  ID        int  auto_generated primary key,
  FirstName varchar( 32 ),
  Hiredate  date not null,
  TermDate  date,            -- last date worked
  Birthdate date,
  ...              -- other static data
);

Je důležité si uvědomit, že pro každého zaměstnance existuje jedna položka, stejně jako u každé takové tabulky.

Potom přidružená tabulka verzí. Tím se vytvoří 1-metrový vztah se statickou tabulkou, protože pro zaměstnance může existovat několik verzí.

create table Employee_versions(
  ID         int   not null,
  EffDate    date  not null,
  char( 1 )  IsWorking not null default true,
  LastName   varchar( 32 ),    -- because employees can change last name
  PayRate    currency not null,
  WorkDept   int   references Depts( ID ),
  ...,              -- other changable data
  constraint PK_EmployeeV primary key( ID, EffDate )
);

V poznámce k tabulce verzí je datum účinnosti, ale ne odpovídající pole, které již není účinné. Důvodem je to, že jakmile verze vstoupí v platnost, zůstane v platnosti, dokud nebude nahrazena následující verzí. Kombinace ID a EffDate musí být jedinečná, takže nemohou existovat dvě verze pro stejného zaměstnance, které jsou aktivní ve stejnou dobu, ani nemůže být mezera mezi koncem jedné verze a zahájením verze další.

Většina dotazů bude chtít znát aktuální verzi dat zaměstnanců. To je zajištěno spojením statického řádku pro zaměstnance s verzí, která je nyní platná. To lze nalézt pomocí následujícího dotazu:

select  ...
from    Employees e
join    Employee_versions v1
    on  v1.ID = e.ID
    and v1.EffDate =(
        select  Max( v2.EffDate )
        from    EmployeeVersions v2
        where   v2.ID = v1.ID
            and v2.EffDate <= NOW()
    )
where  e.ID = :EmpID;

Tím se vrátí jediná verze, která začala v poslední minulosti. Použití nerovnosti <=v kontrole data (v2.EffDate <= NOW() ) umožňuje datum účinnosti v budoucnosti. Předpokládejme, že víte, že nový zaměstnanec nastoupí první den příštího měsíce nebo že je na 13. dne příštího měsíce naplánováno zvýšení platu, lze tato data vložit předem. Takové "předem načtené" položky budou ignorovány.

Nedovolte, aby se k vám poddotaz dostal. Všechna vyhledávací pole jsou indexována, takže výsledek je poměrně rychlý.

Tento design nabízí velkou flexibilitu. Výše uvedený dotaz vrací nejnovější data všech zaměstnanců, současných i minulých. Můžete zkontrolovat TermDate pole získat právě přítomné zaměstnance. Ve skutečnosti, protože mnoho míst ve vašich aplikacích se bude zajímat pouze o aktuální informace o současných zaměstnancích, by tento dotaz poskytl dobrý přehled (vynechejte poslední where doložka). Aplikace nemusí ani vědět, že takové verze existují.

Pokud máte konkrétní datum a chcete zobrazit data, která byla v tu dobu platná, změňte v2.EffDate <= NOW() v dílčím dotazu na v2.EffDate <= :DateOfInterest .

Více podrobností lze nalézt v prezentaci zde a ne zcela dokončený dokument zde.

Chcete-li předvést trochu rozšiřitelnosti designu, všimněte si, že existuje IsWorking indikátor v tabulce verzí a také datum ukončení ve statické tabulce. Když zaměstnanec opustí společnost, do statické tabulky se vloží poslední datum a kopie nejnovější verze s IsWorking nastavit na false se vloží do tabulky verzí.

Je poměrně běžné, že zaměstnanci na nějakou dobu odejdou z firmy a pak jsou znovu přijati. Pouze s datem ve statické tabulce lze položku znovu aktivovat nastavením tohoto data zpět na NULL. Ale dotaz "ohlédnutí zpět" pro každou dobu, kdy osoba již nebyla zaměstnancem, by vrátil výsledek. Nic nenasvědčuje tomu, že ze společnosti odešli. Ale verze s IsWorking =false při odchodu ze společnosti a IsWorking =true při návratu do společnosti umožní kontrolu této hodnoty v době zájmu a ignoruje zaměstnance, kteří již nebyli zaměstnancem, i když se vrátili později.



  1. Ovlivní aktualizace SQL jeho poddotaz během běhu aktualizace?

  2. Změňte tabulku pro úpravu výchozí hodnoty sloupce

  3. Typ přetypování řetězce na celé číslo

  4. Jak zachovat pořadí vkládání na SQL Server