Dapat CURRENT_TIMESTAMP
digunakan sebagai PRIMARY KEY
?
Apakah ada kemungkinan dua atau lebih INSERT yang berbeda, mendapatkan yang sama CURRENT_TIMESTAMP
?
postgresql
database-design
primary-key
timestamp
John Puskin
sumber
sumber
Jawaban:
Sesuai dokumentasi , ketepatan
CURRENT_TIMESTAMP
mikrodetik adalah. Dengan demikian, kemungkinan tabrakan rendah, tetapi mungkin.Sekarang bayangkan sebuah bug yang terjadi sangat jarang, dan menyebabkan kesalahan database. Seberapa sulit untuk men-debug itu? Ini adalah bug yang jauh lebih buruk daripada yang setidaknya bersifat deterministik.
Konteks yang lebih luas: Anda mungkin ingin menghindari nuansa kecil ini dengan urutan, yang sangat mengganggu jika Anda terbiasa dengan MySQL.
Selain itu, jika Anda menggunakan transaksi (kebanyakan kerangka kerja web, terutama yang Java, lakukan!), Maka cap waktu akan sama di dalam transaksi! Demonstrasi:
Sampai jumpa? Dua pilihan, hasil yang persis sama. Saya tidak mengetik begitu cepat. ;-)
-
Jika Anda ingin ID mudah, menghindari penggunaan urutan, kemudian menghasilkan beberapa nilai hash dari pengidentifikasi nyata catatan. Misalnya, jika database Anda memiliki manusia, dan Anda tahu bahwa tanggal lahir mereka, nama gadis ibu dan nama asli secara unik mengidentifikasi mereka, maka gunakan
sebagai id. Selain itu, Anda bisa menggunakan
CreationDate
kolom, setelah apa yang Anda indeks tabel, tetapi itu bukan kunci (yang merupakan id).PS Secara umum, ini adalah praktik yang sangat baik untuk membuat DB Anda begitu deterministik, karena itu mungkin. Yaitu operasi yang sama harus membuat perubahan persis sama di DB . ID berbasis timestamp gagal fitur penting ini. Bagaimana jika Anda ingin men-debug atau mensimulasikan sesuatu? Anda memutar ulang operasi dan objek yang sama akan dibuat dengan id yang berbeda ... benar-benar tidak sulit untuk diikuti, dan menghemat banyak jam kerja.
Ps2 Siapa pun yang memeriksa kode Anda di masa depan, tidak akan memiliki pendapat terbaik melihat id yang dihasilkan timestamp, dengan alasan di atas.
sumber
INSERT
beberapa baris, semuanya mendapatkan yang samacurrent_timestamp
. Dan kemudian Anda memiliki pemicu ...Tidak juga karena CURRENT_TIMESTAMP mungkin memberikan dua nilai identik untuk dua INSERT berikutnya (atau satu INSERT dengan beberapa baris).
Gunakan UUID berbasis waktu sebagai gantinya: uuid_generate_v1mc () .
sumber
Sebenarnya: Tidak. Karena
CURRENT_TIMESTAMP
adalah fungsi dan hanya satu atau lebih kolom tabel yang dapat membentukPRIMARY KEY
kendala.Jika Anda bermaksud membuat
PRIMARY KEY
batasan pada kolom dengan nilai defaultCURRENT_TIMESTAMP
, maka jawabannya adalah: Ya, Anda bisa . Tidak ada yang menghalangi Anda melakukannya, seperti tidak ada yang mencegah Anda menembak apel dari kepala putra Anda. Pertanyaannya tetap tidak masuk akal sementara Anda tidak mendefinisikan tujuan dari pertanyaan itu. Jenis data apa yang harus dimiliki oleh kolom dan tabel? Aturan apa yang Anda coba terapkan?Biasanya, idenya pasti akan mengalami kesalahan kunci duplikat karena
CURRENT_TIMESTAMP
merupakanSTABLE
fungsi yang mengembalikan nilai yang sama untuk transaksi yang sama (waktu mulai transaksi). Beberapa INSERT dalam transaksi yang sama pasti akan bertabrakan - seperti jawaban lain yang telah diilustrasikan. Manual:Stempel waktu Postgres diimplementasikan sebagai bilangan bulat 8-byte yang mewakili hingga 6 digit fraksional (resolusi mikrodetik).
Jika Anda membangun tabel yang seharusnya menampung tidak lebih dari satu baris per mikrodetik dan kondisi itu tidak akan berubah (sesuatu bernama
sensor_reading_per_microsecond
), maka mungkin masuk akal. Baris duplikat seharusnya meningkatkan kesalahan pelanggaran kunci duplikat. Itu pengecualian eksotis. Dan tipe datatimestamptz
(bukantimestamp
) mungkin lebih disukai. Lihat:Saya masih lebih suka menggunakan kunci primer serial pengganti sebagai gantinya. Dan tambahkan
UNIQUE
kendala pada kolom cap waktu. Lebih sedikit kemungkinan komplikasi, tidak bergantung pada detail implementasi RDBMS.sumber
sensor_reading_per_microsecond
mungkin berbenturan jika Anda tidak dapat benar-benar menjamin bahwa waktu setiap pembacaan disinkronkan dengan sempurna dengan yang sebelumnya; penyimpangan sub-mikrodetik (yang seringkali bukan tidak mungkin) mematahkan skema. Secara umum saya masih benar-benar menghindari ini. (Ingat, seperti yang Anda tunjukkan, dalam kasus seperti itu, tabrakan yang dihasilkan mungkin diinginkan!)