Kapan saya harus menggunakan hubungan satu lawan satu?

92

Maaf untuk pertanyaan noob itu tetapi adakah kebutuhan nyata untuk menggunakan hubungan satu-ke-satu dengan tabel di database Anda? Anda dapat menerapkan semua bidang yang diperlukan di dalam satu tabel. Bahkan jika data menjadi sangat besar, Anda dapat menghitung nama kolom yang Anda butuhkan dalam SELECTpernyataan daripada menggunakan SELECT *. Kapan Anda benar-benar membutuhkan pemisahan ini?

Pavel Shchegolevatykh
sumber

Jawaban:

105

1 sampai 0..1

  • The "1 to 0..1" antara super dan sub-kelas digunakan sebagai bagian dari strategi "semua kelas dalam tabel terpisah" untuk mengimplementasikan pewarisan .

  • "1 hingga 0..1" dapat direpresentasikan dalam satu tabel dengan bagian "0..1" yang tercakup oleh kolom yang dapat NULL. Namun, jika sebagian besar hubungannya adalah "1 ke 0" dengan hanya beberapa baris "1 ke 1", memisahkan bagian "0..1" ke dalam tabel terpisah mungkin menghemat beberapa manfaat penyimpanan (dan kinerja cache). Beberapa database lebih hemat dalam menyimpan NULL dibandingkan yang lain, jadi "titik potong" di mana strategi ini menjadi layak dapat sangat bervariasi.

1 banding 1

  • "1 ke 1" yang sebenarnya mempartisi data secara vertikal, yang mungkin memiliki implikasi untuk penyimpanan ke cache. Database biasanya menerapkan cache di tingkat halaman, bukan di tingkat kolom individual, jadi meskipun Anda memilih hanya beberapa kolom dari satu baris, biasanya seluruh halaman yang memiliki baris tersebut akan di-cache. Jika baris sangat lebar dan bidang yang dipilih relatif sempit, Anda akan menyimpan banyak informasi yang sebenarnya tidak Anda butuhkan. Dalam situasi seperti itu, mungkin berguna untuk mempartisi data secara vertikal, sehingga hanya bagian atau baris yang lebih sempit dan lebih sering digunakan yang akan di-cache, sehingga lebih banyak dari mereka dapat masuk ke dalam cache, membuat cache secara efektif "lebih besar".

  • Penggunaan lain dari partisi vertikal adalah untuk mengubah perilaku penguncian: database biasanya tidak dapat mengunci pada tingkat bidang individual, hanya seluruh baris. Dengan memisahkan baris, Anda mengizinkan kunci hanya terjadi pada salah satu bagiannya.

  • Pemicu juga biasanya khusus tabel. Meskipun Anda secara teoritis hanya dapat memiliki satu tabel dan memicu mengabaikan "bagian yang salah" dari baris, beberapa database mungkin memberlakukan batasan tambahan tentang apa yang dapat dan tidak dapat dilakukan pemicu yang dapat membuat hal ini tidak praktis. Misalnya, Oracle tidak mengizinkan Anda mengubah tabel mutasi - dengan memiliki tabel terpisah, hanya satu tabel yang mungkin bermutasi sehingga Anda masih dapat memodifikasi tabel lainnya dari pemicu.

  • Tabel terpisah memungkinkan keamanan yang lebih terperinci.

Pertimbangan ini tidak relevan dalam banyak kasus, jadi dalam banyak kasus Anda harus mempertimbangkan untuk menggabungkan tabel "1 ke 1" menjadi satu tabel.

Branko Dimitrijevic
sumber
20

Jika data dalam satu tabel terkait, tetapi tidak 'milik' entitas yang dijelaskan oleh tabel lain, maka itu adalah kandidat untuk memisahkannya.

Ini bisa memberikan keuntungan di masa depan, jika data yang terpisah perlu dikaitkan dengan entitas lain juga.

Sepster
sumber
19

Jika Anda menempatkan dua tabel satu-ke-satu dalam satu, kemungkinan Anda akan mengalami masalah semantik. Misalnya, jika setiap perangkat memiliki satu pengontrol jarak jauh, kedengarannya tidak cukup baik untuk menempatkan perangkat dan pengontrol jarak jauh dengan berbagai karakteristiknya dalam satu tabel. Anda bahkan mungkin harus menghabiskan waktu untuk mencari tahu apakah atribut tertentu milik perangkat atau pengontrol jarak jauh.

Mungkin ada kasus, ketika setengah dari kolom Anda akan tetap kosong untuk waktu yang lama, atau tidak akan pernah terisi. Misalnya, sebuah mobil dapat memiliki satu trailer dengan banyak karakteristik, atau mungkin tidak ada. Jadi, Anda akan memiliki banyak atribut yang tidak digunakan.

Jika tabel Anda memiliki 20 atribut, dan hanya 4 di antaranya yang digunakan sesekali, masuk akal untuk memecah tabel menjadi 2 tabel untuk masalah kinerja.

Dalam kasus seperti itu, tidak baik untuk memiliki semuanya dalam satu tabel. Selain itu, tidak mudah menangani tabel yang memiliki 45 kolom!

superM
sumber
17

2 sen saya.

Saya bekerja di tempat di mana kita semua berkembang dalam aplikasi besar, dan semuanya adalah modul. Misalnya, kami memiliki userstabel, dan kami memiliki modul yang menambahkan detail facebook untuk pengguna, modul lain yang menambahkan detail twitter ke pengguna. Kami dapat memutuskan untuk mencabut salah satu modul tersebut dan menghapus semua fungsinya dari aplikasi kami. Dalam kasus ini, setiap modul menambahkan tabelnya sendiri dengan hubungan 1: 1 ke userstabel global , seperti ini:

create table users ( id int primary key, ...);
create table users_fbdata ( id int primary key, ..., constraint users foreighn key ...)
create table users_twdata ( id int primary key, ..., constraint users foreighn key ...)
santiago arizti
sumber
13

Waktu yang paling masuk akal untuk menggunakan ini adalah jika ada dua konsep terpisah yang hanya berhubungan dengan cara ini. Misalnya, sebuah Mobil hanya dapat memiliki satu Pengemudi saat ini, dan Pengemudi hanya dapat mengemudikan satu mobil dalam satu waktu - jadi hubungan antara konsep Mobil dan Pengemudi adalah 1 banding 1. Saya menerima bahwa ini adalah contoh buatan untuk mendemonstrasikan titik.

Alasan lainnya adalah Anda ingin mengkhususkan konsep dengan cara yang berbeda. Jika Anda memiliki tabel Orang dan ingin menambahkan konsep berbagai jenis Orang, seperti Karyawan, Pelanggan, Pemegang Saham - masing-masing memerlukan kumpulan data yang berbeda. Data yang serupa di antara mereka akan ada di tabel Orang, informasi spesialis akan ada di tabel khusus untuk Pelanggan, Pemegang Saham, Karyawan.

Beberapa mesin database berjuang untuk secara efisien menambahkan kolom baru ke tabel yang sangat besar (banyak baris) dan saya telah melihat tabel ekstensi yang digunakan untuk memuat kolom baru, daripada kolom baru yang ditambahkan ke tabel asli. Ini adalah salah satu penggunaan tabel tambahan yang lebih mencurigakan.

Anda juga dapat memutuskan untuk membagi data untuk satu konsep di antara dua tabel yang berbeda untuk masalah kinerja atau keterbacaan, tetapi ini adalah kasus yang cukup khusus jika Anda memulai dari awal - masalah ini akan muncul nanti.

Fenton
sumber
5

tidak terlalu sering.

Anda mungkin menemukan beberapa keuntungan jika Anda perlu menerapkan beberapa keamanan - sehingga beberapa pengguna dapat melihat beberapa kolom (tabel1) tetapi tidak yang lain (tabel2) ..

tentu saja beberapa database (Oracle) memungkinkan Anda untuk melakukan keamanan semacam ini dalam tabel yang sama, tetapi beberapa yang lain mungkin tidak.

Randy
sumber
5

Anda mengacu pada normalisasi database. Salah satu contoh yang dapat saya pikirkan dalam aplikasi yang saya pelihara adalah Item. Aplikasi ini memungkinkan pengguna untuk menjual berbagai jenis item (mis. InventoryItems, NonInventoryItems, ServiceItems, dll ...). Meskipun saya dapat menyimpan semua bidang yang diperlukan oleh setiap item dalam satu tabel Item, jauh lebih mudah untuk mempertahankan agar memiliki tabel Item dasar yang berisi kolom yang umum untuk semua item dan kemudian memisahkan tabel untuk setiap jenis item (yaitu Inventaris, NonInventory, dll ..) yang berisi bidang khusus hanya untuk jenis item itu. Kemudian, tabel item akan memiliki kunci asing untuk tipe item tertentu yang diwakilinya. Hubungan antara tabel item tertentu dan tabel item dasar akan menjadi satu-ke-satu.

Di bawah ini, adalah artikel tentang normalisasi.

http://support.microsoft.com/kb/283878

Belalang
sumber
3

Seperti semua pertanyaan desain, jawabannya adalah "tergantung".

Ada beberapa pertimbangan:

  • seberapa besar ukuran tabel (baik dalam bidang dan baris)? Mungkin tidak nyaman untuk menyimpan nama pengguna Anda, kata sandi dengan data lain yang kurang umum digunakan baik dari sudut pandang pemeliharaan dan pemrograman

  • bidang dalam tabel gabungan yang memiliki batasan bisa menjadi rumit untuk dikelola dari waktu ke waktu. misalnya, jika pemicu perlu diaktifkan untuk bidang tertentu, itu akan terjadi untuk setiap pembaruan pada tabel terlepas dari apakah bidang itu terpengaruh.

  • Seberapa yakin Anda bahwa hubungannya akan menjadi 1: 1? Seperti yang ditunjukkan oleh pertanyaan ini , segala sesuatunya menjadi rumit dengan cepat.

Rob Allen
sumber
3

Kasus penggunaan lainnya adalah sebagai berikut: Anda dapat mengimpor data dari beberapa sumber dan memperbaruinya setiap hari, misalnya informasi tentang buku. Kemudian, Anda menambahkan sendiri data tentang beberapa buku. Maka masuk akal untuk meletakkan data yang diimpor di tabel lain selain data Anda sendiri.

Beladau
sumber
2

Saya biasanya menjumpai dua jenis umum hubungan 1: 1 dalam praktik:

  1. Hubungan IS-A, juga dikenal sebagai hubungan supertipe / subtipe. Ini terjadi ketika satu jenis entitas sebenarnya adalah jenis dari entitas lain (EntityA IS A EntityB). Contoh:

    • Entitas orang, dengan entitas terpisah untuk Akuntan, Insinyur, Penjual, dalam perusahaan yang sama.
    • Entitas item, dengan entitas terpisah untuk Widget, RawMaterial, FinishedGood, dll.
    • Entitas mobil, dengan entitas terpisah untuk Truk, Sedan, dll.

    Dalam semua situasi ini, entitas supertipe (mis. Orang, Barang atau Mobil) akan memiliki atribut yang sama untuk semua subtipe, dan entitas subtipe akan memiliki atribut unik untuk setiap subtipe. Kunci utama dari subtipe akan sama dengan kunci supertipe.

  2. Hubungan "Bos". Ini terjadi ketika seseorang adalah bos atau manajer atau supervisor unik dari sebuah unit organisasi (departemen, perusahaan, dll.). Jika hanya ada satu bos yang diperbolehkan untuk sebuah unit organisasi, maka terdapat hubungan 1: 1 antara entitas orang yang mewakili bos dan entitas unit organisasi.

Tripartio
sumber
1
Saya suka contoh kedua. Anda dapat memiliki entitas "Departemen" dan entitas "Karyawan". Dalam satu departemen Anda memiliki banyak karyawan, dan seorang karyawan hanya dapat bekerja di satu departemen. Ini adalah 1: n. Seorang karyawan dapat menjadi supervisor sebuah departemen - hanya untuk satu departemen, dan departemen tersebut hanya memiliki satu supervisor. Jadi Anda berakhir dengan dua tabel yang terhubung dengan dua relasi - 1: n dan 1: 1.
cezar
2

Pertama, saya pikir ini adalah pertanyaan tentang pemodelan dan mendefinisikan apa yang terdiri dari entitas yang terpisah. Misalkan Anda memiliki customersdengan satu dan hanya satu address. Tentu saja Anda bisa menerapkan semuanya dalam satu tabelcustomer , tetapi jika, di masa mendatang Anda mengizinkannya untuk memiliki 2 atau lebih alamat, maka Anda perlu mempertimbangkannya kembali (bukan masalah, tetapi ambil keputusan secara sadar).

Saya juga dapat memikirkan kasus menarik yang tidak disebutkan dalam jawaban lain di mana memisahkan tabel dapat berguna:

Bayangkan, sekali lagi, Anda memiliki masing-masing customersdengan satu address, tetapi kali ini opsional untuk memiliki alamat. Tentu saja Anda bisa mengimplementasikannya sebagai sekumpulan NULLkolom yang dapat digunakan seperti ZIP,state,street. Tetapi anggaplah diberikan bahwa Anda memang memiliki alamat, statusnya tidak opsional, tetapi ZIP-nya. Bagaimana memodelkannya dalam satu tabel? Anda dapat menggunakan batasan pada customertabel, tetapi jauh lebih mudah untuk membagi di tabel lain dan membuat foreign_key NULLable. Dengan cara itu model Anda jauh lebih eksplisit dalam mengatakan bahwa entitas address itu opsional, dan bahwa ZIPadalah atribut opsional dari entitas itu.

polvoazul.dll
sumber
0

Dalam waktu pemrograman saya, saya menemukan ini hanya dalam satu situasi. Yaitu ketika ada hubungan 1-ke-banyak dan 1-ke-1 antara 2 entitas yang sama ("Entitas A" dan "Entitas B").

Jika "Entitas A" memiliki beberapa "Entitas B" dan "Entitas B" hanya memiliki 1 "Entitas A" dan "Entitas A" hanya memiliki 1 "Entitas B" saat ini dan "Entitas B" hanya memiliki 1 "Entitas A".

Misalnya, sebuah Mobil hanya dapat memiliki satu Pengemudi saat ini, dan Pengemudi hanya dapat mengemudikan satu mobil dalam satu waktu - jadi hubungan antara konsep Mobil dan Pengemudi adalah 1 banding 1. - Saya meminjam contoh ini dari jawaban @Steve Fenton

Dimana Pengemudi dapat mengendarai banyak Mobil, tidak pada saat yang bersamaan. Jadi entitas Mobil dan Pengemudi adalah 1-ke-banyak atau banyak-ke-banyak. Tetapi jika kita perlu mengetahui siapa driver saat ini, maka kita juga membutuhkan relasi 1-to-1.

Jo Smo
sumber
0

Kasus penggunaan lain mungkin jika jumlah kolom maksimum dalam tabel database terlampaui. Kemudian Anda bisa bergabung dengan tabel lain menggunakan OneToOne

db303
sumber