Apakah praktik yang baik untuk selalu memiliki kunci primer integer autoincrement?

191

Dalam database saya, saya cenderung membiasakan diri memiliki kunci primer bilangan bulat yang bertambah secara otomatis dengan nama iduntuk setiap tabel yang saya buat sehingga saya memiliki pencarian yang unik untuk setiap baris tertentu.

Apakah ini dianggap ide yang buruk? Apakah ada kelemahan untuk melakukannya dengan cara ini? Kadang-kadang saya akan memiliki beberapa indeks seperti id, profile_id, subscriptionsmana idadalah pengenal unik, profile_idlink ke asing iddari Profilemeja, dll

Atau ada skenario di mana Anda tidak ingin menambahkan bidang seperti itu?

AJJ
sumber
61
Lihat masalah tank Jerman untuk contoh di mana pengidentifikasi peningkatan otomatis adalah masalah. Tentu saja ini hanya masalah jika Anda menggunakan id Anda di depan umum.
Bergi
24
@ArukaJ Intinya adalah ia membocorkan beberapa informasi tentang sistem. Misalnya, misalkan database berisi posting yang ditulis pengguna, yang masing-masing mendapat id berurutan. Katakanlah Anda membuat empat posting, yang masing-masing mendapat id: pada jam 4 pagi (20), jam 5 pagi (25), jam 8 malam (100), dan jam 9 malam (200). Dengan melihat id, Anda dapat melihat bahwa hanya 5 posting yang ditambahkan antara jam 4 pagi dan 5 pagi, sedangkan 100 ditambahkan antara jam 8 malam dan jam 9 malam. Jika Anda mencoba memilih waktu untuk penolakan serangan layanan, itu bisa menjadi informasi yang berharga.
Joshua Taylor
29
Untuk semua orang yang mengeluh tentang "masalah tank Jerman" .... jika satu-satunya hal yang mencegah seseorang mengakses data yang seharusnya tidak mereka lakukan adalah kunci dalam URL Anda ... Anda memiliki masalah yang lebih besar daripada GUID versus Auto INT.
Matthew Whited
11
@MatthewWhited Ini bukan hanya tentang menukar parameter di URL. Misalkan Anda menggunakan situs dan Anda membuat aset 100 pada waktu t, dan aset 120 pada waktu t + 60. Jika Anda dapat melihat kedua ID tersebut (100 dan 120) dalam bentuk tanpa campur tangan, Anda sekarang tahu jumlah total aset yang ada, serta kira-kira tingkat pembuatannya. Ini adalah kebocoran informasi. Ini bukan murni hipotetis.
Chris Hayes
15
"Apakah itu praktik yang baik untuk selalu ..." Tidak.
brian_o

Jawaban:

137

Tidak pernah merupakan ide buruk untuk memiliki pengidentifikasi baris unik yang dijamin. Saya kira saya seharusnya tidak mengatakan tidak pernah - tapi mari kita pergi dengan mayoritas waktu itu adalah ide yang bagus.

Kerugian potensial teoretis termasuk indeks ekstra untuk mempertahankan dan ruang penyimpanan tambahan yang digunakan. Itu tidak pernah cukup alasan bagi saya untuk tidak menggunakannya.

GrandmasterB
sumber
11
Itu yang saya lakukan. Kebanyakan orang menggunakan 'id' atau 'tablename_id' (seperti user_id). Argumen ini tidak biasanya jika kolom diperlukan, tetapi ke mana nama itu.
GrandmasterB
103
Secara pribadi saya pikir nama tabel harus menyiratkan sisanya. TableName.idsebagai lawan TableName.TableName_id, karena apa lagi yang idakan merujuk? Jika saya memiliki bidang id lain dalam tabel maka saya akan awalan dengan nama tabel jika mengacu pada beberapa tabel lain
AJJ
10
@ArukaJ Anda menyebutkan Anda menggunakan SQLite. Itu sebenarnya sedikit kasus khusus, karena selalu membuat kolom seperti 'di bawah tenda'. Jadi Anda bahkan tidak menggunakan ruang tambahan karena Anda mendapatkannya apakah Anda menginginkannya atau tidak. Juga, rowid SQLite selalu merupakan integer 64bit. Jika pemahaman saya tentang hal itu benar, jika Anda mendefinisikan baris penambahan otomatis, itu akan menjadi alias ke rowid internal. Jadi, Anda mungkin selalu melakukannya! Lihat sqlite.org/autoinc.html
GrandmasterB
9
Satu-satunya pengecualian yang dapat saya pikirkan adalah jika Anda memiliki pengidentifikasi unik yang dihasilkan dengan cara lain, dalam hal ini yang seharusnya menjadi kunci utama dan id penambahan otomatis adalah mubazir.
HamHamJ
4
@GrandmasterB: Versi SQLite saat ini memungkinkan pembuatan WITHOUT ROWIDtabel (dengan eksplisit PRIMARY KEY) sebagai optimisasi. Tetapi sebaliknya, INTEGER PRIMARY KEYkolom adalah alias untuk rowid.
dan04
92

Saya tidak setuju dengan semua jawaban sebelumnya. Ada banyak alasan mengapa menambahkan bidang kenaikan otomatis di semua tabel merupakan ide yang buruk.

Jika Anda memiliki tabel di mana tidak ada kunci yang jelas, bidang kenaikan otomatis sepertinya ide yang bagus. Lagi pula, Anda tidak mau select * from blog where body = '[10000 character string]'. Anda lebih suka select * from blog where id = 42. Saya berpendapat bahwa dalam sebagian besar kasus ini, apa yang Anda inginkan adalah pengidentifikasi unik; bukan pengidentifikasi unik berurutan. Anda mungkin ingin menggunakan pengidentifikasi unik universal.

Ada fungsi di sebagian besar database untuk menghasilkan pengidentifikasi unik acak ( uuiddi mysql, postgres. newidDi mssql). Ini memungkinkan Anda untuk menghasilkan data ke banyak basis data, pada mesin yang berbeda, kapan saja, tanpa koneksi jaringan di antara mereka, dan masih menggabungkan data dengan nol konflik. Ini memungkinkan Anda untuk lebih mudah men-setup beberapa server dan bahkan pusat data, seperti misalnya, dengan layanan microser.

Ini juga menghindari penyerang menebak url ke halaman yang seharusnya tidak mereka akses. Jika ada, https://example.com/user/1263mungkin ada https://example.com/user/1262juga. Ini dapat memungkinkan otomasi eksploitasi keamanan di halaman profil pengguna.

Ada juga banyak kasus di mana kolom uuid tidak berguna atau bahkan berbahaya. Katakanlah Anda memiliki jejaring sosial. Ada usersmeja dan friendsmeja. Tabel teman berisi dua kolom userid dan bidang penambahan otomatis. Anda ingin 3berteman dengan 5, jadi Anda memasukkan 3,5ke dalam database. Basis data menambahkan id peningkatan otomatis dan menyimpan 1,3,5. Entah bagaimana, pengguna 3mengklik tombol "tambah teman" lagi. Anda memasukkan lagi 3,5ke dalam database, database menambahkan id dan sisipan peningkatan otomatis 2,3,5. Tapi sekarang 3dan 5berteman satu sama lain dua kali! Itu buang-buang ruang, dan kalau dipikir-pikir, begitu juga kolom kenaikan-otomatis. Yang perlu Anda lihat jika adanbadalah teman untuk memilih baris dengan dua nilai tersebut. Mereka, bersama-sama, pengidentifikasi baris yang unik. (Anda mungkin ingin menulis logika untuk memastikan 3,5dan 5,3dideduplikasi.)

Masih ada beberapa kasus di mana id berurutan dapat berguna, seperti saat membuat pemendek-url, tetapi kebanyakan (dan bahkan dengan pemendek url), id unik yang dihasilkan secara acak adalah yang benar-benar ingin Anda gunakan.

TL; DR: Gunakan UUID sebagai ganti kenaikan otomatis, jika Anda belum memiliki cara unik untuk mengidentifikasi setiap baris.

Filip Haglund
sumber
26
Masalah dengan UUID adalah bahwa mereka mengambil terlalu banyak ruang untuk sebagian besar tabel. Gunakan pengidentifikasi unik yang tepat untuk setiap tabel.
Stephen
49
Seluruh paragraf tentang keunikan diperdebatkan - keunikan dapat ditegakkan, dengan atau tanpa kunci utama. Selain itu, UUID lebih baik di sisi teoretis, tetapi mengerikan untuk digunakan ketika debugging / melakukan tugas-tugas DBA atau melakukan apa pun yang tidak "menolak serangan".
11
Skenario lain ketika UUID lebih baik: menerapkan operasi PUT idempoten, sehingga Anda dapat dengan aman mencoba kembali permintaan tanpa memperkenalkan baris duplikat.
yurez
21
Pada titik "menebak URL", memiliki ID unik (berurutan atau lainnya) tidak menyiratkan mengekspos ID itu kepada pengguna aplikasi.
Dave Sherohman
7
Murni dari sudut pandang basis data, jawaban ini sepenuhnya salah. Menggunakan UUID alih-alih bilangan bulat yang bertambah otomatis menumbuhkan indeks terlalu cepat, dan memengaruhi kinerja dan konsumsi memori. Jika Anda berbicara dari sudut pandang layanan web atau aplikasi web, harus ada lapisan antara basis data dan ujung depan. Yang lainnya adalah desain yang buruk. Menggunakan data sebagai kunci utama bahkan lebih buruk. Kunci primer harus digunakan hanya pada lapisan data, di tempat lain.
Drunken Code Monkey
60

Kunci autoincemental sebagian besar memiliki keunggulan.

Tetapi beberapa kelemahan yang mungkin terjadi adalah:

  • Jika Anda memiliki kunci bisnis, Anda harus menambahkan indeks unik pada kolom itu juga untuk menegakkan aturan bisnis.
  • Saat mentransfer data antara dua database, terutama ketika data berada di lebih dari satu tabel (mis. Master / detail), itu tidak langsung karena urutan tidak disinkronkan antara database, dan Anda harus membuat tabel ekivalen terlebih dahulu menggunakan kunci bisnis sebagai kecocokan untuk mengetahui ID mana dari database asal yang sesuai dengan ID mana dalam database target. Itu seharusnya tidak menjadi masalah ketika mentransfer data dari / ke tabel terisolasi.
  • Banyak perusahaan memiliki alat pelaporan ad-hoc, grafis, point-and-click, drag-and-drop. Karena ID autoincremental tidak ada artinya, tipe pengguna ini akan merasa sulit untuk memahami data di luar "aplikasi".
  • Jika Anda secara tidak sengaja memodifikasi kunci bisnis, kemungkinan Anda tidak akan pernah memulihkan baris itu karena Anda tidak lagi memiliki sesuatu untuk diidentifikasi oleh manusia. Itu menyebabkan kesalahan pada platform BitCoin sekali .
  • Beberapa desainer menambahkan ID ke tabel gabungan di antara dua tabel, ketika PK harus terdiri dari dua ID asing. Jelas jika tabel gabungan berada di antara tiga tabel atau lebih, maka ID penambahan otomatis masuk akal, tetapi kemudian Anda harus menambahkan kunci unik ketika diterapkan pada kombinasi FK untuk menegakkan aturan bisnis.

Inilah bagian artikel Wikipedia tentang kerugian kunci pengganti.

Tulains Córdova
sumber
13
Menyalahkan kesalahan mt.gox pada kunci pengganti tampaknya agak meragukan. Masalahnya adalah bahwa mereka memasukkan semua bidang dalam kunci gabungan mereka, bahkan bidang yang bisa diubah / ditempa.
CodesInChaos
6
Kerugian "sosial" dari menggunakan kunci kenaikan-otomatis adalah bahwa kadang-kadang "bisnis" mengasumsikan bahwa tidak boleh ada kesenjangan dan tuntutan untuk mengetahui apa yang terjadi pada baris yang hilang yang terjadi ketika insert gagal terjadi (rollback transaksi).
Rick Ryker
4
Kerugian lain adalah bahwa jika sistem tumbuh begitu besar sehingga Anda harus membuang database, Anda tidak dapat lagi menggunakan autoincrement untuk menghasilkan kunci unik secara global. Ketika Anda sampai pada titik itu, Anda mungkin memiliki banyak kode bergantung pada asumsi itu. Ada cara lain untuk menghasilkan pengidentifikasi unik yang akan tetap berfungsi jika database dibelokkan.
kasperd
1
@ Vooo Tidak dijamin database yang Anda pilih mendukungnya. Dan mencoba menerapkannya lapisan yang lebih tinggi dari database itu sendiri berarti Anda kehilangan beberapa jaminan SQL akan memberi Anda. Akhirnya setiap penugasan ID terpusat akan meningkatkan latensi jika Anda memiliki sistem terdistribusi.
kasperd
1
@ Voo Tentu saja terlepas dari skala sistem seseorang tidak boleh membuat terlalu banyak asumsi tentang sifat ID autoincremented. Jika Anda hanya memiliki satu database, mereka ditugaskan secara berurutan, tetapi tidak ada jaminan mereka berkomitmen secara berurutan. Dan mungkin ada kesenjangan dalam urutan karena tidak semua transaksi dilakukan.
kasperd
20

Justru sebaliknya, Tidak, Anda TIDAK perlu selalu memiliki PK AutoInc numerik.

Jika Anda menganalisis data dengan cermat, Anda sering mengidentifikasi kunci alami dalam data. Ini sering terjadi ketika data memiliki makna intrinsik untuk bisnis. Kadang-kadang PK adalah artefak dari sistem kuno yang digunakan pengguna bisnis sebagai bahasa kedua untuk menggambarkan atribut sistem mereka. Saya telah melihat nomor VIN kendaraan yang digunakan sebagai kunci utama dari tabel "Kendaraan" dalam sistem manajemen armada misalnya.

Namun itu berasal, JIKA Anda sudah memiliki pengidentifikasi unik, gunakan itu. Jangan membuat kunci primer kedua yang tidak berarti; boros dan dapat menyebabkan kesalahan.

Kadang-kadang Anda dapat menggunakan AutoInc PK untuk menghasilkan nilai bermakna pelanggan misalnya Nomor Kebijakan. Menetapkan nilai awal untuk sesuatu yang masuk akal dan menerapkan aturan bisnis tentang memimpin nol dll. Ini mungkin merupakan pendekatan "terbaik dari kedua dunia".

Ketika Anda memiliki sejumlah kecil nilai yang relatif statis, gunakan nilai yang masuk akal bagi pengguna sistem. Mengapa menggunakan 1,2,3 ketika Anda bisa menggunakan L, C, H di mana L, H dan C mewakili Life, Car dan Home dalam konteks "Tipe Kebijakan" asuransi, atau, kembali ke contoh VIN, bagaimana menggunakan "TO "untuk Toyota? Semua mobil Toyata memiliki VIN yang dimulai dengan "TO". Satu hal yang kurang diingat oleh pengguna, membuatnya lebih kecil kemungkinannya untuk memperkenalkan pemrograman dan kesalahan pengguna dan bahkan bisa menjadi pengganti yang dapat digunakan untuk deskripsi lengkap dalam laporan manajemen sehingga laporan menjadi lebih sederhana untuk menulis dan mungkin lebih cepat untuk menghasilkan.

Pengembangan lebih lanjut dari ini mungkin "jembatan terlalu jauh" dan saya biasanya tidak merekomendasikannya tapi saya memasukkannya untuk kelengkapan dan Anda mungkin menemukan manfaatnya. Yaitu, gunakan Deskripsi sebagai Kunci Utama. Untuk mengubah data dengan cepat, ini adalah kekejian. Untuk data yang sangat statis yang dilaporkan di All The Time , mungkin tidak. Sebut saja jadi itu duduk di sana sebagai kemungkinan.

Saya DO menggunakan PK AutoInc, saya hanya melibatkan otak saya dan mencari alternatif yang lebih baik terlebih dahulu. Seni desain database membuat sesuatu yang bermakna yang dapat ditanyakan dengan cepat. Terlalu banyak bergabung menghalangi ini.

EDIT Satu kasus penting lainnya di mana Anda tidak memerlukan PK Autogenerated adalah kasus tabel yang mewakili persimpangan dua tabel lainnya. Untuk tetap dengan analogi Mobil, A Car memiliki 0..n Aksesori, Setiap Aksesori dapat ditemukan di banyak mobil. Jadi untuk mewakili ini, Anda membuat tabel Car_Accessory yang berisi PK dari Mobil dan Aksesori dan informasi terkait lainnya tentang tautan Tanggal, dll.

Yang tidak Anda perlukan (biasanya) adalah AutoInc PK di tabel ini - ini hanya akan diakses melalui mobil "beri tahu saya aksesori apa yang ada di mobil ini" atau dari Aksesori "beri tahu mereka mobil yang memiliki aksesori ini"

mcottle
sumber
4
> Semua mobil Toyata memiliki VIN yang mulai "TO" Itu tidak benar. Mereka mulai dengan "JT" jika dibuat di Jepang. Toyotas buatan Amerika memiliki VIN yang sama sekali berbeda en.wikibooks.org/wiki/…
Monty Harder
17
Don't create a second, meaningless primary key; it's wasteful and may cause errors.Namun, jika cara Anda membangun keunikan untuk suatu catatan adalah kombinasi dari 6 kolom, maka bergabung pada semua 6 sepanjang waktu sangat rentan terhadap kesalahan itu sendiri. Data secara alami memang memiliki PK tetapi Anda lebih baik menggunakan idkolom dan kendala unik pada 6 kolom tersebut.
Brad
14
Saya akui beberapa saran ini agak jauh bagi saya. Ya, menjadi pragmatis baik-baik saja, tetapi saya tidak dapat menghitung seberapa sering seseorang bersumpah demi kehidupan anak sulungnya sehingga beberapa atribut di luar domain akan tetap unik selama sisa hari. Yah, biasanya itu bekerja dengan baik sampai minggu kedua setelah ditayangkan, ketika duplikat pertama muncul. ;) Menggunakan "deskripsi" sebagai PK sangat jauh.
AnoE
2
@Onty, salahku, kau benar. Memori yang salah, sudah 20 tahun sejak saya merancang sistem manajemen armada. Tidak, VIN bukan kunci utama :) Saya menggunakan AutoInc Asset_ID IIRC yang mengarah ke sesuatu yang saya lupa. Tabel yang merupakan penghubung untuk hubungan banyak ke banyak tempat Anda menautkan, misalnya, mobil ke aksesori (misalnya sunroof) Banyak mobil memiliki banyak aksesori sehingga Anda memerlukan tabel "Car_Accessory" yang berisi Car_ID dan Accessory_ID tetapi sama sekali TIDAK membutuhkan Car_Accesory_ID sebagai sebuah AutoInc PK.
mcottle
7
Sungguh menakjubkan betapa sedikit "kunci alam" yang SANGAT abadi yang ada. SSN? Tidak, mereka bisa berubah. Ini jarang terjadi, tetapi itu bisa terjadi. Nama pengguna? Nggak. Akhirnya seseorang akan memiliki alasan bisnis yang sah untuk berubah. VIN sering menjadi contoh buku teks, tetapi tidak banyak yang lain. Bahkan alamat rumah dapat berubah, mengingat perubahan penamaan jalan.
Erik Funkenbusch
12

Banyak tabel sudah memiliki id unik alami. Jangan menambahkan kolom id unik lain (peningkatan otomatis atau lainnya) ke tabel ini. Gunakan id unik alami sebagai gantinya. Jika Anda menambahkan id unik lain, pada dasarnya Anda memiliki redundansi (duplikasi atau ketergantungan) dalam data Anda. Ini bertentangan dengan prinsip normalisasi. Satu id unik tergantung pada yang lain untuk akurasi. Ini berarti bahwa mereka harus tetap sinkron dengan sempurna setiap saat di setiap sistem yang mengelola baris ini. Ini hanya kerapuhan lain dalam integritas data Anda yang Anda tidak ingin harus mengelola dan memvalidasi untuk jangka panjang.

Sebagian besar tabel saat ini tidak benar-benar membutuhkan peningkatan kinerja yang sangat kecil yang diberikan oleh kolom id unik tambahan (dan kadang-kadang bahkan mengurangi kinerja). Sebagai aturan umum dalam TI, hindari redundansi seperti wabah! Menahannya di mana saja disarankan untuk Anda. Ini laknat. Dan perhatikan kutipannya. Semuanya harus sesederhana mungkin, tetapi tidak sederhana. Jangan memiliki dua id unik di mana satu akan cukup, bahkan jika yang alami tampaknya kurang rapi.

Brad Thomas
sumber
3
Tidakkah seharusnya Anda hanya menggunakan ID "alami" sebagai kunci utama jika dijamin tidak akan pernah berubah? Misalnya, Anda tidak boleh menggunakan nomor SIM sebagai kunci utama, karena jika seseorang mendapat SIM baru, Anda harus memperbarui tidak hanya tabel itu tetapi tabel apa pun dengan kunci asing yang merujuknya!
ekolis
1
Ada beberapa alasan mengapa nomor SIM tidak memenuhi syarat sebagai id unik alami. Pertama beberapa dari mereka berasal dari data lain, seperti tanggal lahir dan nama. Mereka tidak dijamin unik di seluruh negara bagian. Dan untuk mengambil contoh Anda, ketika seseorang menerbitkan kembali lisensi dengan nomor yang sama, tetapi mungkin masa berlakunya diperpanjang, apa yang terjadi kemudian? Mereka memiliki lisensi berbeda dengan nomor yang sama. Id alami masih harus memenuhi properti dasar dari primary key. Nomor SIM (setidaknya di AS) memiliki beberapa kekurangan dalam hal ini.
Brad Thomas
1
OK, saya kira saya salah paham tentang definisi natural ID; Saya pikir itu hanya ID yang ditentukan oleh aturan bisnis, apakah itu benar-benar dijamin tidak dapat diubah.
ekolis
10

Pada sistem yang lebih besar, ID adalah booster konsistensi, gunakan hampir di mana saja. Dalam konteks ini, masing-masing kunci primer TIDAK direkomendasikan, mereka mahal di garis bawah (baca alasannya).

Setiap aturan memiliki pengecualian, jadi Anda mungkin tidak perlu ID autoincrement integer pada tabel staging yang digunakan untuk ekspor / impor dan pada tabel satu arah atau tabel sementara yang serupa. Anda juga akan lebih memilih GUID daripada ID pada sistem terdistribusi.

Banyak jawaban di sini menunjukkan bahwa kunci unik yang ada harus diambil. Yah bahkan jika itu memiliki 150 karakter? Saya kira tidak.

Sekarang poin utama saya:

Tampaknya lawan ID bilangan bulat autoincrement berbicara tentang database kecil hingga 20 tabel. Di sana mereka mampu melakukan pendekatan individual ke setiap tabel.

TETAPI begitu Anda memiliki ERP dengan 400 tabel, memiliki integer autoincrement ID di mana saja (kecuali kasus yang disebutkan di atas) masuk akal. Anda tidak bergantung pada bidang unik lainnya bahkan jika itu ada dan dijamin untuk keunikan.

  • Anda mendapat manfaat dari konvensi universal yang hemat waktu, hemat, dan mudah diingat.
  • Dalam kebanyakan kasus Anda membuat JOINtabel, tanpa perlu memeriksa apa kuncinya.
  • Anda dapat memiliki rutinitas kode universal yang bekerja dengan kolom autoincrement integer Anda.
  • Anda dapat memperluas sistem Anda dengan tabel baru atau plugin pengguna yang tidak diramalkan sebelumnya hanya dengan merujuk ke ID dari tabel yang ada. Mereka sudah ada sejak awal, tidak ada biaya untuk menambahkannya juga.

Pada sistem yang lebih besar, ada baiknya mengabaikan manfaat kecil dari masing-masing kunci primer dan secara konsisten menggunakan ID bilangan bulat autoreguler dalam kebanyakan kasus. Menggunakan bidang unik yang ada sebagai kunci utama mungkin menghemat beberapa byte per catatan tetapi penyimpanan tambahan atau waktu pengindeksan tidak menimbulkan masalah di mesin basis data saat ini. Sebenarnya Anda kehilangan lebih banyak uang dan sumber daya pada waktu yang terbuang dari pengembang / pengelola. Perangkat lunak saat ini harus dioptimalkan untuk waktu dan upaya programmer - pendekatan apa yang memenuhi ID konsisten jauh lebih baik.

miroxlav
sumber
Dari pengalaman pribadi, saya sepenuh hati setuju dengan bagian kedua dari jawaban Anda. Anda akan membutuhkan kunci unik secara global jauh, jauh lebih jarang daripada Anda akan membutuhkan indeks cepat dan kompak. Jika Anda memang membutuhkannya, buat tabel GlobalEntities dengan ID yang di-autogenerasi dan kolom UUID. Kemudian tambahkan kunci asing ExGlobalEntityId ke tabel Pelanggan misalnya. Atau gunakan hash dari beberapa nilai.
Drunken Code Monkey
8

Ini bukan praktik yang baik untuk desain berlebihan. Yaitu - itu bukan praktik yang baik untuk selalu memiliki kunci primer int auto increment ketika seseorang tidak diperlukan.

Mari kita lihat contoh di mana seseorang tidak diperlukan.

Anda memiliki tabel untuk artikel - ini memiliki kunci primer int id, dan kolom varchar bernama title.

Anda juga memiliki tabel yang penuh dengan kategori idartikel– int primary key, varchar name.

Satu baris dalam tabel Artikel memiliki id5, dan title "Cara memasak angsa dengan mentega". Anda ingin menautkan artikel itu dengan baris berikut di tabel Kategori Anda: "Fowl" ( id : 20), "Goose" ( id : 12), "Cooking" ( id : 2), "Butter" (id: 9) .

Sekarang, Anda memiliki 2 tabel: artikel dan kategori. Bagaimana Anda menciptakan hubungan di antara keduanya?

Anda bisa memiliki tabel dengan 3 kolom: id (kunci utama), article_id (kunci asing), category_id (kunci asing). Tetapi sekarang Anda memiliki sesuatu seperti:

| id | a_id | c_id |
| 1 | 5 | 20 |
| 2 | 5 | 12 |
| 3 | 5 | 2 |

Solusi yang lebih baik adalah memiliki kunci utama yang terdiri dari 2 kolom.

| a_id | c_id |
| 5 | 20 |
| 5 | 12 |
| 5 | 2 |

Ini dapat dicapai dengan melakukan:

create table articles_categories (
  article_id bigint,
  category_id bigint,
  primary key (article_id, category_id)
) engine=InnoDB;

Alasan lain untuk tidak menggunakan integer kenaikan otomatis adalah jika Anda menggunakan UUID untuk kunci utama Anda.

UUID menurut definisi mereka unik, yang melakukan hal yang sama dengan menggunakan integer unik. Mereka juga memiliki manfaat tambahan (dan kontra) mereka sendiri di atas bilangan bulat. Misalnya, dengan UUID, Anda tahu bahwa string unik yang Anda maksudkan menunjuk ke catatan data tertentu; ini berguna dalam kasus di mana Anda tidak memiliki 1 basis data pusat, atau di mana aplikasi memiliki kemampuan untuk membuat catatan data offline (kemudian unggah ke database di kemudian hari).

Pada akhirnya, Anda tidak perlu memikirkan kunci primer sebagai suatu hal. Anda perlu menganggap mereka sebagai fungsi yang mereka lakukan. Mengapa Anda memerlukan kunci utama? Untuk dapat mengidentifikasi secara unik set data tertentu dari tabel menggunakan bidang yang tidak akan diubah di masa mendatang. Apakah Anda memerlukan kolom tertentu yang dipanggil iduntuk melakukan ini, atau dapatkah Anda mendasarkan identifikasi unik ini dari data lain (tidak dapat diubah)?

anw
sumber
7

Atau ada skenario di mana Anda tidak ingin menambahkan bidang seperti itu?

Tentu.

Pertama-tama, ada database yang tidak memiliki autoincrements (misalnya, Oracle, yang tentunya bukan salah satu pesaing terkecil di sekitar). Ini harus menjadi indikasi pertama bahwa tidak semua orang menyukai atau membutuhkannya.

Lebih penting, berpikir tentang apa ID sebenarnya adalah - itu adalah kunci utama untuk data Anda. Jika Anda memiliki tabel dengan kunci utama yang berbeda, maka Anda tidak perlu ID, dan tidak boleh memilikinya. Misalnya, sebuah tabel (EMPLOYEE_ID, TEAM_ID)(di mana setiap karyawan dapat berada di beberapa tim secara bersamaan) memiliki kunci utama yang jelas terdiri dari dua ID tersebut. Menambahkan IDkolom peningkatan otomatis , yang juga menjadi kunci utama untuk tabel ini, tidak masuk akal sama sekali. Sekarang Anda menyeret 2 kunci utama, dan kata pertama dalam "kunci utama" akan memberi Anda petunjuk bahwa Anda benar-benar hanya memiliki satu.

AnoE
sumber
9
(Bukan pengguna Oracle jadi maafkan pertanyaannya tetapi) bukankah Oracle menggunakan Sequence dengan cara yang sama seperti orang lain menggunakan Autoincrement / Identity? Apakah mengatakan bahwa Oracle tidak memiliki tipe data Autoincrement benar-benar hanya argumen sematik?
Brad
Ya, itu hanya poin kecil; bagian utama adalah bahwa ID berjalan tidak sesuai untuk setiap tabel, sehingga membiasakan diri dengan hanya menampar ID-otomatis pada setiap tabel mungkin bukan yang paling bijaksana.
AnoE
tidak ada dua kunci primer, hanya ada satu kunci primer dan semua sisanya disebut kunci kandidat jika mereka dapat berfungsi sebagai kunci primer juga ..
rahul tyagi
7

Saya biasanya menggunakan kolom "identitas" (integer peningkatan-otomatis) ketika mendefinisikan tabel baru untuk data "berumur panjang" (catatan saya berharap untuk memasukkan sekali dan tetap di sekitar tanpa batas bahkan jika akhirnya "dihapus secara logis" dengan menetapkan sedikit bidang ).

Ada beberapa situasi yang dapat saya pikirkan ketika Anda tidak ingin menggunakannya, yang sebagian besar mengarah ke skenario di mana satu tabel pada satu contoh DB tidak bisa menjadi sumber otoritatif untuk nilai ID baru:

  • Ketika ID tambahan akan terlalu banyak informasi untuk penyerang potensial. Penggunaan kolom identitas untuk layanan data "menghadap publik" membuat Anda rentan terhadap "Masalah Tank Jerman"; jika record id 10234 ada, maka masuk akal bahwa record 10233, 10232, dll ada, kembali ke setidaknya record 10001, dan kemudian mudah untuk memeriksa record 1001, 101 dan 1 untuk mencari tahu dari mana kolom identitas Anda dimulai. GUID V4 yang terdiri dari sebagian besar data acak memecah perilaku inkremental ini dengan desain, sehingga hanya karena satu GUID ada, GUID yang dibuat dengan menambah atau mengurangi satu byte GUID tidak selalu ada, sehingga mempersulit penyerang untuk menggunakan layanan yang diminta. untuk pengambilan rekaman tunggal sebagai alat dump. Ada langkah-langkah keamanan lain yang dapat membatasi akses dengan lebih baik, tetapi ini membantu.
  • Dalam M: M tabel referensi silang. Ini semacam beri tapi aku sudah pernah melihatnya. Jika Anda memiliki hubungan banyak-ke-banyak antara dua tabel dalam database Anda, solusi masuk adalah tabel referensi silang yang berisi kolom kunci asing yang merujuk PK masing-masing tabel. PK tabel ini harus selalu menjadi kunci majemuk dari dua kunci asing, untuk mendapatkan perilaku indeks bawaan dan untuk memastikan keunikan referensi.
  • Ketika Anda berencana untuk memasukkan dan menghapus secara massal di tabel ini banyak. Mungkin kerugian terbesar untuk kolom identitas adalah kehebohan ekstra yang harus Anda lalui ketika melakukan penyisipan baris dari tabel atau kueri lain, tempat Anda ingin mempertahankan nilai kunci tabel asli. Anda harus mengaktifkan "sisipan identitas" (namun itu dilakukan dalam DBMS Anda), lalu secara manual pastikan kunci yang Anda masukkan unik, dan kemudian ketika Anda selesai dengan impor Anda harus mengatur penghitung identitas di metadata tabel hingga nilai maksimum yang ada. Jika operasi ini sering terjadi pada tabel ini, pertimbangkan skema PK yang berbeda.
  • Untuk tabel terdistribusi.Kolom identitas bekerja sangat baik untuk database satu-contoh, pasangan failover, dan skenario lain di mana satu contoh database adalah otoritas tunggal pada seluruh skema data pada waktu tertentu. Namun, hanya ada begitu besar Anda dapat pergi dan masih memiliki satu komputer yang cukup cepat. Replikasi atau pengiriman log transaksi dapat memberi Anda salinan read-only tambahan, tetapi ada batasan untuk skala solusi itu juga. Cepat atau lambat Anda akan memerlukan dua atau lebih server contoh yang menangani memasukkan data dan kemudian menyinkronkan satu sama lain. Ketika situasi itu datang, Anda akan menginginkan bidang GUID alih-alih bidang tambahan, karena sebagian besar DBMS telah dikonfigurasikan sebelumnya untuk menggunakan sebagian dari GUID yang mereka hasilkan sebagai pengenal spesifik-instance, kemudian buat sisa pengidentifikasi baik secara acak atau secara bertahap. Dalam kedua kasus tersebut,
  • Ketika Anda harus menegakkan keunikan di beberapa tabel di DB.Adalah umum dalam sistem akuntansi, misalnya, untuk mengelola Buku Besar (dengan baris untuk setiap kredit atau debit dari setiap akun yang pernah terjadi, sehingga menjadi sangat besar dengan sangat cepat) sebagai urutan tabel yang masing-masing mewakili satu bulan kalender / tahun. Tampilan kemudian dapat dibuat untuk menyatukan mereka untuk pelaporan. Secara logis, ini semua adalah tabel yang sangat besar, tetapi memotongnya membuat pekerjaan pemeliharaan DB lebih mudah. Namun, ini menyajikan masalah bagaimana mengelola sisipan ke dalam beberapa tabel (memungkinkan Anda untuk mulai mencatat transaksi di bulan berikutnya sambil tetap menutup yang terakhir) tanpa berakhir dengan kunci duplikat. Sekali lagi, GUID, bukan kolom integer identitas adalah solusi masuk, karena DBMS dirancang untuk menghasilkan ini dengan cara yang benar-benar unik,

Ada solusi yang memungkinkan penggunaan kolom identitas dalam situasi ini, seperti yang saya harapkan, tetapi dalam sebagian besar dari ini, peningkatan dari kolom integer identitas ke GUID lebih sederhana dan menyelesaikan masalah lebih lengkap.

KeithS
sumber
1
Ada kasus Anda masih bisa memerlukan ID dalam tabel M: N (menggunakan kolom ID, ID_M, ID_N) karena melampirkan properti ke instance relasi M: N Anda.
miroxlav
V4 GUIDS tidak dijamin untuk menggunakan PNRG yang kuat secara kriptografis sehingga Anda benar-benar tidak boleh mengandalkannya untuk imo contoh pertama Anda (meskipun jika mesin db Anda membuat janji yang lebih kuat Anda mungkin baik-baik saja, tapi itu agak tidak portabel). Sebaliknya posting yang beralasan.
Voo
1
@miroxlav - Saya akan menegaskan bahwa jika sebuah tabel memiliki metadata tambahan yang cukup mengenai hubungan bahwa PK terpisah di luar dua FK adalah ide yang baik, itu bukan tabel referensi silang lagi; entitasnya sendiri yang merujuk dua lainnya.
KeithS
@Voo - Anda benar, GUID V4 tidak dijamin acak secara kriptografis, hanya unik (seperti halnya GUID lainnya). Namun, jumlah ekor jet tempur AS juga tidak dihasilkan dari data / algoritma seed acak acak. Apa yang benar-benar Anda cari adalah domain yang jarang penduduknya; sebuah V4 GUID memiliki 112 byte data acak, yang mampu mengidentifikasi secara unik 5e33 catatan.
KeithS
Untuk menempatkan angka itu dalam perspektif, setiap pria, wanita, dan anak-anak di planet ini (semuanya 7 miliar) dapat memiliki 741 triliun yang secara individual didata dan didata poin data dalam DB kami, dan kami hanya akan menggunakan satu nilai GUID per miliar yang tersedia. Big Data, sebagai industri global, bahkan tidak mendekati skala pengetahuan ini. Meskipun diberi pola untuk pembuatan GUID, ada sumber entropi lain yang terlibat, seperti urutan di mana data memasuki sistem dan diberi GUID.
KeithS
7

Kunci primer yang ditambahkan secara otomatis (identitas) adalah ide yang baik kecuali untuk mencatat bahwa itu tidak berarti di luar konteks database dan klien langsung dari database tersebut. Misalnya, jika Anda mentransfer dan menyimpan beberapa data di database lain, kemudian lanjutkan untuk menulis data yang berbeda untuk kedua tabel database, id akan berbeda - yaitu, data dengan id 42 dalam satu database tidak akan selalu cocok dengan data dengan id 42 di yang lain.

Mengingat hal ini, jika perlu masih dapat mengidentifikasi baris secara unik di luar basis data (dan memang sering demikian), maka Anda harus memiliki kunci yang berbeda untuk tujuan ini. Kunci bisnis yang dipilih dengan cermat akan berhasil, tetapi Anda akan sering berakhir di posisi sejumlah besar kolom yang diperlukan untuk menjamin keunikan. Teknik lain adalah memiliki kolom Id sebagai kunci primer clustered auto-increment dan kolom pengenal unik lainnya (guid) sebagai kunci unik yang tidak dikelompokkan, untuk keperluan mengidentifikasi baris secara unik di mana pun baris itu ada di dunia. Alasan Anda masih memiliki kunci yang ditambahkan otomatis dalam kasus ini adalah karena lebih efisien untuk mengelompokkan dan mengindeks kunci penambahan otomatis daripada melakukan hal yang sama pada pemandu.

Satu kasus di mana Anda mungkin tidak ingin kunci penambahan otomatis akan menjadi tabel banyak-ke-banyak di mana kunci primer adalah gabungan dari kolom Id dari dua tabel lain (Anda masih bisa memiliki kunci penambahan otomatis di sini, tapi saya tidak mengerti maksudnya).

Satu pertanyaan lain adalah tipe data dari kunci yang ditambahkan otomatis. Menggunakan Int32 memberi Anda rentang nilai yang besar, tetapi relatif terbatas. Secara pribadi saya sering menggunakan kolom bigint untuk ID, agar secara praktis tidak perlu khawatir kehabisan nilai.

MatthewHari ini
sumber
6

Karena orang lain telah membuat kasus untuk kunci primer yang bertambah saya akan membuat satu untuk GUID:

  • Dijamin unik
  • Anda dapat memiliki satu perjalanan lebih sedikit ke database untuk data dalam aplikasi Anda. (Untuk tabel jenis misalnya, Anda dapat menyimpan GUID dalam aplikasi dan menggunakannya untuk mengambil catatan. Jika Anda menggunakan identitas, Anda perlu menanyakan database dengan nama dan saya telah melihat banyak aplikasi yang melakukan ini untuk mendapatkan PK dan kemudian bertanya lagi untuk mendapatkan detail lengkap).
  • Ini berguna untuk menyembunyikan data. www.domain.com/Article/2 Beritahu saya bahwa Anda hanya memiliki dua artikel sedangkan www.domain.com/article/b08a91c5-67fc-449f-8a50-ffdf2403444a tidak memberi tahu saya apa pun.
  • Anda dapat menggabungkan catatan dari basis data yang berbeda dengan mudah.
  • MSFT menggunakan GUIDS untuk identitas.

Edit: Titik Gandakan

Tiga Logika Nilai
sumber
5
-1. GUID / UUID tidak dijamin unik, dan tidak 100% unik. GUID masih terbatas, jadi pada titik tertentu Anda bisa mengambil risiko duplikat, meskipun sangat tidak mungkin. Poin Anda tentang lebih sedikit perjalanan ke database juga tidak valid - mengapa Anda tidak dapat menyimpan id utama dalam aplikasi, seperti yang Anda bisa dengan kunci GUID?
Niklas H
2
Jeff Atwood mengatakan itu jauh lebih baik daripada yang pernah saya bisa. blog.codinghorror.com/primary-keys-ids-versus-guids
Three Value Logic
Adapun mengapa Anda tidak dapat menyimpan id utama dalam aplikasi Anda? Karena database menciptakannya. Jika Anda menjalankan benih pada basis data kosong, Anda dapat mengasumsikan bahwa ID tersebut adalah 1. Bagaimana jika Anda menjalankan skrip yang sama pada database dengan data di dalamnya? ID tidak akan 1.
Tiga Nilai Logika
Anda tidak mengatakan apa-apa tentang membuat ID dalam aplikasi - Anda baru saja menulis "menyimpan". Tetapi jika perlu untuk membuat ID di luar database, maka ya, sebuah GUID bisa menjadi jawabannya.
Niklas H
2
Saya akan menambahkan skala mereka lebih baik. Data besar Basis data NoSQL seperti Cassandra bahkan tidak mendukung kunci kenaikan otomatis.
Karl Bielefeldt
2

Sebagai prinsip desain yang baik, setiap tabel harus memiliki cara yang andal untuk mengidentifikasi satu baris secara unik. Meskipun untuk itulah kunci primer diperuntukkan, itu tidak selalu mensyaratkan keberadaan kunci primer. Menambahkan kunci utama ke setiap tabel bukan praktik yang buruk karena memberikan identifikasi baris yang unik, tetapi mungkin tidak perlu.

Untuk menjaga hubungan yang andal antara baris dua atau lebih tabel, Anda perlu melakukannya melalui kunci asing, karenanya kebutuhan untuk kunci utama di setidaknya beberapa tabel. Menambahkan kunci utama ke setiap tabel memudahkan untuk memperluas desain database Anda ketika tiba saatnya untuk menambahkan tabel baru atau hubungan ke data yang ada. Perencanaan ke depan selalu merupakan hal yang baik.

Sebagai prinsip dasar (aturan keras mungkin), nilai kunci primer tidak boleh berubah sepanjang umur barisnya. Adalah bijaksana untuk mengasumsikan bahwa data bisnis apa pun secara berurutan dapat berubah sepanjang hidupnya, sehingga data bisnis apa pun akan menjadi kandidat yang buruk untuk kunci utama. Inilah sebabnya mengapa sesuatu yang abstrak seperti bilangan bulat yang ditambahkan secara otomatis seringkali merupakan ide yang bagus. Namun, bilangan bulat yang bertambah secara otomatis memang memiliki keterbatasan.

Jika data Anda hanya akan memiliki kehidupan dalam database Anda, bilangan bulat yang ditambahkan secara otomatis baik-baik saja. Tetapi, seperti yang telah disebutkan dalam jawaban lain, jika Anda ingin data Anda dibagikan, disinkronkan, atau memiliki kehidupan di luar basis data Anda, bilangan bulat yang bertambah secara otomatis membuat kunci utama yang buruk. Pilihan yang lebih baik adalah panduan (alias uuid "id unik universal").

Zenilogix
sumber
2

Pertanyaan, dan banyak jawaban, kehilangan poin penting bahwa semua kunci alami untuk setiap tabel berada hanya dalam skema logis untuk database, dan semua kunci pengganti untuk setiap tabel berada hanya dalam skema fisik untuk database. jawaban lain hanya membahas manfaat relatif kunci pengganti bilangan bulat versus GUID, tanpa membahas alasan mengapa kunci pengganti digunakan dengan benar, dan kapan.

BTW: Mari kita hindari penggunaan kunci primer istilah yang tidak jelas dan tidak tepat . Ini adalah artefak dari model data pra-relasional yang pertama kali dikooptasi (secara tidak bijaksana) ke dalam model relasional, dan kemudian dikooptasi kembali ke domain fisik oleh berbagai vendor RDBMS. Penggunaannya hanya untuk membingungkan semantik.

Perhatikan dari model relasional bahwa, agar skema logis database berada dalam bentuk normal pertama , setiap tabel harus memiliki kumpulan bidang yang terlihat oleh pengguna, yang dikenal sebagai kunci alami, yang secara unik mengidentifikasi setiap baris tabel. Dalam kebanyakan kasus kunci alami seperti itu mudah diidentifikasi, tetapi kadang-kadang seseorang harus dibangun, apakah sebagai bidang pemutus dasi atau sebaliknya. Namun kunci yang dikonstruksi seperti itu selalu tetap terlihat oleh pengguna, dan dengan demikian selalu berada dalam skema logis dari database.

Sebaliknya setiap kunci pengganti di atas meja berada murni dalam skema fisik untuk basis data (dan karenanya harus selalu, baik karena alasan keamanan dan untuk pemeliharaan integritas basis data, sepenuhnya tidak terlihat oleh pengguna basis data). Satu-satunya alasan untuk memperkenalkan kunci pengganti adalah untuk mengatasi masalah kinerja dalam pemeliharaan fisik dan penggunaan DB; apakah itu gabungan, replikasi, beberapa sumber perangkat keras untuk data, atau lainnya.

Karena satu-satunya alasan untuk memperkenalkan kunci pengganti adalah kinerja, marilah kita menganggap bahwa kita ingin itu menjadi penampil. Jika masalah kinerja yang dihadapi adalah bergabung, maka kami tentu ingin membuat kunci pengganti kami sesempit mungkin (tanpa menghalangi perangkat keras, sehingga bilangan bulat pendek dan byte biasanya keluar). Kinerja gabungan bergantung pada tinggi indeks minimal, sehingga integer 4-byte adalah solusi alami. Jika masalah kinerja Anda adalah tingkat penyisipan, integer 4-byte juga dapat menjadi solusi alami (tergantung pada internal RDBMS Anda). Jika masalah kinerja Anda untuk tabel adalah replikasi atau beberapa sumber data dibandingkan beberapa teknologi kunci pengganti lainnya , baik itu GUID atau kunci dua bagian (Host ID + integer) mungkin lebih cocok. Saya pribadi bukan favorit GUID tetapi nyaman.

Singkatnya, tidak semua tabel akan membutuhkan kunci pengganti (jenis apa pun); mereka hanya boleh digunakan jika dianggap perlu untuk kinerja tabel yang sedang dipertimbangkan. Terlepas dari teknologi pengganti mana yang Anda sukai, pikirkan baik-baik tentang kebutuhan sebenarnya dari tabel sebelum membuat pilihan; mengubah pilihan teknologi kunci pengganti untuk sebuah meja akan sangat melelahkan. Dokumentasikan metrik kinerja utama untuk meja Anda sehingga penerus Anda akan memahami pilihan yang dibuat.

Kasus khusus

  1. Jika persyaratan bisnis Anda mengamanatkan penomoran berurutan transaksi untuk keperluan audit (atau lainnya) daripada bidang itu bukanlah kunci pengganti; itu adalah kunci alami (dengan persyaratan tambahan). Dari dokumentasi, integer peningkatan-otomatis hanya menghasilkan kunci pengganti , jadi temukan mekanisme lain untuk membuatnya. Jelas beberapa jenis monitor akan diperlukan, dan jika Anda mengambil sumber transaksi Anda dari beberapa situs maka satu situs akan istimewa , berdasarkan menjadi situs host yang ditunjuk untuk monitor.

  2. Jika meja Anda tidak akan pernah lebih dari sekitar seratus baris, maka tinggi indeks tidak relevan; setiap akses akan dilakukan dengan pemindaian tabel. Namun perbandingan string pada string panjang masih akan jauh lebih mahal daripada perbandingan integer 4-byte, dan lebih mahal daripada perbandingan GUID.

  3. Tabel nilai kode yang dikunci oleh bidang kode char (4) harus sama performannya dengan yang memiliki bilangan bulat 4-byte. Meskipun saya tidak punya bukti tentang ini, saya sering menggunakan asumsi ini dan tidak pernah punya alasan untuk menyesalinya.

Pieter Geerkens
sumber
-1

Bukan hanya itu bukan praktik yang baik, pada kenyataannya itu digambarkan sebagai anti-pola dalam buku Antiperner SQL karya Bill Karwin.

Tidak setiap tabel membutuhkan pseudokey - kunci utama dengan nilai arbitrer, bukan sesuatu yang memiliki nilai semantik untuk model -, dan tidak ada alasan untuk selalu menyebutnya id.

Pedro Werneck
sumber
ini tampaknya tidak menawarkan sesuatu yang substansial atas poin yang dibuat dan dijelaskan dalam 9 jawaban sebelumnya
nyamuk
2
dan mengapa ini bisa menjadi penting?
nyamuk
3
@gnat Karena ini buku tentang praktik terbaik, yang langsung menjawab pertanyaan. Bukankah sudah jelas?
Pedro Werneck
3
tidak sedikitpun. Pencarian Google untuk "book sql best practices" menunjukkan sekitar 900 ribu tautan kepada saya, mengapa yang satu ini sangat layak
nyamuk
1
@gnat, saya tidak akan berdebat sepanjang hari. Anda tidak suka jawabannya, itulah gunanya downvotes.
Pedro Werneck
-2

Ini cukup universal - jika tidak, Anda perlu memvalidasi bahwa kuncinya sebenarnya unik. Ini akan dilakukan dengan melihat semua kunci lain ... yang akan memakan waktu. Memiliki kunci tambahan menjadi mahal karena nomor catatan Anda mendekati nilai overflow kunci.

Saya biasanya membuat pointer nama bidang lebih jelas seperti ref_{table}atau ide serupa.

Jika tidak perlu untuk menunjuk ke catatan maka Anda tidak perlu id.

Johnny V
sumber
Nilai rollover kunci?
AJJ
Bilangan bulat yang tidak ditandatangani memiliki nilai maksimal 4294967295 sebelum menambahkan 1 akan menggulungnya menjadi 0. Ingat jika Anda menambahkan catatan lalu menghapusnya, penghitung masih meningkat. Pastikan Anda menggunakan unsigned intuntuk jenis bidang jika batasnya adalah setengah dari angka itu.
Johnny V
Integer Overflow - en.wikipedia.org/wiki/Integer_overflow
Johnny V
2
Jika Anda menambahkan / menghapus banyak baris, penghitung kenaikan otomatis pada akhirnya akan meluap.
Johnny V
1
Bagaimana orang menangani rollover? Bagaimana jika ada catatan dengan ID rendah yang tidak pernah dihapus, tetapi Anda mulai mendekati akhir di mana beberapa ID berada di ujung atas 4294967295? Apakah "pengindeksan ulang" dapat dilakukan?
AJJ
-2

Saya tidak akan mengatakan itu harus selalu dilakukan. Saya punya meja di sini tanpa kunci unik - dan tidak perlu. Ini adalah log audit. Tidak akan pernah ada pembaruan, kueri akan mengembalikan semua perubahan ke apa yang sedang dicatat tetapi itu adalah yang terbaik yang dapat dilakukan secara wajar. Perlu manusia untuk mendefinisikan perubahan yang salah. (Jika kodenya bisa, itu tidak diizinkan di tempat pertama!)

Loren Pechtel
sumber
-3

Penghitung kenaikan otomatis untuk kunci utama bukan ide yang baik. Itu karena Anda harus kembali ke database untuk menemukan kunci berikutnya dan ditambahkan satu per satu sebelum memasukkan data Anda.

Bahwa menjadi kata saya biasanya akan menggunakan apa pun yang dapat menyediakan database untuk kunci utama daripada memilikinya sebagai bagian dari aplikasi.

Dengan membiarkan database menyediakannya untuk Anda, ia dapat menjamin kunci untuk menjadi unik untuk apa yang dibutuhkannya.

Tentu saja tidak semua database mendukungnya. Dalam hal ini saya biasanya menggunakan tabel yang menyimpan ember kunci dan menggunakan rentang tinggi dan rendah yang dikelola dalam aplikasi. Ini adalah solusi paling berkinerja yang saya temukan karena Anda mendapatkan kisaran 10.000 nomor dan secara otomatis menambahnya pada contoh aplikasi. Contoh aplikasi lain dapat mengambil ember nomor lain untuk digunakan. Anda memang membutuhkan kunci primer primitif yang cukup besar seperti panjang 64-bit.

UUID Saya tidak menggunakan sebagai kunci utama karena biaya membangun dan menyimpannya jauh lebih tinggi daripada menambah nilai yang panjang satu per satu. UUID masih berurusan dengan paradoks ulang tahun di mana duplikat secara teoritis dapat muncul.

Archimedes Trajano
sumber
3
Tidak. Kunci penambahan otomatis berarti bahwa penambahan kunci dilakukan secara otomatis oleh database. Terkadang (saya melihat Anda, Oracle!) Anda memerlukan kombinasi urutan + pemicu untuk melakukannya, tetapi Anda tidak perlu melihat nilai yang dimasukkan sebelumnya untuk kunci, tambahkan 1, lalu gunakan.
SQB
Dengan beberapa kerangka kerja yang gigih seperti JPA jika Anda ingin mengembalikan nilai kunci yang telah dibuat kembali ke pemanggil, Anda perlu memuat catatan untuk melihat kunci.
Archimedes Trajano