Membagikan urutan kunci primer tunggal di dalam basis data?

14

Apakah ini merupakan praktik yang dapat diterima untuk menggunakan urutan tunggal sebagai kunci utama di semua tabel (alih-alih kunci primer menjadi unik untuk tabel yang diberikan, itu adalah unik untuk semua tabel)? Jika demikian, apakah secara objektif lebih baik daripada menggunakan urutan kunci primer tunggal di seluruh tabel.

Saya seorang pengembang perangkat lunak junior, bukan DBA, jadi saya masih mempelajari banyak dasar-dasar desain basis data yang baik.

Sunting: Jika ada yang bertanya-tanya, saya baru-baru ini membaca kritik tentang desain database oleh salah satu DBA perusahaan kami yang menyebutkan itu adalah masalah bahwa desain tidak menggunakan kunci primer tunggal di seluruh database, yang terdengar berbeda dari apa Saya sudah belajar sejauh ini.

Sunting2: Untuk menjawab pertanyaan dalam komentar, ini untuk Oracle 11g, tapi saya bertanya-tanya pada tingkat spesifik non-database. Jika pertanyaan ini tergantung pada database, saya akan tertarik untuk mengetahui alasannya, tetapi dalam kasus seperti ini saya akan mencari jawaban yang spesifik untuk Oracle.

Lawtonfogle
sumber
2
Ini biasanya ide yang buruk, karena alasan kinerja.
Philᵀᴹ
1
Sebenarnya ada manfaat yang lebih kuat dalam membuat setiap tabel dengan kisaran kunci primer independennya sendiri. Tetapi hanya dalam hal itu ketika Anda melihat banyak ID Anda bisa mengatakan, ini adalah Akun, bahwa itu adalah PurchaseHeader, dll. Melakukan ini memerlukan beberapa pengaturan dan (seperti hal tujuan khusus) beberapa perawatan dan pemberian makan yang berkelanjutan. (Ya, saya telah bekerja dengan sistem seperti ini, bertahun-tahun yang lalu.)
RLF
DBMS mana yang Anda gunakan? Peramal? Postgres? DB2?
a_horse_with_no_name
1
Apakah mungkin Anda salah mengartikan apa yang dia maksud? Mungkin dia tidak begitu literal?
JamesRyan
Apakah perusahaan DBA sebenarnya berarti tidak ada bidang kunci utama yang ada di salah satu tabel?
Max Vernon

Jawaban:

13

Dapat diterima? Tentu. Umum? Tidak. Bermanfaat? Diragukan.

Di pekerjaan lama saya, kami mewarisi sistem di mana mereka memiliki generator urutan pusat (ini adalah sistem SQL Server jauh sebelum SEQUENCEdiperkenalkan dalam SQL Server 2012). Itu sebenarnya bukan hambatan kinerja dan seharusnya tidak terjadi kecuali Anda menghasilkan ratusan ribu nilai per detik. Tapi itu membuat semua kode jauh lebih kompleks daripada yang seharusnya, tanpa alasan yang bagus. Maksud dari desain adalah untuk memastikan bahwa jika sesuatu dalam sistem diberi nilai ID 12, hanya satu hal dalam sistem yang dapat memiliki ID 12. Ini tampaknya cukup tumpul bagi saya dan saya tidak pernah memahaminya. Jika saya memiliki pelanggan dengan CustomerID = 12, mengapa hal itu menghalangi saya untuk melakukan pemesanan dengan OrderID = 12?

Saya memang melihat manfaat dari generator urutan pusat jika Anda memiliki banyak sistem dan Anda menghasilkan ID untuk jenis entitas tertentu (misalnya, pelanggan atau pesanan) dari beberapa sistem ini. Urutan sentral dapat membagikan nilai-nilai baru ke banyak sistem tanpa menjadi hambatan (hanya satu titik kegagalan) dan tanpa takut dua sistem menghasilkan ID yang sama.

Aaron Bertrand
sumber
Jika Anda harus memilih antara sesuatu seperti ini dan hanya menggunakan pengidentifikasi unik sebagai kunci utama, apakah Anda memiliki preferensi (walaupun jawabannya kemungkinan "itu tergantung")? Sepertinya GUID akan mengatasi masalah dengan cara yang sama, kecuali bahwa Anda akan mendapatkan implementasi standar daripada harus memutar generator kunci utama Anda sendiri yang terpusat. Jelas, menggunakan urutan dalam SQL 2012 akan menyelesaikan kedua hal tersebut, tetapi dengan asumsi seseorang menggunakan versi yang lebih lama?
SqlRyan
2
@SqlRyan Saya perlu memahami mengapa OrderID harus benar-benar berbeda dari CustomerID. Saya hampir pasti tidak akan menggunakan GUID untuk ini; menyiapkan rentang IDENTITAS mungkin lebih baik (Pelanggan mulai dari 1, Pesanan mulai dari 1000000, dll.) dengan peringatan ketika Anda hampir melelahkan rentang saja.
Aaron Bertrand
1
@SqlRyan - menggunakan GUID yang diimplementasikan dengan buruk karena kunci primer yang dikelompokkan dapat menyebabkan semua jenis masalah. Seperti yang dikatakan Harun, IDENTITAS sesuai dengan tujuannya jauh lebih baik.
Max Vernon
Dalam sistem sebelumnya saya telah melihat menggunakan urutan tunggal di seluruh database, ini dilakukan untuk memungkinkan kunci asing untuk menunjuk ke berbagai tabel bukan satu tabel, sehingga ketika Anda mengatakan bahwa kunci asing dari dua baris yang berbeda 12, Anda tahu mereka menunjuk ke hal yang sama tanpa perlu memeriksa apa meja yang mereka tunjuk. Angka 13 pada kolom yang sama berpotensi menjadi kunci utama pada tabel yang berbeda. Saya pribadi sangat tidak nyaman dengan gaya desain itu.
Lawtonfogle
@ AaronBertrand Atau sebagai gantinya gunakan pengidentifikasi bilangan bulat sederhana dan tambahkan beberapa kode ke awal ketika ini adalah pelanggan yang menghadap. misalnya. I1337, C1337 jelas merupakan faktur atau pelanggan
JamesRyan
7

Idenya memiliki manfaat dalam database yang sangat kompleks di mana orang dapat secara tidak sengaja bergabung ke tabel menggunakan kolom yang salah dan mendapatkan baris yang tidak valid hanya karena ID INT adalah sama.

Kami memilih untuk memiliki GUID berurutan sebagai kunci utama kami untuk menghindari beberapa jebakan fragmentasi indeks dari GUID. Sayangnya mereka cukup besar.

SQL server dapat menghasilkan GUID berurutan melalui default yang memanggil fungsi newSequentialID (), sehingga tidak ada tabel kunci yang dikeluarkan untuk dipelihara dan tidak ada pemblokiran hambatan.

Ini telah memberi kami ID unik di seluruh basis data, di seluruh perusahaan kami karena mereka benar-benar unik.

Harga tentu saja adalah ruang dan bermasalah ketika Anda mencoba membawa data ke Gudang Data / Kubus di mana kecepatan / ukuran didasarkan pada penggunaan kunci Integer yang lebih kecil.

Saya yakin kami telah menghindari banyak bug di aplikasi kami karena menggunakannya.

RayG
sumber
4

Saya tidak bisa membayangkan apa yang mungkin menjadi alasan di balik urutan tunggal di semua tabel. Yang dilakukannya hanyalah membuat bottleneck saat menghasilkan nilai baru.

Tidak peduli seberapa kecil overhead untuk menghasilkan nilai kunci berurutan, generator adalah sumber daya tunggal, akses yang harus disinkronkan. Semakin banyak permintaan yang didapat, semakin tinggi kemungkinan bahwa beberapa pemohon harus menunggu giliran mereka di keran. Jelas bahwa generator urutan tunggal yang dibagi antara semua tabel akan diakses lebih sering oleh lebih banyak klien, sehingga menghasilkan lebih banyak pertengkaran, daripada salah satu dari beberapa generator. Perselisihan dapat menjadi lebih jelas jika aturan bisnis memberlakukan batasan pada nilai yang dihasilkan, seperti tidak adanya celah atau pemesanan yang ketat, atau dalam database yang dikelompokkan.

Bahkan dengan generator urutan paling efisien akan ada beban kerja yang menyebabkan pertengkaran yang tidak dapat ditoleransi.

mustaccio
sumber
2
Anda mungkin ingin menambahkan detail tentang bagaimana bottleneck dibuat dan mengapa itu adalah ide yang buruk.
Max Vernon
2

tujuan dari PrimaryKey dalam tabel Database terutama untuk menegakkan keunikan data yang seharusnya unik, karena semua alur kerja tidak dapat dibahas dan dipastikan bahwa itu tidak akan menghasilkan duplikasi data. Alasan kedua adalah, berkali-kali PK juga kandidat utama untuk Indeks berkerumun di atas meja sehingga juga meningkatkan pengambilan data saat / di mana kolom ini digunakan dengan benar dalam kueri pemilihan.

menggunakan nomor urut sebagai kunci Primer sama karena setiap tabel memiliki kolom Identitas dan hanya kolom yang digunakan di PrimaryKey. memiliki nomor urut tunggal di DB harus memiliki beberapa penggunaan khusus tetapi dari sudut pandang PrimaryKey saya tidak mengerti alasannya. misalnya dalam salah satu proyek Datawarehouse yang saya kerjakan, kami memiliki Kolom yang disebut LoadBatchID dan dari ETL untuk melaporkan 50% dari semua tabel memiliki kolom ini tetapi di beberapa tempat memiliki arti yang berbeda. kami menggunakan proc unik sebagai penghasil angka untuk memastikan kami tidak menemukan konflik dan juga membantu kami melacak kembali ke file asli dari mana data berasal dan apa yang terjadi pada setiap tahap ETL yang berbeda.

Anup Shah
sumber
2

Saya kira satu alasan untuk melakukannya adalah jika semua entitas diwarisi dari beberapa entitas induk. Katakan misalnya Anda ingin dapat memberikan komentar pada semua jenis entitas:

create table god_entity (
  id bigserial primary key
);

create table some_table (
  id bigint primary key references god_entity(id),
  ...
);

create table some_other_table (
  id bigint primary key references god_entity(id),
  ...
);

create table comment (
  id bigint primary key references god_entity(id),
  ...
);

create table entity_comment (
  entity_id bigint not null references god_entity(id),
  comment_id bigint not null references god_entity(id),

  primary key (entity_id, comment_id)
);

Biasanya ini tidak dilakukan. .

Tidak tahu tentang karakteristik kinerja.

Neil McGuigan
sumber