it-swarm-id.com

Kunci pengganti vs. alami / bisnis

Ini dia lagi, argumen lama masih muncul ...

Apakah kita lebih baik memiliki kunci bisnis sebagai kunci utama, atau lebih baik kita memiliki id pengganti (yaitu identitas SQL Server) dengan kendala unik pada bidang kunci bisnis?

Tolong, berikan contoh atau bukti untuk mendukung teori Anda.

163
Manrico Corazzi

Kedua. Dapatkan kue Anda dan makanlah.

Ingat, tidak ada yang spesial dari kunci primer, kecuali bahwa itu dilabeli demikian. Ini tidak lebih dari batasan NOT NULL UNIK, dan sebuah tabel dapat memiliki lebih dari satu.

Jika Anda menggunakan kunci pengganti, Anda masih menginginkan kunci bisnis untuk memastikan keunikan sesuai dengan aturan bisnis.

91
Ted

Hanya beberapa alasan untuk menggunakan kunci pengganti:

  1. Stabilitas: Mengubah kunci karena kebutuhan bisnis atau alami akan memengaruhi tabel terkait secara negatif. Kunci pengganti jarang, jika pernah, perlu diubah karena tidak ada makna yang terkait dengan nilai tersebut.

  2. Konvensi: Memungkinkan Anda untuk memiliki konvensi penamaan kolom Kunci Utama terstandarisasi daripada harus memikirkan cara bergabung dengan tabel dengan berbagai nama untuk PK mereka.

  3. Kecepatan: Bergantung pada nilai dan jenis PK, kunci pengganti bilangan bulat mungkin lebih kecil, lebih cepat untuk mengindeks dan mencari.

113
Jay Shepherd

Tampaknya belum ada yang mengatakan apa pun untuk mendukung kunci non-pengganti (saya ragu untuk mengatakan "alami"). Jadi begini ...

Kerugian dari kunci pengganti adalah bahwa mereka tidak berarti (dikutip sebagai diuntungkan oleh beberapa orang, tapi ...). Ini terkadang memaksa Anda untuk bergabung dengan lebih banyak tabel ke dalam kueri Anda daripada yang seharusnya diperlukan. Membandingkan:

select sum(t.hours)
from timesheets t
where t.dept_code = 'HR'
and t.status = 'VALID'
and t.project_code = 'MYPROJECT'
and t.task = 'BUILD';

melawan:

select sum(t.hours)
from timesheets t
     join departents d on d.dept_id = t.dept_id
     join timesheet_statuses s on s.status_id = t.status_id
     join projects p on p.project_id = t.project_id
     join tasks k on k.task_id = t.task_id
where d.dept_code = 'HR'
and s.status = 'VALID'
and p.project_code = 'MYPROJECT'
and k.task_code = 'BUILD';

Kecuali ada orang yang berpikir serius bahwa yang berikut adalah ide yang bagus?

select sum(t.hours)
from timesheets t
where t.dept_id = 34394
and t.status_id = 89    
and t.project_id = 1253
and t.task_id = 77;

"Tetapi" seseorang akan berkata, "apa yang terjadi ketika kode untuk MYPROJECT atau VALID atau HR berubah?" Jawaban saya adalah: "mengapa Anda perlu untuk mengubahnya?" Ini bukan kunci "alami" dalam arti bahwa beberapa badan luar akan membuat undang-undang yang selanjutnya 'VALID' harus dikodekan ulang sebagai 'BAIK'. Hanya sebagian kecil kunci "alami" yang benar-benar masuk dalam kategori tersebut - SSN dan kode pos menjadi contoh yang biasa. Saya pasti akan menggunakan kunci numerik yang tidak berarti untuk tabel seperti Person, Address - tetapi tidak untuk semuanya , yang untuk beberapa alasan sebagian besar orang di sini tampaknya menganjurkan.

Lihat juga: jawaban saya untuk pertanyaan lain

67
Tony Andrews

Kunci pengganti tidak akan pernah punya alasan untuk berubah. Saya tidak bisa mengatakan hal yang sama tentang kunci alami. Nama belakang, email, ISBN nubmers - mereka semua dapat berubah satu hari.

29
Rimantas

Kunci pengganti (biasanya bilangan bulat) memiliki nilai tambah untuk membuat hubungan tabel Anda lebih cepat, dan lebih ekonomis dalam penyimpanan dan kecepatan pembaruan (bahkan lebih baik, kunci asing tidak perlu diperbarui saat menggunakan kunci pengganti, berbeda dengan bidang kunci bisnis, yang berubah sekarang dan kemudian).

Kunci utama tabel harus digunakan untuk mengidentifikasi baris yang unik, terutama untuk tujuan bergabung. Pikirkan tabel Orang: nama dapat berubah, dan tidak dijamin unik.

Pikirkan Perusahaan: Anda adalah perusahaan Merkin yang bahagia berbisnis dengan perusahaan lain di Merkia. Anda cukup pintar untuk tidak menggunakan nama perusahaan sebagai kunci utama, jadi Anda menggunakan ID perusahaan unik milik pemerintah Merkia secara keseluruhan dari 10 karakter alfanumerik. Kemudian Merkia mengubah ID perusahaan karena mereka pikir itu akan menjadi ide yang bagus. Tidak apa-apa, Anda menggunakan fitur pembaruan mesin db bertingkat Anda, untuk perubahan yang seharusnya tidak melibatkan Anda di tempat pertama. Di kemudian hari, bisnis Anda berkembang, dan sekarang Anda bekerja dengan perusahaan di Freedonia. ID perusahaan Freedonian hingga 16 karakter. Anda perlu memperbesar ID utama perusahaan (juga bidang kunci asing dalam Pesanan, Masalah, MoneyTransfers, dll), menambahkan bidang Negara di kunci utama (juga dalam kunci asing). Aduh! Perang saudara di Freedonia, terpecah di tiga negara. Nama negara rekan Anda harus diubah menjadi yang baru; mengalirkan pembaruan ke penyelamatan. BTW, apa kunci utama Anda? (Negara, CompanyID) atau (CompanyID, Negara)? Yang terakhir membantu bergabung, yang pertama menghindari indeks lain (atau mungkin banyak, jika Anda ingin Pesanan Anda dikelompokkan berdasarkan negara juga).

Semua ini bukan bukti, tetapi indikasi bahwa kunci pengganti untuk secara unik mengidentifikasi baris untuk semua penggunaan, termasuk operasi gabungan, lebih disukai daripada kunci bisnis.

29
tzot

Saya benci kunci pengganti secara umum. Mereka hanya boleh digunakan ketika tidak ada kunci alami kualitas yang tersedia. Agak aneh ketika Anda memikirkannya, berpikir bahwa menambahkan data yang tidak berarti ke meja Anda bisa membuat segalanya lebih baik.

Inilah alasan saya:

  1. Saat menggunakan kunci alami, tabel mengelompok dalam cara yang paling sering dicari sehingga membuat kueri lebih cepat.

  2. Saat menggunakan kunci pengganti, Anda harus menambahkan indeks unik pada kolom kunci logis. Anda masih perlu mencegah duplikat data logis. Misalnya, Anda tidak dapat mengizinkan dua Organisasi dengan nama yang sama di tabel Organisasi Anda meskipun pk adalah kolom id pengganti.

  3. Ketika kunci pengganti digunakan sebagai kunci primer, akan jauh lebih tidak jelas apa kunci primer alami itu. Saat mengembangkan Anda ingin tahu set kolom apa yang membuat tabel unik.

  4. Dalam satu ke banyak rantai hubungan, rantai kunci logis. Jadi misalnya, Organisasi memiliki banyak Akun dan Akun memiliki banyak Faktur. Jadi kunci logis Organisasi adalah OrgName. Kunci logis Akun adalah OrgName, AccountID. Kunci logis Faktur adalah OrgName, AccountID, InvoiceNumber.

    Ketika kunci pengganti digunakan, gantungan kunci terpotong dengan hanya memiliki kunci asing ke induk langsung. Misalnya, tabel Faktur tidak memiliki kolom OrgName. Itu hanya memiliki kolom untuk AccountID. Jika Anda ingin mencari faktur untuk organisasi tertentu, maka Anda harus bergabung dengan tabel Organisasi, Akun, dan Faktur. Jika Anda menggunakan kunci logis, maka Anda bisa langsung menanyakan tabel organisasi.

  5. Menyimpan nilai-nilai kunci pengganti dari tabel pencarian menyebabkan tabel diisi dengan bilangan bulat yang tidak berarti. Untuk melihat data, tampilan kompleks harus dibuat yang bergabung dengan semua tabel pencarian. Tabel pencarian dimaksudkan untuk menampung seperangkat nilai yang dapat diterima untuk kolom. Seharusnya tidak dikodifikasikan dengan menyimpan kunci pengganti integer sebagai gantinya. Tidak ada dalam aturan normalisasi yang menyarankan bahwa Anda harus menyimpan bilangan pengganti bukan nilai itu sendiri.

  6. Saya punya tiga buku basis data yang berbeda. Tidak satu pun dari mereka menunjukkan menggunakan kunci pengganti.

26
Ken

Saya ingin berbagi pengalaman dengan Anda dalam perang tanpa akhir ini: D pada dilema kunci alami vs pengganti. Saya pikir kunci pengganti (kunci buatan otomatis) dan kunci alami (terdiri dari kolom dengan makna domain) miliki pro dan kontra . Jadi tergantung pada situasi Anda, mungkin lebih relevan untuk memilih satu metode atau yang lain.

Karena tampaknya banyak orang menghadirkan kunci pengganti sebagai solusi yang hampir sempurna dan kunci alami sebagai wabah, saya akan fokus pada argumen sudut pandang yang lain:

Kekurangan kunci pengganti

Kunci pengganti adalah:

  1. Sumber masalah kinerja:
    • Mereka biasanya diimplementasikan menggunakan kolom yang bertambah secara otomatis yang berarti:
      • Bolak-balik ke database setiap kali Anda ingin mendapatkan Id baru (saya tahu bahwa ini dapat ditingkatkan menggunakan algoritma caching atau [seq] hilo sama tetapi masih metode tersebut memiliki kelemahan sendiri).
      • Jika suatu hari Anda perlu memindahkan data Anda dari satu skema ke skema lain (Setidaknya ini terjadi cukup rutin di perusahaan saya) maka Anda mungkin mengalami masalah tabrakan ID. Dan Ya saya tahu bahwa Anda dapat menggunakan UUID tetapi yang terakhir membutuhkan 32 digit heksadesimal! (Jika Anda peduli tentang ukuran database maka itu bisa menjadi masalah).
      • Jika Anda menggunakan satu urutan untuk semua kunci pengganti Anda kemudian - pasti - Anda akan berakhir dengan pertikaian pada database Anda.
  2. Rawan kesalahan. Urutan memiliki batas max_value sehingga - sebagai pengembang - Anda harus memperhatikan poin-poin berikut:
    • Anda harus memutar urutan Anda (ketika nilai maksimum tercapai, itu kembali ke 1,2, ...).
    • Jika Anda menggunakan urutan sebagai urutan (dari waktu ke waktu) data Anda, maka Anda harus menangani kasus siklus (kolom dengan Id 1 mungkin lebih baru daripada baris dengan Id max-value - 1).
    • Pastikan kode Anda (dan bahkan antarmuka klien Anda yang seharusnya tidak terjadi karena seharusnya merupakan ID internal) mendukung bilangan bulat 32b/64b yang Anda gunakan untuk menyimpan nilai urutan Anda.
  3. Mereka tidak menjamin data yang tidak digandakan. Anda selalu dapat memiliki 2 baris dengan semua nilai kolom yang sama tetapi dengan nilai yang dihasilkan berbeda. Bagi saya ini adalah [~ # ~] masalah [~ # ~] dari kunci pengganti dari sudut pandang desain database.
  4. Lebih banyak di Wikipedia ...

Mitos tentang kunci alami

  1. Kunci komposit kurang efisien dibandingkan kunci pengganti. Tidak! Itu tergantung pada mesin database yang digunakan:
  2. Kunci alami tidak ada dalam kehidupan nyata. Maaf tapi mereka memang ada! Dalam industri penerbangan, misalnya, Tuple berikut akan selalu unik tentang penerbangan terjadwal (penerbangan, keberangkatan, Tanggal, flightNumber, operationalSuffix). Lebih umum, ketika satu set data bisnis dijamin unik oleh standar yang diberikan maka set data ini adalah kandidat kunci alami [baik].
  3. Kunci alami "mencemari skema" tabel anak. Bagi saya ini lebih merupakan perasaan daripada masalah nyata. Memiliki 4 kolom primary-key masing-masing 2 byte mungkin lebih efisien daripada satu kolom tunggal 11 byte. Selain itu, 4 kolom dapat digunakan untuk query tabel anak secara langsung (dengan menggunakan 4 kolom dalam klausa di mana) tanpa bergabung ke tabel induk.

Kesimpulan

Gunakan kunci alami saat relevan untuk melakukannya dan gunakan kunci pengganti saat lebih baik menggunakannya.

Semoga ini bisa membantu seseorang!

17
mwnsiri

Selalu menggunakan kunci yang tidak memiliki arti bisnis. Ini latihan yang bagus.

EDIT: Saya mencoba mencari tautan ke internet, tetapi saya tidak bisa. Namun dalam 'Pola Arsitektur Perusahaan' [Fowler] ia memiliki penjelasan yang baik tentang mengapa Anda tidak boleh menggunakan apa pun selain kunci tanpa makna selain menjadi kunci. Itu bermuara pada kenyataan bahwa ia harus memiliki satu pekerjaan dan satu pekerjaan saja.

15
Iain Holder

Kunci pengganti sangat berguna jika Anda berencana untuk menggunakan alat ORM untuk menangani/menghasilkan kelas data Anda. Meskipun Anda dapat menggunakan kunci komposit dengan beberapa pemetaan yang lebih maju (baca: hibernasi), ini menambahkan beberapa kerumitan pada kode Anda.

(Tentu saja, basis data puritan akan berpendapat bahwa bahkan gagasan kunci pengganti adalah kekejian.)

Saya penggemar menggunakan cairan untuk kunci pengganti jika cocok. Kemenangan besar bersama mereka adalah bahwa Anda mengetahui kunci sebelumnya, mis. Anda dapat membuat instance kelas dengan ID yang telah ditetapkan dan dijamin unik sedangkan dengan, katakanlah, kunci integer Anda harus default ke 0 atau -1 dan memperbarui ke nilai yang sesuai saat Anda menyimpan/memperbarui.

UID memiliki hukuman dalam hal pencarian dan kecepatan bergabung sehingga tergantung pada aplikasi yang dipertanyakan apakah mereka diinginkan.

9
Derek Lawless

Menggunakan kunci pengganti lebih baik menurut saya karena tidak ada kesempatan untuk mengubahnya. Hampir semua yang dapat saya pikirkan yang dapat Anda gunakan sebagai kunci alami dapat berubah (penafian: tidak selalu benar, tetapi umumnya).

Contohnya mungkin DB mobil - pada pandangan pertama, Anda mungkin berpikir bahwa plat dapat digunakan sebagai kuncinya. Tapi ini bisa diubah jadi itu ide yang buruk. Anda tidak benar-benar ingin mengetahuinya setelah melepaskan aplikasi, ketika seseorang datang kepada Anda ingin tahu mengapa mereka tidak dapat mengubah plat nomor mereka menjadi yang baru dipersonalisasi mengkilap.

6
Mark Embling

Selalu gunakan satu kolom, kunci pengganti jika memungkinkan. Ini membuat gabungan serta penyisipan/pembaruan/penghapusan jauh lebih bersih karena Anda hanya bertanggung jawab untuk melacak satu informasi untuk menjaga catatan.

Kemudian, sesuai kebutuhan, susun kunci bisnis Anda sebagai batasan atau indeks unik. Ini akan menjaga integritas data Anda tetap utuh.

Logika bisnis/kunci alami dapat berubah, tetapi kunci fisik tabel tidak akan pernah berubah.

5
user7658

Pada skenario datawarehouse saya percaya lebih baik mengikuti jalur kunci pengganti. Dua alasan:

  • Anda independen dari sistem sumber, dan perubahan di sana - seperti perubahan tipe data - tidak akan memengaruhi Anda.
  • DW Anda akan membutuhkan lebih sedikit ruang fisik karena Anda hanya akan menggunakan tipe data integer untuk kunci pengganti Anda. Juga indeks Anda akan bekerja lebih baik.
4
Santiago Cepas

Ini adalah salah satu kasus di mana kunci pengganti cukup banyak selal masuk akal. Ada beberapa kasus di mana Anda memilih yang terbaik untuk database atau yang terbaik untuk model objek Anda, tetapi dalam kedua kasus, menggunakan kunci yang tidak berarti atau GUID adalah ide yang lebih baik. Itu membuat pengindeksan lebih mudah dan lebih cepat, dan itu adalah identitas untuk objek Anda yang tidak berubah.

2
Charles Graham

Sebagai pengingat itu bukan praktik yang baik untuk menempatkan indeks berkerumun pada kunci pengganti acak yaitu PANDUAN yang membaca XY8D7-DFD8S, karena mereka SQL Server tidak memiliki kemampuan untuk secara fisik mengurutkan data ini. Sebagai gantinya Anda harus menempatkan indeks unik pada data ini, meskipun mungkin juga bermanfaat untuk hanya menjalankan profiler SQL untuk operasi tabel utama dan kemudian menempatkan data tersebut ke dalam Penasihat Tuning Mesin Basis Data.

Lihat utas @ http://social.msdn.Microsoft.com/Forums/en-us/sqlgetstarted/thread/27bd9c77-ec31-44f1-ab7f-bd2cb13129be

2
Bryan Swan

Kasus 1: Tabel Anda adalah tabel pencarian dengan kurang dari 50 jenis (sisipan)

Gunakan kunci bisnis/natural. Sebagai contoh:

Table: JOB with 50 inserts
CODE (primary key)       NAME               DESCRIPTION
PRG                      PROGRAMMER         A programmer is writing code
MNG                      MANAGER            A manager is doing whatever
CLN                      CLEANER            A cleaner cleans
...............
joined with
Table: PEOPLE with 100000 inserts

foreign key JOBCODE in table PEOPLE
looks at
primary key CODE in table JOB

Kasus 2: Tabel Anda adalah tabel dengan ribuan sisipan

Gunakan surrogate/autoincrement keys. Sebagai contoh:

Table: ASSIGNMENT with 1000000 inserts
joined with
Table: PEOPLE with 100000 inserts

foreign key PEOPLEID in table ASSIGNMENT
looks at
primary key ID in table PEOPLE (autoincrement)

Dalam kasus pertama:

  • Anda dapat memilih semua pemrogram dalam tabel ORANG tanpa menggunakan bergabung dengan tabel JOB, tetapi cukup dengan: "PILIH * DARI ORANG DI MANA JOBCODE = 'PRG'"

Dalam kasus kedua:

  • Kueri basis data Anda lebih cepat karena kunci utama Anda adalah bilangan bulat
  • Anda tidak perlu repot-repot mencari kunci unik berikutnya karena database itu sendiri memberi Anda kenaikan otomatis berikutnya.
2
Stefanos Kargas

Kunci pengganti dapat berguna ketika informasi bisnis dapat berubah atau identik. Lagipula, nama bisnis tidak harus unik di seluruh negeri. Misalkan Anda berurusan dengan dua bisnis bernama Smith Electronics, satu di Kansas dan satu di Michigan. Anda dapat membedakan mereka berdasarkan alamat, tetapi itu akan berubah. Bahkan negara dapat berubah; bagaimana jika Smith Electronics dari Kansas City, Kansas bergerak menyeberangi sungai ke Kansas City, Missouri? Tidak ada cara yang jelas untuk membedakan bisnis ini dengan informasi kunci alami, jadi kunci pengganti sangat berguna.

Pikirkan kunci pengganti seperti nomor ISBN. Biasanya, Anda mengidentifikasi buku berdasarkan judul dan pengarang. Namun, saya punya dua buku berjudul "Pearl Harbor" oleh H. P. Willmott, dan mereka pasti buku yang berbeda, bukan hanya edisi yang berbeda. Dalam kasus seperti itu, saya bisa merujuk pada tampilan buku-buku itu, atau yang lebih awal versus yang belakangan, tetapi hanya saja saya memiliki ISBN untuk digunakan kembali.

2
David Thornley

Kuda untuk kursus. Untuk menyatakan bias saya; Saya seorang pengembang pertama, jadi saya terutama peduli memberi pengguna aplikasi yang berfungsi.

Saya telah bekerja pada sistem dengan kunci alami, dan harus menghabiskan banyak waktu untuk memastikan bahwa perubahan nilai akan berombak.

Saya telah bekerja pada sistem dengan hanya tombol pengganti, dan satu-satunya kelemahan adalah kurangnya data yang dinormalisasi untuk dipartisi.

Kebanyakan pengembang PL/SQL tradisional yang pernah bekerja dengan saya tidak suka kunci pengganti karena jumlah tabel per gabung, tetapi basis data pengujian dan produksi kami tidak pernah berkeringat; gabungan tambahan tidak memengaruhi kinerja aplikasi. Dengan dialek basis data yang tidak mendukung klausa seperti "X inner join Y on Xa = Yb", atau pengembang yang tidak menggunakan sintaksis itu, gabungan ekstra untuk kunci pengganti memang membuat kueri lebih sulit dibaca, dan lebih lama untuk mengetik dan periksa: lihat posting @Tony Andrews. Tetapi jika Anda menggunakan ORM atau kerangka kerja generasi SQL lainnya, Anda tidak akan melihatnya. Pengetikan sentuh juga mengurangi.

1
WillC

Mungkin tidak sepenuhnya relevan dengan topik ini, tetapi sakit kepala saya harus berurusan dengan kunci pengganti. Analisis pra-pengiriman Oracle membuat SK yang dihasilkan secara otomatis pada semua tabel dimensinya di gudang, dan juga menyimpannya berdasarkan fakta. Jadi, kapan saja mereka (dimensi) perlu dimuat ulang ketika kolom baru ditambahkan atau perlu diisi untuk semua item dalam dimensi, SK yang ditugaskan selama pembaruan membuat SK tidak sinkron dengan nilai-nilai asli yang disimpan pada fakta, memaksa memuat ulang semua tabel fakta yang bergabung secara lengkap. Saya lebih suka bahwa bahkan jika SK adalah angka yang tidak berarti, akan ada beberapa cara yang tidak dapat diubah untuk catatan asli/lama. Seperti yang diketahui banyak orang, out-of-the-box jarang melayani kebutuhan organisasi, dan kami harus menyesuaikannya terus-menerus. Kami sekarang memiliki data senilai 3 tahun di gudang kami, dan isi ulang lengkap dari sistem Oracle Financial sangat besar. Jadi dalam kasus saya, mereka tidak dihasilkan dari entri data, tetapi ditambahkan di gudang untuk membantu melaporkan kinerja. Aku mengerti, tapi kita memang berubah, dan itu mimpi buruk.

1
lrb

Dalam hal basis data titik waktu, yang terbaik adalah memiliki kombinasi kunci pengganti dan alami. misalnya Anda perlu melacak informasi anggota untuk klub. Beberapa atribut anggota tidak pernah berubah. mis. Tanggal Lahir tetapi nama bisa berubah. Jadi buat tabel Anggota dengan kunci pengganti member_id dan punya kolom untuk DOB. Buat tabel lain yang disebut nama orang dan memiliki kolom untuk member_id, member_fname, member_lname, date_updated. Dalam tabel ini kunci alami akan menjadi member_id + date_updated.

0
kanad