Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Bagaimana cara terbaik mengelola nilai pencarian historis dalam database?

Ada teknik yang disebut pembuatan versi yang telah ada selama bertahun-tahun tetapi sebagian besar tidak dapat diterapkan karena beberapa alasan. Namun, ada teknik serupa yang saya sebut sebagai Bentuk Normal Versi yang menurut saya sangat berguna. Berikut adalah contoh penggunaan tabel Karyawan.

Pertama, tabel statis dibuat. Ini adalah tabel entitas utama dan berisi data statis tentang entitas. Data statis adalah data yang diperkirakan tidak akan berubah selama umur entitas, seperti tanggal lahir.

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

Penting untuk menyadari bahwa ada satu entri untuk setiap karyawan, seperti halnya tabel semacam itu.

Kemudian tabel versi terkait. Ini menetapkan hubungan 1-m dengan tabel statis karena mungkin ada beberapa versi untuk seorang karyawan.

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

Dalam catatan tabel versi ada tanggal efektif tetapi bukan bidang yang tidak lagi efektif yang cocok. Ini karena setelah versi berlaku, itu tetap berlaku sampai digantikan oleh versi berikutnya. Kombinasi ID dan EffDate harus unik sehingga tidak boleh ada dua versi untuk karyawan yang sama yang aktif secara bersamaan, juga tidak boleh ada jarak antara waktu satu versi berakhir dan saat versi berikutnya dimulai.

Sebagian besar kueri ingin mengetahui versi data karyawan saat ini. Ini disediakan dengan menggabungkan baris statis untuk karyawan dengan versi yang berlaku sekarang. Ini dapat ditemukan dengan kueri berikut:

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;

Ini mengembalikan satu-satunya versi yang dimulai di masa lalu. Menggunakan pertidaksamaan <=pada pemeriksaan tanggal (v2.EffDate <= NOW() ) memungkinkan tanggal efektif di masa mendatang. Misalkan Anda tahu seorang karyawan baru akan mulai pada hari pertama bulan depan atau kenaikan gaji dijadwalkan pada tanggal 13 bulan depan, data ini dapat dimasukkan sebelumnya. Entri "pramuat" tersebut akan diabaikan.

Jangan biarkan subquery menguasai Anda. Semua bidang pencarian diindeks sehingga hasilnya cukup cepat.

Ada banyak fleksibilitas dengan desain ini. Kueri di atas mengembalikan data terbaru dari semua karyawan, sekarang dan sebelumnya. Anda dapat memeriksa TermDate lapangan untuk mendapatkan karyawan yang baru saja hadir. Faktanya, karena banyak tempat di aplikasi Anda hanya akan tertarik dengan info terkini dari karyawan saat ini, kueri itu akan menjadi tampilan yang bagus (hilangkan where akhir ayat). Tidak perlu aplikasi untuk mengetahui versi seperti itu ada.

Jika Anda memiliki tanggal tertentu dan ingin melihat data yang berlaku efektif pada saat itu, ubah v2.EffDate <= NOW() dalam subkueri ke v2.EffDate <= :DateOfInterest .

Detail lebih lanjut dapat ditemukan dalam presentasi slide di sini dan dokumen yang tidak lengkap di sini.

Untuk memamerkan sedikit ekstensibilitas desain, perhatikan ada IsWorking indikator di tabel versi serta tanggal penghentian di tabel statis. Ketika seorang karyawan meninggalkan perusahaan, tanggal terakhir dimasukkan ke dalam tabel statis dan salinan versi terbaru dengan IsWorking setel ke false dimasukkan ke dalam tabel versi.

Cukup umum bagi karyawan untuk meninggalkan perusahaan untuk sementara waktu kemudian dipekerjakan lagi. Dengan hanya tanggal di tabel statis, entri dapat diaktifkan kembali hanya dengan mengatur tanggal itu kembali ke NULL. Tetapi kueri "lihat ke belakang" untuk setiap saat ketika orang tersebut tidak lagi menjadi karyawan akan memberikan hasil. Tidak akan ada indikasi bahwa mereka telah meninggalkan perusahaan. Tapi versi dengan IsWorking =false saat keluar dari perusahaan dan IsWorking =true saat kembali ke perusahaan akan mengizinkan pemeriksaan nilai tersebut pada saat menarik dan mengabaikan karyawan saat mereka bukan lagi karyawan meskipun mereka kembali lagi nanti.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Permintaan parameter dalam masalah Oracle

  2. Bagaimana cara menghapus duplikat dari daftar yang dipisahkan koma oleh regexp_replace di Oracle?

  3. TANH() Fungsi di Oracle

  4. ORA-01017 Nama Pengguna/Kata Sandi Tidak Valid saat menghubungkan ke database 11g dari klien 9i

  5. Apakah ada operator Oracle yang lebih baik untuk melakukan pemeriksaan kesetaraan nol-aman?