Oracle
 sql >> база данни >  >> RDS >> Oracle

Как най-добре да управлявате исторически стойности за търсене в база данни?

Има техника, наречена версия на версиите, която съществува от много години, но до голяма степен е неизпълнима по няколко причини. Въпреки това, има подобна техника, която наричам Version Normal Form, която намирам за много полезна. Ето пример за използване на таблица за служители.

Първо се създава статичната таблица. Това е основната таблица с обекти и съдържа статични данни за обекта. Статичните данни са данни, които не се очаква да се променят по време на живота на субекта, като например рождена дата.

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

Важно е да разберете, че има един запис за всеки служител, точно както при всяка такава таблица.

След това свързаната таблица с версии. Това установява 1-метрова връзка със статичната таблица, тъй като може да има няколко версии за един служител.

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

В бележката към таблицата с версиите има дата на влизане в сила, но не съответстващо вече неефективно поле. Това е така, защото след като една версия влезе в сила, тя остава в сила, докато не бъде заменена от следващата версия. Комбинацията от ID и EffDate трябва да е уникална, така че не може да има две версии за един и същ служител, които да са активни едновременно, нито да има разлика между времето, когато едната версия приключва и когато стартира следващата версия.

Повечето заявки ще искат да знаят текущата версия на данните за служителите. Това се осигурява чрез присъединяване на статичния ред за служителя с версията, която е в сила в момента. Това може да бъде намерено със следната заявка:

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;

Това връща една и единствена версия, стартирана в най-близкото минало. Използване на неравенството <=в проверката на датата (v2.EffDate <= NOW() ) позволява дати на влизане в сила в бъдеще. Да предположим, че знаете, че нов служител ще започне на първия ден от следващия месец или е насрочено увеличение на заплатата за 13-то число на следващия месец, тези данни могат да бъдат въведени предварително. Такива „предварително заредени“ записи ще бъдат игнорирани.

Не позволявайте на подзаявката да стигне до вас. Всички полета за търсене са индексирани, така че резултатът е доста бърз.

Има голяма гъвкавост с този дизайн. Заявката по-горе връща най-новите данни за всички служители, настоящи и минали. Можете да проверите TermDate поле, за да получите само настоящи служители. Всъщност, тъй като много места във вашите приложения ще се интересуват само от текущата информация на настоящите служители, тази заявка ще направи добър изглед (пропуснете крайното where клауза). Няма нужда приложенията дори да знаят, че съществуват такива версии.

Ако имате конкретна дата и искате да видите данните, които са били в сила по това време, променете v2.EffDate <= NOW() в подзаявката към v2.EffDate <= :DateOfInterest .

Повече подробности можете да намерите в слайд презентация тук и не съвсем завършен документ тук.

За да покажете малко от разширяемостта на дизайна, забележете, че има IsWorking индикатор в таблицата с версиите, както и дата на прекратяване в статичната таблица. Когато служител напусне компанията, последната дата се вмъква в статичната таблица и копие на най-новата версия с IsWorking зададен на false се вмъква в таблицата с версиите.

Доста обичайно е служителите да напуснат компания за известно време, след което да бъдат наети отново. Само с датата в статичната таблица, записът може да бъде активиран отново, само като зададете тази дата обратно на NULL. Но заявка „поглед назад“ за всеки момент, когато лицето вече не е служител, ще върне резултат. Нямаше да има индикация, че са напуснали компанията. Но версия с IsWorking =false при напускане на фирмата и IsWorking =true при връщане в компанията ще позволи проверка на тази стойност в момента на интерес и ще игнорира служителите, когато вече не са били служител, дори ако се върнат по-късно.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Защо времето за изпълнение на съхранената процедура на Oracle се увеличава значително в зависимост от това как се изпълнява?

  2. Търсене на текст в съхранените процедури на Oracle

  3. SQLRecoverableException:Изключение за I/O:Нулиране на връзката

  4. Функция ROWIDTOCHAR() в Oracle

  5. Разделете стойностите, разделени със запетая, на колона в ред, чрез Oracle SQL заявка