Kolom Identitas atau UDF yang secara eksplisit menghasilkan id unik?

11

Saya di tengah-tengah perdebatan tentang apakah lebih baik untuk membuat PRIMARY KEYkeluar dari Kolom Identitas , kami keluar dari UDF yang secara eksplisit menghasilkan id unik.

  • Saya berdebat untuk Kolom Identitas.
  • Mitra saya berdebat untuk menghasilkan nilai secara manual, klaimnya
    • dengan meletakkan UDF di atas meja lain di mana kita dapat memiliki UDF
      • kunci sumber daya
      • menambah tabel ID dengan satu bidang yang disebut ID_Valueoleh1
      • gunakan ini sebagai pengidentifikasi unik global
    • Atau minta meja melakukan id+1saat memasukkan
    • Bahwa lebih mudah untuk memindahkan data antara server dan / atau lingkungan yang tidak memiliki kendala identifikasi; bergerak dari satu DB di mana ada data ke DB lain yang serupa dengan katakanlah staging atau data dummy. Untuk pengujian dalam produksi non, kami mungkin ingin menarik semua catatan dari kemarin ke panggung untuk pengujian.

Implementasi mana yang lebih masuk akal?

kacalapy
sumber

Jawaban:

21

Kolega Anda idiot.

Solusinya tidak akan terukur, UDF tidak bersamaan ( alasan yang sama seperti ini ). Dan bagaimana Anda menangani insert multi-baris: ini akan membutuhkan panggilan UDF per baris

Dan bermigrasi ke RDBMS lain tidak sering terjadi dalam kehidupan nyata ... Anda mungkin juga tidak menggunakan SQL Server sekarang dan menggunakan urutan pada Oracle dan berharap Anda tidak bermigrasi.

Edit:

Pembaruan Anda menyatakan bahwa memindahkan data adalah untuk menyegarkan basis data non-produksi.

Dalam hal ini, Anda mengabaikan kolom identitas saat menyegarkan. Anda tidak mengkompromikan implementasi Anda untuk membuat pemuatan non-prod lebih mudah. Atau gunakan tabel temp untuk melacak perubahan nilai identitas.

Atau gunakan proses: kami menyegarkan sistem pengujian kami setiap malam dari produksi yang menghindari masalah sepenuhnya. (Dan memastikan cadangan prod kami dapat dikembalikan juga)

gbn
sumber
11

Gunakan nilai identitas. Menghasilkan tabel urutan Anda sendiri dan nilai-nilai urutan akan mengambil banyak overhead dan menyebabkan banyak mengunci dan memblokir ketika mencoba untuk menghasilkan angka.

Identitas ada karena suatu alasan, gunakan itu.

Ketika SQL Denali keluar, itu akan mendukung urutan yang akan lebih efisien daripada identitas, tetapi Anda tidak dapat membuat sesuatu yang lebih efisien sendiri.

Adapun untuk memindahkan catatan dari satu lingkungan ke lingkungan lain baik mengaktifkan IDENTITY_INSERT ON saat melakukan penyisipan, atau centang kotak di SSIS.

mrdenny
sumber
Jika Anda berpindah dari "produksi" ke "menguji" dan memiliki bidang identitas, Anda berisiko menimpa atau menabrak data. Itu saja yang saya katakan. Ya, itu seharusnya tidak menjadi masalah dalam yang arah, tapi aku hanya mengatakan bahwa hal itu bisa terjadi.
jcolebrand
Benar, Anda akan memiliki angka yang sama untuk nilai baris yang berbeda di dev, test, qa, uat dan produksi. Terus? Jika nilai-nilai itu penting (seperti untuk tabel pencarian) maka hard code secara manual, yang seharusnya tidak menjadi masalah karena Anda tidak harus sering meletakkan nilai dalam tabel tersebut. Jika Anda perlu mengontrol nilai identitas antara lingkungan untuk menghindari tabrakan, maka setel ulang nilai identitas antara lingkungan saat Anda memulihkan dari produksi.
mrdenny
5

Kolom identitas terdengar baik bagi saya. Saya tidak yakin saya mengikuti logika tentang mengapa sulit untuk memindahkan data antar server.

Jika Anda ingin setiap baris memiliki identitas unik secara global, Anda dapat menggunakan UUID tetapi saya tidak akan melakukannya kecuali Anda yakin bahwa keunikan global diperlukan - biasanya tidak. Menggunakan UUID sebagai id akan menurunkan kinerja, menambah persyaratan ruang disk, dan mempersulit proses debug - karena panjangnya sulit untuk mengingat UUID, memberitahukannya kepada seseorang melalui telepon, atau menuliskannya di atas kertas tanpa kesalahan.

Mark Byers
sumber
4

Untuk ID numerik sederhana, cukup gunakan identitas dan lupakan semua masalah pembuatannya secara manual.

Anda selalu dapat membuat "tabel super" yang menggunakan identitas sebagai PK dan memiliki kolom tipe, dan info lainnya. Ketika Anda membutuhkan ID baru (dengan asumsi maksud Anda IDS unik di berbagai tabel) cukup masukkan ke tabel ini dan ambil SCOPE_IDENTITY()dan kemudian masukkan ke tabel aktual yang Anda butuhkan.

Pada dasarnya Anda membuat tabel: MasterID dengan PK identitas, saat Anda perlu menyisipkan baris ke Table1 Anda, INSERT INTO MasterIDsdan mendapatkan identitas yang dihasilkan oleh baris itu menggunakan SCOPE_IDENTITY()dan kemudian menyisipkan ke Table1 menggunakan nilai itu sebagai PK.

Table1 akan memiliki int PK non-identitas. Anda akan melakukan proses yang sama untuk menyisipkan ke dalam Table2, dll. Biarkan SQL Server mengelola nilai-nilai identitas dalam tabel MasterID , yang kemudian dapat Anda gunakan di tabel Anda yang lain. MasterID bisa berisi tabel lain, seperti tipe (sehingga Anda bisa tahu tabel apa, Table1 atau Table2, dll, menggunakan nilai identitas itu.

Paul White 9
sumber
3

Selama Anda menggunakan batasan kunci asing dengan benar (berjenjang, memperbarui, dll) maka Anda akan baik-baik saja dengan menggunakan bidang identitas. Saya benar-benar tidak melihat keuntungan dari solusi lain dalam kasus ini.

Joe Phillips
sumber
2

Identitas dibuat agar sesuai dengan skenario Anda. Anda memiliki alat seperti replikasi untuk pertukaran data server / lingkungan yang menyatukan semuanya.


sumber
1

Saya baru saja menyelesaikan pekerjaan di mana saya telah mengganti identitykolom SQL Server dengan intbidang normal dan mengontrol alokasi Id sendiri.

Saya telah melihat peningkatan kinerja yang sangat mengesankan. Tidak seperti OP, saya tidak punya UDF untuk menghasilkan id. Tetapi prinsipnya hampir sama: Ada bagian dari perangkat lunak yang memelihara kumpulan id. Ketika mereka kehabisan mendapat batch lain dengan meminta database untuk nilai rendah berikutnya dan meningkatkan ini ke tinggi berikutnya .

Ini memungkinkan kami untuk menghasilkan id dan menghubungkan semua entitas di luar transaksi dalam ORM kami sebelum kami mengirimkan batch ke database dan juga mengirimkan batch yang lebih besar tanpa bolak-balik tambahan untuk mendapatkan identitas yang baru saja dimasukkan (diperlukan oleh kolom identitas).

Dalam tabel id yang kita miliki ada lebih dari satu baris, memungkinkan kita untuk menggunakan rentang tertentu jika kita mau. yaitu untuk menggunakan kembali blok yang dihapus dan id negatif.

Menandai
sumber
0

Saya telah menggunakan identitas selama bertahun-tahun dan secara serius mempertimbangkan untuk mengganti nomor identitas dengan UNIQUEIDENTIFIER. Ini adalah mimpi buruk ketika Anda perlu mengubah tipe data jika seseorang telah dirancang untuk menjadi db dan mimpi buruk jika Anda perlu menambahkan identitas ke kolom, juga, Anda tidak dapat memperbarui kolom identitas. Bayangkan Anda menaruh int dan basis data Anda tumbuh melampaui 2 miliar catatan, lagi-lagi mimpi buruk untuk diubah (pertimbangkan FK)! Mengubah apa pun dengan identitas adalah mimpi buruk dan tidak ramah skala kecuali Anda menaruh bigint! UNIQUEIDENTIFIER vs Identity = kenyamanan dan kekokohan vs mungkin peningkatan kinerja yang nyata (tidak melakukan patokan).

Pembaruan: Setelah saya melihat ini, saya pasti condong ke UNIQUEIDENTIFIER. Ini tidak menunjukkan manfaat nyata dari identitas bigint dan banyak manfaat untuk UNIQUEIDENTIFIER! Versi SQL Server yang berbeda dapat memiliki hasil yang berbeda. Hanya ada keindahan dalam memiliki id unik di semua basis data dan sistem (ketahanan)! Pindahkan, salin, ubah data sesukamu! https://www.mssqltips.com/sqlservertip/5105/sql-server-performance-comparison-int-versus-guid/

Hrvoje Batrnek
sumber
INT 64 bit akan bertahan lama ...
Vérace