Pro dan Kontra Memeriksa apakah ada nilai untuk kolom unik atau biarkan db meningkatkan kesalahan unik saat memasukkan
8
Saat menulis pertanyaan beberapa hari yang lalu, sebuah pemikiran muncul di benak saya dan terus melekat di benak saya.
Apa yang lebih disukai, pertama memeriksa apakah ada nilai untuk kolom unik dan kemudian menyisipkan atau menyisipkan dan membiarkan db meningkatkan kesalahan kendala unik? Akankah itu penting?
Sunting: Seperti yang disarankan di bawah ini dalam menjawab bahwa masalah ini tergantung pada database saya menambahkan tag postgresql.
Saya tidak berpikir pertanyaan Anda benar-benar database agnostik. Jawaban yang tepat dapat bergantung pada detail implementasi, yang mungkin berbeda dari vendor ke vendor dan berubah dengan versi berikutnya. Saya akan menguji di bawah konkurensi sebelum memilih pendekatan apa pun pada RDBMS.
Saat ini, di SQL Server 2008 R2, saya menggunakan yang berikut ini:
Konkurensi rendah dan jumlah modifikasi rendah. Untuk menyimpan satu baris, saya membuat serial menggunakan sp_getapplock dan menggunakan MERGE. Saya menekankan pengujian di bawah konkurensi tinggi untuk memverifikasi bahwa itu berfungsi.
Konkurensi dan / atau volume lebih tinggi. Untuk menghindari konkurensi dan meningkatkan kinerja, saya tidak menyimpan satu baris sekaligus. Saya mengakumulasikan perubahan pada server aplikasi saya, dan menggunakan TVP untuk menghemat batch. Namun, untuk menghindari masalah terkait konkurensi, saya membuat serial menggunakan sp_getapplock sebelum MERGE. Sekali lagi, saya menekankan tes di bawah konkurensi tinggi untuk memverifikasi bahwa itu berhasil.
Akibatnya, kami memiliki kinerja yang baik dan nol masalah terkait konkurensi dalam produksi: tidak ada deadlock, tidak ada pelanggaran PK / kendala unik dll.
jadi Anda bermaksud mengatakan bahwa jika masalah konkurensi ditangani dengan baik maka memeriksa dulu adalah ide yang bagus?
codecool
1
Ya, biasanya menghindari kesalahan berkinerja lebih baik daripada melempar dan menangkap pengecualian, tetapi Anda perlu membandingkannya di platform Anda.
AK
7
Biarkan DB memunculkan kesalahan.
Mengujinya terlebih dahulu tidak aman untuk konkurensi karena pada akhirnya Anda akan mendapatkan tabrakan karena 2 utas mungkin lulus "BUKAN ADA" dan keduanya akan mencoba menulis. Ini berlaku untuk strategi "READ COMMITTED" dan MVCC / Snapshot.
Anda dapat menggunakan petunjuk kunci untuk memaksa isolasi, tetapi Anda mengurangi kinerja.
Saya menyebutnya pola JFDI (tautan SO). Untuk "perbarui jika ada" maka lihat ini di sini: Butuh Bantuan Pemecahan Masalah Sql Server 2005 Skenario Kebuntuan . Ini adalah SQL Server. MySQL memiliki INSERT IGNORE yang menangani ini dengan anggun. Tidak yakin tentang yang lain
Saya pikir bermanfaat untuk melakukan pemeriksaan (dan gagal dengan anggun) tetapi ikuti pepatah "percaya tapi verifikasi" untuk mengetahui kegagalannya. Alasannya? Penanganan kesalahan itu mahal. Saya sedang mengerjakan beberapa tes hari ini, sebenarnya, yang akan mengungkapkan apakah komentar ini masuk akal. Jika komentar ini hilang, Anda tahu hasilnya. :-)
Aaron Bertrand
Juga pada tahun 2008 ada MERGEyang mungkin telah menyelesaikan pengamatan Paul, tetapi saya belum menguji ini pada tingkat tinggi. Terutama karena saya belum melatih otak saya untuk memahami sintaksis itu.
Aaron Bertrand
1
MEA Culpa. Saya telah membuat beberapa pengamatan dalam pengujian saya hari ini. Perlu diingat ini adalah tes yang sangat terisolasi tanpa konkurensi. Untuk sisipan lurus, memeriksa terlebih dahulu dan menghindari kesalahan adalah sekitar 10x lebih cepat daripada membiarkan kesalahan terjadi. Tetapi dalam kasus lain di mana Anda akan melakukan penanganan kesalahan yang lebih kompleks (COBALAH / CATCH atau IF @@ ERROR <> 0, dengan ROLLBACK atau THROW, dll.) Itu dua kali lebih lambat jika Anda periksa dulu. Sekali lagi saya akan menekankan ini hanya pengamatan awal saya dan ada banyak faktor yang dapat mempengaruhi dampaknya. Mungkin perlu beberapa waktu sebelum saya bisa blog tentang hal itu secara menyeluruh.
Biarkan DB memunculkan kesalahan.
Mengujinya terlebih dahulu tidak aman untuk konkurensi karena pada akhirnya Anda akan mendapatkan tabrakan karena 2 utas mungkin lulus "BUKAN ADA" dan keduanya akan mencoba menulis. Ini berlaku untuk strategi "READ COMMITTED" dan MVCC / Snapshot.
Anda dapat menggunakan petunjuk kunci untuk memaksa isolasi, tetapi Anda mengurangi kinerja.
Saya menyebutnya pola JFDI (tautan SO). Untuk "perbarui jika ada" maka lihat ini di sini: Butuh Bantuan Pemecahan Masalah Sql Server 2005 Skenario Kebuntuan . Ini adalah SQL Server. MySQL memiliki INSERT IGNORE yang menangani ini dengan anggun. Tidak yakin tentang yang lain
sumber
MERGE
yang mungkin telah menyelesaikan pengamatan Paul, tetapi saya belum menguji ini pada tingkat tinggi. Terutama karena saya belum melatih otak saya untuk memahami sintaksis itu.