it-swarm-id.com

Penggunaan Tabel Pencarian yang Benar

Saya mengalami kesulitan mencari tahu bagaimana cara menempatkan batas yang baik untuk kapan dan di mana menggunakan tabel pencarian dalam database. Sebagian besar sumber yang pernah saya lihat mengatakan bahwa saya tidak akan pernah memiliki terlalu banyak tetapi, pada titik tertentu, sepertinya basis data akan dipecah menjadi banyak bagian sehingga, walaupun mungkin efisien, ia tidak lagi dapat dikelola. Berikut adalah contoh bersama tentang apa yang saya kerjakan:

Katakanlah saya memiliki meja yang disebut Karyawan:

ID  LName   FName   Gender  Position
1   Doe     John    Male    Manager
2   Doe     Jane    Female  Sales
3   Smith   John    Male    Sales

Berpura-puralah sejenak bahwa datanya lebih kompleks dan berisi ratusan baris. Hal yang paling jelas saya lihat yang bisa dipindahkan ke tabel pencarian adalah Posisi. Saya bisa membuat tabel yang disebut Posisi dan menempelkan kunci asing dari tabel Posisi ke dalam tabel Karyawan di kolom Posisi.

ID  Position
1   Manager
2   Sales

Tapi seberapa jauh saya bisa terus memecah informasi menjadi tabel pencarian yang lebih kecil sebelum menjadi tidak terkelola? Saya bisa membuat tabel Jenis Kelamin dan memiliki 1 korespondensi untuk Pria dan 2 koresponden untuk Perempuan di tabel pencarian terpisah. Saya bahkan bisa memasukkan LNames dan FNames ke dalam tabel. Semua entri "John" diganti dengan kunci asing 1 yang menunjuk ke tabel FName yang mengatakan ID 1 sesuai dengan John. Jika Anda turun ke lubang kelinci ini terlalu jauh seperti ini, meja Karyawan Anda kemudian dikurangi menjadi berantakan kunci asing:

ID  LName   FName   Gender  Position
1   1       1       1       1
2   1       2       2       2
3   2       1       1       2

Walaupun ini mungkin atau mungkin tidak lebih efisien untuk diproses oleh server, ini tentu tidak dapat dibaca oleh orang normal yang mungkin mencoba untuk mempertahankannya dan membuatnya lebih sulit bagi pengembang aplikasi yang mencoba mengaksesnya. Jadi, pertanyaan saya yang sebenarnya adalah seberapa jauh terlalu jauh? Apakah ada "praktik terbaik" untuk hal semacam ini atau seperangkat pedoman yang baik di suatu tempat? Saya tidak dapat menemukan informasi online apa pun yang benar-benar menetapkan serangkaian pedoman yang baik dan dapat digunakan untuk masalah khusus yang saya alami ini. Desain basis data adalah topi lama bagi saya tetapi desain basis data yang bagus sangat baru sehingga jawaban teknis yang terlalu banyak mungkin ada di kepala saya. Bantuan apa pun akan dihargai!

25
Brad Turner

Tapi seberapa jauh saya bisa terus memecah informasi menjadi tabel pencarian yang lebih kecil sebelum menjadi tidak terkelola? Saya bisa membuat tabel Jenis Kelamin dan memiliki 1 korespondensi untuk Pria dan 2 koresponden untuk Perempuan di tabel pencarian terpisah.

Anda mencampur dua masalah berbeda. Salah satu masalah adalah penggunaan tabel "pencarian"; yang lainnya adalah penggunaan kunci pengganti (nomor id).

Mulailah dengan tabel ini.

ID  LName   FName   Gender  Position
1   Doe     John    Male    Manager
2   Doe     Jane    Female  Sales
3   Smith   John    Male    Sales

Anda dapat membuat tabel "pencarian" untuk posisi seperti ini.

create table positions (
  pos_name varchar(10) primary key
);

insert into positions
select distinct position 
from employees;

alter table employees
add constraint emp_fk1
foreign key (position) 
  references positions (pos_name);

Tabel asli Anda terlihat persis seperti sebelum membuat tabel "pencarian". Dan tabel karyawan mengharuskan no bergabung tambahan untuk mendapatkan data yang bermanfaat dan dapat dibaca manusia dari itu.

Menggunakan tabel "pencarian" bermuara di bawah ini: Apakah aplikasi Anda memerlukan kontrol atas nilai input yang disediakan oleh referensi kunci asing? Jika demikian, maka Anda selalu dapat menggunakan tabel "pencarian". (Terlepas dari apakah itu menggunakan kunci pengganti.)

Dalam beberapa kasus, Anda dapat mengisi tabel itu sepenuhnya pada waktu desain. Dalam kasus lain, pengguna harus dapat menambahkan baris ke tabel itu pada waktu berjalan. (Dan Anda mungkin perlu memasukkan beberapa proses administrasi untuk meninjau data baru.) Jenis kelamin, yang sebenarnya memiliki standar ISO , dapat diisi sepenuhnya pada waktu desain. Nama jalan untuk pesanan produk online internasional mungkin harus ditambahkan pada waktu berjalan.

Di tabel Karyawan Anda, saya hanya akan mencari "Posisi" karena ini adalah kumpulan data terbatas yang dapat diperluas.

  • Jenis kelamin menggambarkan diri sendiri (katakan M atau F), terbatas pada 2 nilai, dan dapat ditegakkan dengan kendala PERIKSA. Anda tidak akan menambahkan jenis kelamin baru (mengabaikan bollocks kebenaran politik)
  • Nama pertama "John" bukan bagian dari set data yang terbatas dan terbatas: kumpulan data potensial sangat besar hingga secara efektif tidak terbatas sehingga tidak boleh menjadi pencarian.

Jika Anda ingin menambahkan Posisi baru Anda cukup menambahkan baris ke tabel pencarian. Ini juga menghapus anomali modifikasi data yang merupakan salah satu titik normalisasi

Juga, sekali Anda memiliki sejuta karyawan maka itu lebih efisien untuk menyimpan Positionint tinyint daripada varchar.

Mari tambahkan kolom baru "mata uang gaji". Saya akan menggunakan tabel pencarian di sini dengan kunci CHF, GBP, EUR, USD dll: Saya tidak akan menggunakan kunci pengganti. Ini dapat dibatasi dengan batasan PERIKSA seperti Jenis Kelamin, tetapi ini adalah set data yang terbatas namun dapat diperluas seperti Posisi. Saya memberikan contoh ini karena saya akan menggunakan kunci alami bahkan jika itu muncul dalam sejuta baris data karyawan meskipun char (3) daripada tinyint

Jadi, untuk meringkas, Anda menggunakan tabel pencarian

  1. di mana Anda memiliki kumpulan data yang terbatas, namun dapat diperluas dalam sebuah kolom
  2. di mana tidak menggambarkan diri
  3. untuk menghindari anomali modifikasi data
8
gbn

Jawabannya adalah "itu tergantung". Tidak terlalu memuaskan tetapi ada banyak pengaruh mendorong dan menarik desain. Jika Anda memiliki pemrogram aplikasi yang mendesain database, struktur seperti yang Anda gambarkan berfungsi untuk mereka karena ORM menyembunyikan kerumitannya. Anda akan mencabut rambut Anda ketika Anda menulis laporan dan harus bergabung dengan sepuluh tabel untuk mendapatkan alamat.

Desain untuk penggunaan, penggunaan yang dimaksudkan, dan kemungkinan penggunaan di masa depan. Di sinilah pengetahuan Anda tentang proses bisnis masuk. Jika Anda mendesain database untuk bisnis veteriner, ada asumsi yang masuk akal tentang ukuran, penggunaan, dan arah fungsionalitas yang akan sangat berbeda dari permulaan teknologi tinggi.

Untuk menggunakan kembali kutipan favorit

"Orang bijak pernah mengatakan kepada saya" normalkan sampai sakit, denormalkan sampai bekerja ".

Di suatu tempat ada sweet spot. Pengalaman saya adalah bahwa memiliki id kunci di lebih dari satu tabel bukanlah kejahatan yang serius seperti yang dipikirkan beberapa orang jika Anda tidak pernah mengubah kunci primer.

Ambil contoh singkat dari tabel yang sangat dinormalisasi ini dari sistem nyata

CREATE TABLE PROPERTY
(ID                          NUMBER(9)           NOT NULL);

CREATE TABLE PROPERTY_TYPE
(ID                          NUMBER(9)           NOT NULL);

CREATE TABLE PROPERTY_LOCALE 
PROPERTY_ID                  NUMBER(9)           NOT NULL,
(LOCALE_ID                   NUMBER(9)           NOT NULL,  --language 
VALUE                        VARCHAR2(200)       NOT NULL);

CREATE TABLE PROPERTY_DEPENDENCY
(PROPERTY_ID                 NUMBER(9)           NOT NULL,
 PARENT_PROPERTY_ID          NUMBER(9)                   ,
 PROPERTY_TYPE_ID            NUMBER(9)           NOT NULL);

Tabel-tabel ini mengatur daftar properti tunggal dan properti anak induk yang ditautkan dan mereka digunakan di sini

  CREATE TABLE CASE_PROPERTY
  (ID                        NUMBER(9)           NOT NULL,
  PARENT_ID                  NUMBER(9),
  CASE_ID                    NUMBER(9)           NOT NULL,
  PROPERTY_ID                NUMBER(9),
  PROPERTY_TYPE_ID           NUMBER(9)           NOT NULL);

Ini terlihat bagus: dapatkan semua case dengan property_id dalam satu pilihan

Mari kita ambil daftar untuk dipilih

 Select pl.value, pd.property_id
 from property_locale pl, property_dependency pd
 where pl.property_id = pd.property_id
 and pd.property_type_id = 2;  --example number

Sekarang coba pilih semua properti dari case jika memiliki property_types dari 3 dan 4 dan 5, atau tidak ...

SELECT   cp2.case_id,
         (SELECT   pl.VALUE
            FROM   case_property cp, property_locale pl
           WHERE       cp.property_id = pl.property_id
                   AND CP.PROPERTY_TYPE_ID = 2
                   AND pl.locale_id = 2
                   AND cp.case_id = cp2.case_id)
            AS VALUE1,
         (SELECT   pl.VALUE
            FROM   case_property cp, property_locale pl
           WHERE       cp.property_id = pl.property_id
                   AND CP.PROPERTY_TYPE_ID = 34
                   AND pl.locale_id = 2
                   AND cp.case_id = cp2.case_id)
            AS VALUE2,
         (SELECT   pl.VALUE
            FROM   case_property cp, property_locale pl
           WHERE       cp.property_id = pl.property_id
                   AND CP.PROPERTY_TYPE_ID = 4
                   AND pl.locale_id = 2
                   AND cp.case_id = cp2.case_id)
            AS VALUE3
  FROM   case_property cp2
 WHERE   cp2.case_id = 10293  

Ini hanya menyakitkan ... bahkan ketika Anda menggunakan cara yang lebih elegan untuk menangani ini. Namun, tambahkan sedikit de normalisasi dengan memecah properti yang memiliki case hanya memiliki satu property_id dan ini bisa menjadi jauh lebih baik.

Untuk mencari tahu kapan Anda memiliki terlalu banyak tabel atau tidak cukup mencoba menanyakan database dengan pertanyaan aplikasi, laporan dan analisis tahun ke tahun akan digunakan.

5
kevinsky