Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Jak najlepiej zarządzać historycznymi wartościami wyszukiwania w bazie danych?

Istnieje technika zwana wersjonowaniem, która istnieje od wielu lat, ale jest w dużej mierze niewykonalna z kilku powodów. Istnieje jednak podobna technika, którą nazywam Wersją Normalną Formą, która okazała się bardzo przydatna. Oto przykład użycia tabeli Pracownicy.

Najpierw tworzona jest tabela statyczna. To jest główna tabela encji i zawiera statyczne dane o encji. Dane statyczne to dane, które nie powinny ulec zmianie w trakcie życia jednostki, takie jak data urodzenia.

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
);

Ważne jest, aby zdać sobie sprawę, że dla każdego pracownika jest jeden wpis, tak jak w przypadku każdej takiej tabeli.

Następnie powiązana tabela wersji. Ustanawia to 1-metrową relację ze statyczną tabelą, ponieważ może istnieć kilka wersji dla pracownika.

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 )
);

W uwadze do tabeli wersji znajduje się data wejścia w życie, ale nie ma pasującego pola, które już nie obowiązuje. Dzieje się tak, ponieważ gdy wersja zacznie obowiązywać, pozostaje ona w mocy, dopóki nie zostanie zastąpiona przez kolejną wersję. Kombinacja ID i EffDate musi być unikalna, więc nie może być dwóch wersji dla tego samego pracownika, które są aktywne w tym samym czasie, ani nie może być przerwy między końcem jednej wersji a rozpoczęciem następnej.

Większość zapytań będzie chciała znać aktualną wersję danych pracowników. Jest to zapewnione przez połączenie statycznego wiersza dla pracownika z wersją, która teraz obowiązuje. Można to znaleźć za pomocą następującego zapytania:

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;

Zwraca to jedyną wersję, która rozpoczęła się w najnowszej przeszłości. Użycie nierówności <=w sprawdzaniu daty (v2.EffDate <= NOW() ) pozwala na wprowadzenie dat w przyszłości. Załóżmy, że wiesz, że nowy pracownik rozpocznie pracę pierwszego dnia następnego miesiąca lub podwyżka jest zaplanowana na 13 dnia następnego miesiąca, te dane można wstawić z wyprzedzeniem. Takie „wstępnie załadowane” wpisy będą ignorowane.

Nie pozwól, aby podzapytanie do Ciebie dotarło. Wszystkie pola wyszukiwania są indeksowane, więc wynik jest dość szybki.

Ten projekt zapewnia dużą elastyczność. Powyższe zapytanie zwraca najnowsze dane wszystkich pracowników, obecnych i przeszłych. Możesz sprawdzić TermDate pole, aby zdobyć tylko obecnych pracowników. W rzeczywistości, ponieważ wiele miejsc w twoich aplikacjach będzie zainteresowanych tylko bieżącymi informacjami o obecnych pracownikach, to zapytanie będzie stanowić dobry widok (pomiń końcowe where klauzula). Aplikacje nie muszą nawet wiedzieć o istnieniu takich wersji.

Jeśli masz konkretną datę i chcesz zobaczyć dane, które obowiązywały w tym czasie, zmień v2.EffDate <= NOW() w podzapytaniu do v2.EffDate <= :DateOfInterest .

Więcej szczegółów można znaleźć w prezentacji slajdów tutaj i nie do końca wypełnionym dokumencie tutaj.

Aby pokazać odrobinę rozszerzalności projektu, zauważ, że istnieje IsWorking wskaźnik w tabeli wersji oraz data zakończenia w tabeli statycznej. Kiedy pracownik opuszcza firmę, ostatnia data jest wstawiana do tabeli statycznej i kopia najnowszej wersji z IsWorking ustaw na false zostanie wstawiony do tabeli wersji.

Często zdarza się, że pracownicy opuszczają firmę na jakiś czas, a następnie zostają ponownie zatrudnieni. Mając tylko datę w tabeli statycznej, wpis można aktywować ponownie, ustawiając tę ​​datę z powrotem na NULL. Ale zapytanie „spojrzenie wstecz” za dowolny czas, gdy dana osoba nie była już pracownikiem, zwróciłoby wynik. Nic nie wskazywało na to, że opuścili firmę. Ale wersja z IsWorking =false przy opuszczeniu firmy i IsWorking =true, gdy powrót do firmy umożliwi sprawdzenie tej wartości w momencie zainteresowania i zignorowanie pracowników, którzy nie byli już pracownikami, nawet jeśli wrócili później.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. cx_Oracle nie łączy się podczas używania SID zamiast nazwy usługi w ciągu połączenia

  2. Dopasowywanie wartości zduplikowanych kolumn Oracle za pomocą Soundex, Jaro Winkler i Edit Distance (UTL_MATCH)

  3. Jak utrwalać DUŻE BLOBy (>100 MB) w Oracle przy użyciu Hibernate

  4. Jak wyodrębnić tylko wartość daty z pola daty w Oracle?

  5. Tłumaczenie Microsoft T-SQL na Oracle SQL