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

Bagaimana merancang model data yang berhubungan dengan karyawan saat ini dan karyawan yang diperkirakan?

Saya dapat melihat beberapa alasan mengapa Anda memerlukan dua tabel untuk ini:

  • karyawan asli harus memiliki nama, departemen, dll, sedangkan karyawan prakiraan hanya boleh memiliki atribut ini
  • akan ada tanggung jawab yang hanya dapat dimiliki oleh karyawan sungguhan, jadi Anda ingin dapat merujuknya secara terpisah

Tetapi pada saat yang sama Anda ingin memastikan bahwa tidak ada bentrokan ID di kedua tabel, karena (semoga) perkiraan karyawan akan menjadi karyawan yang sebenarnya.

Cara untuk melakukannya adalah dengan mengimplementasikan struktur super-type/sub-type. Jadi, Anda memiliki satu tabel, EMPLOYEES yang menjamin satu kunci utama, dan dua tabel dependen untuk karyawan aktual dan prakiraan. Penggunaan kolom tipe sangat penting, karena memastikan bahwa karyawan tertentu hanya muncul dalam satu sub-tabel.

create table employees
    ( emp_id number not null
      , emp_type varchar2(8) not null
      , constraint emp_pk primary key (emp_id)
      , constraint emp_uk unique (emp_id, emp_type)
      , constraint emp_type_ck check (emp_type in ('FORECAST', 'ACTUAL'));

create table actual_employees
    ( emp_id number not null
      , emp_type varchar2(8) not null
      , name varchar2(30) not null
      , deptno number(2,0) not null
      , sal number(7,2) not null
      , hiredate date not null
      , constraint actemp_pk primary key (emp_id)
      , constraint actemp_type_ck check (emp_type = 'ACTUAL')
      , constraint actemp_emp_fk foreign key (emp_id, emp_type)
                   references emp (emp_id, emp_type) 
                   deferrable initially deferred ;

create table forecast_employees
    ( emp_id number not null
      , emp_type varchar2(8) not null
      , name varchar2(30) 
      , deptno number(2,0) 
      , sal number(7,2) 
      , predicted_joining_date date
      , constraint foremp_pk primary key (emp_id)
      , constraint foremp_type_ck check (emp_type = 'FORECAST')
      , constraint foremp_emp_fk foreign key (emp_id, emp_type)
                   references emp (emp_id, emp_type) 
                   deferrable initially deferred ;

Jadi kuncinya mungkin terlihat agak aneh. Tabel induk memiliki kunci utama dan kunci unik majemuk. Kunci utama menjamin satu instance EMP_ID. Kunci unik memungkinkan kita untuk membuat kunci asing pada tabel anak yang mereferensikan EMP_ID dan EMP_TYPE. Dikombinasikan dengan batasan pemeriksaan pada anak tIni karena mereka mereferensikan kunci unik pada tabel induk daripada kunci utamanya. memungkinkan pengaturan ini memastikan bahwa seorang karyawan dapat berada di FORECAST_EMPLOYEES atau ACTUAL_EMPLOYEES tetapi tidak keduanya.

Kunci asing dapat ditangguhkan untuk memungkinkan konversi karyawan prakiraan menjadi karyawan sebenarnya. Ini membutuhkan tiga aktivitas:

  1. menghapus catatan dari FORECAST_EMPLOYEES
  2. menyisipkan catatan ke ACTUAL_EMPLOYEES
  3. mengubah EMP_TYPE (tetapi tidak EMP_ID) di EMPLOYEES.

Menyinkronkan tindakan 2 dan 3 lebih mudah dengan batasan yang ditangguhkan.

Juga, perhatikan bahwa batasan kunci asing lainnya yang merujuk KARYAWAN harus menggunakan kunci utama daripada kunci unik. Jika hubungan peduli dengan tipe karyawan, maka hubungan tersebut mungkin harus ditautkan ke tabel anak.

Selamat datang di dunia pemodelan data. Ini salah satu sakit kepala besar. Karena mencoba memasukkan realitas yang berantakan ke dalam model data yang bersih itu sulit :Anda memerlukan persyaratan yang jelas untuk melakukannya dengan benar, dan pemahaman tentang apa yang paling penting sehingga Anda dapat membuat kompromi yang masuk akal.

Saya mengusulkan pendekatan tipe-super/sub-tipe berdasarkan pertanyaan Anda yang lain, dan karena itu tampaknya merupakan cara terbaik menangani dua set data:karyawan nyata dan karyawan nosional. Saya pikir kedua kelompok itu perlu diperlakukan secara berbeda. Misalnya, saya akan menuntut manajer menjadi karyawan sejati. Ini mudah dilakukan dengan batasan integritas terhadap ACTUAL_EMPLOYEES dan jauh lebih sulit untuk dicapai dengan satu tabel yang berisi kedua jenis karyawan.

Tentu memiliki dua tabel berarti mungkin menghasilkan lebih banyak pekerjaan terkait dengan sinkronisasi struktur mereka. Terus? Ini sebagian besar sepele, karena hampir tidak lebih banyak pekerjaan untuk menulis dua pernyataan ALTER TABLE daripada satu. Selain itu, sangat mungkin bahwa kolom baru hanya berlaku untuk karyawan yang sebenarnya dan tidak ada artinya untuk memperkirakan karyawan (mis. EARNED_COMMISSION, LAST_REVIEW_RATING). Karena itu, memiliki tabel terpisah membuat model data lebih akurat.

Sehubungan dengan keharusan menduplikasi tabel dependen, seperti yang ditunjukkan Ollie, itu adalah kesalahpahaman. Tabel yang berlaku untuk semua karyawan terlepas dari aktualitas mereka harus merujuk ke tabel EMPLOYEES bukan anak-anaknya.

Akhirnya saya tidak mengerti mengapa mempertahankan data historis lebih sulit dengan dua tabel daripada satu. Sebagian besar kode penjurnalan harus dihasilkan sepenuhnya dari kamus data.

Ada tiga tabel:

  • KARYAWAN - tabel master untuk menjamin EMP_ID unik
  • ACTUAL_EMPLOYEES - tabel anak untuk orang yang bekerja untuk perusahaan Anda
  • FORECAST_EMPLOYEES - tabel anak untuk orang-orang yang ingin Anda rekrut ke perusahaan Anda

Harap diingat bahwa saya membuat asumsi tentang logika bisnis Anda dari sedikit detail yang Anda berikan.

Sekarang menurut saya orang yang belum bekerja untuk perusahaan Anda seharusnya tidak memiliki aktivitas terkait. Dalam skenario itu Anda akan memiliki satu tabel, EMPLOYEE_ACTIVITIES, yang merupakan anak dari ACTUAL_EMPLOYEES.

Tetapi mungkin Anda benar-benar memiliki kegiatan untuk orang-orang yang tidak ada. Jadi, inilah pilihannya:satu atau dua meja? Desain satu tabel memiliki EMPLOYEE_TASKS sebagai anak dari tabel EMPLOYEES master. Dua desain tabel memiliki ACTUAL_EMPLOYEE_TASKS dan FORECAST_EMPLOYEE_TASKS sebagai anak dari tabel ACTUAL_EMPLOYEES dan FORECAST_EMPLOYEES masing-masing.

Desain mana yang benar tergantung pada apakah Anda perlu menegakkan aturan terkait penugasan tugas. Misalnya, perusahaan Anda mungkin memiliki aturan yang menyatakan bahwa hanya orang sungguhan yang dapat mempekerjakan staf baru. Jadi, akan berguna untuk memiliki model yang hanya mengizinkan tugas rekrutmen ditugaskan ke ACTUAL_EMPLOYEES.

Oke saya telah menambahkan kolom tanggal ke dua tabel. Itu akan memungkinkan Anda untuk menjalankan laporan yang Anda inginkan.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bidang dalam file data melebihi panjang maksimum - kesalahan

  2. Oracle REGEX_SUBSTR Tidak Menghormati nilai nol

  3. ORA-00979 bukan grup dengan ekspresi

  4. Apakah ODP.NET dapat didistribusikan kembali?

  5. Mengapa saya tidak bisa melakukan a dengan x sebagai (...) dengan ADODB dan Oracle?