Dapat CURRENT_TIMESTAMP
digunakan sebagai PRIMARY KEY
?
Apakah ada kemungkinan dua atau lebih INSERT yang berbeda, mendapatkan yang sama CURRENT_TIMESTAMP
?
Dapat CURRENT_TIMESTAMP
digunakan sebagai PRIMARY KEY
?
Apakah ada kemungkinan dua atau lebih INSERT yang berbeda, mendapatkan yang sama CURRENT_TIMESTAMP
?
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:
postgres=# begin;
BEGIN
postgres=# select current_timestamp;
current_timestamp
-------------------------------
2018-08-06 02:41:42.472163+02
(1 Zeile)
postgres=# select current_timestamp;
current_timestamp
-------------------------------
2018-08-06 02:41:42.472163+02
(1 Zeile)
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
md5(mother_name || '-' || given_name || '-' birthday);
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.
INSERT
beberapa baris, semuanya mendapatkan yang sama current_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 () .
Sebenarnya: Tidak. Karena CURRENT_TIMESTAMP
adalah fungsi dan hanya satu atau lebih kolom tabel yang dapat membentuk PRIMARY KEY
kendala.
Jika Anda bermaksud membuat PRIMARY KEY
batasan pada kolom dengan nilai default CURRENT_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
merupakan STABLE
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:
Karena fungsi-fungsi ini mengembalikan waktu mulai dari transaksi saat ini, nilainya tidak berubah selama transaksi. Ini dianggap sebagai fitur: tujuannya adalah untuk memungkinkan satu transaksi memiliki gagasan yang konsisten tentang waktu "saat ini", sehingga beberapa modifikasi dalam transaksi yang sama memiliki cap waktu yang sama.
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 data timestamptz
(bukan timestamp
) 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.
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!)