Apakah hubungan satu-ke-satu dinormalisasi?

12

Anggap kita memiliki satu set besar data statistik untuk suatu catatan; mis. 20-30 INTkolom. Apakah lebih baik menyimpan seluruh set dalam satu tabel karena semuanya milik catatan ATAU membuat tabel lain yang terhubung dengan hubungan satu-ke-satu.

Keuntungan dari yang pertama adalah untuk menghindari JOINdan memiliki akses cepat ke semua data statistik untuk catatan yang sesuai.

Keuntungan yang terakhir adalah menjaga agar kolom tetap rapi. Kolom pertama adalah intensif baca, dan intensif menulis kedua. Tentu saja, saya pikir itu tidak berpengaruh signifikan pada kinerja, karena saya menggunakan InnoDB dengan pemblokiran level-baris.

Secara umum saya ingin tahu apakah praktis berguna untuk memisahkan set data yang berbeda untuk satu catatan?

Googlebot
sumber
2
'Normalisasi' berarti bentuk normal pertama (1NF) dan merupakan persyaratan mendasar dari model relasional. 'Sepenuhnya dinormalisasi' berarti 5NF atau lebih tinggi. Tabel 'hubungan satu-ke-satu' yang Anda usulkan memiliki peluang lebih baik untuk berada dalam bentuk normal yang lebih tinggi (mungkin bahkan dalam 6NF) daripada yang Anda miliki saat ini karena terurai! Bentuk normal apa yang memuaskan tabel Anda saat ini?
onedaywhen
@onedaywhen Seperti banyak orang lain saya tidak mengikuti normalisasi langkah demi langkah, karena kadang-kadang de-normalisasi juga membantu. Secara umum, seluruh database harus memiliki tingkat normalisasi antara 3NF - 5NF (Saya selalu punya masalah dengan 4NF!)
Googlebot

Jawaban:

19

Jika itu sesuai dengan aturan normalisasi, maka hubungan 1: 1 dapat dinormalisasi (menurut definisi!) - Dengan kata lain, tidak ada apapun tentang hubungan 1: 1 yang membuat mereka tidak mungkin untuk mematuhi bentuk normal.

Untuk menjawab pertanyaan Anda tentang kepraktisan hubungan 1: 1, ada kalanya ini adalah konstruksi yang sangat berguna, seperti ketika Anda memiliki subtipe dengan predikat berbeda (kolom).

Alasan Anda menggunakan hubungan 1: 1 tergantung pada sudut pandang Anda. DBA cenderung menganggap segala sesuatu sebagai keputusan kinerja. Pemodel data dan pemrogram cenderung menganggap keputusan ini sebagai berorientasi desain atau model. Bahkan, ada banyak tumpang tindih antara sudut pandang ini. Itu tergantung pada apa perspektif dan prioritas Anda. Berikut adalah beberapa contoh motivasi untuk hubungan 1: 1:

  • Anda memiliki beberapa bagian kolom yang sangat luas dan Anda ingin memisahkannya secara fisik di penyimpanan Anda karena alasan kinerja.

  • Anda memiliki beberapa bagian kolom yang tidak sering dibaca atau diperbarui dan Anda ingin memisahkannya dari kolom yang sering digunakan karena alasan kinerja.

  • Anda memiliki beberapa kolom yang opsional secara umum tetapi wajib jika Anda tahu bahwa catatan adalah tipe tertentu.

  • Anda memiliki beberapa kolom yang secara logis dimiliki bersama untuk subtipe dan Anda ingin memodelkannya agar cocok dengan model objek kode Anda.

  • Anda memiliki beberapa kolom yang hanya bisa berlaku untuk beberapa subtipe dari entitas tipe super, dan Anda ingin skema Anda untuk menegakkan ketiadaan data ini untuk subtipe lainnya.

  • Anda memiliki beberapa kolom yang dimiliki suatu entitas tetapi Anda harus melindungi kolom-kolom khusus ini menggunakan aturan akses yang lebih ketat (mis. Gaji di meja karyawan).

Jadi bisa Anda lihat, kadang-kadang driver adalah kinerja, kadang-kadang itu model kemurnian, atau hanya keinginan untuk mengambil keuntungan penuh dari aturan skema deklaratif.

Joel Brown
sumber
You have some subset of columns that are very wide and you want to segregate them physically in your storage for performance reasons.Bagaimana memisahkannya meningkatkan kinerja (dengan asumsi kolom selalu diakses setiap kali tabel utamanya)?
Gili
@Gili - Jika asumsi Anda benar maka kasus ini tidak berlaku. Memisahkan kolom yang besar dan jarang dibutuhkan memungkinkan lebih banyak baris untuk masuk pada halaman, sehingga memungkinkan pengambilan lebih cepat dari kolom yang biasa digunakan. Jelas membaca kolom terpisah bersama dengan kolom yang biasa digunakan akan lebih lambat karena diperlukan gabungan.
Joel Brown
Saya ingin memisahkan kolom yang umum digunakan untuk alasan desain (pemisahan masalah, peningkatan penggunaan kembali kode). Adakah yang diposting perkiraan biaya bergabung seperti itu? Apakah mereka dapat diabaikan atau sesuatu yang saya harus khawatirkan untuk jangka panjang?
Gili
@Gili - re: biaya bergabung: Tidak ada jawaban yang tepat untuk pertanyaan itu selain dari "itu tergantung". Biaya bergabung dipengaruhi oleh banyak faktor. Apakah mereka dapat diabaikan atau bahkan lebih sulit untuk dijawab, karena itu pada akhirnya bersifat subjektif. Cara terbaik untuk menjawab pertanyaan Anda adalah dengan membuat beberapa data pengujian dan melakukan pengujian volume. Cobalah keduanya dan lihat apakah Anda dapat membedakannya menggunakan volume data dunia nyata (apa pun yang menyiratkan aplikasi Anda).
Joel Brown
Saya lakukan, dan mendapat hasil yang mengejutkan: dba.stackexchange.com/q/74693/4719 Saya akui ini bukan contoh normalisasi normal, tetapi tidak menyoroti bahwa GABUNGAN (masih) sangat mahal.
Gili
4

Alasan utama mengapa Anda akan menggunakan pemetaan satu-ke-satu untuk memecah tabel besar menjadi dua adalah karena alasan kinerja misalnya:

a) Tabel memiliki data biner / gumpalan / gumpalan dalam tabel yang sering diakses sehingga memperlambat kinerja karena kolom besar ditangani secara berbeda.

b) Tabel memiliki banyak kolom yang diakses oleh kueri yang berbeda, maka kinerjanya menurun sehingga Anda akan memindahkan kolom terkait ke tabel terpisah untuk meningkatkan kinerja akses

Namun memiliki banyak kolom integer tidak membenarkan upaya tambahan memecah tabel menjadi tabel terpisah dan harus meminta mereka.

Stephen Senkomago Musoke
sumber
Poin yang sangat bagus untuk klarifikasi masalah!
Googlebot