CURRENT_TIMESTAMP
として使用できますPRIMARY KEY
か?
2つ以上の異なるINSERTが同じになる可能性はありCURRENT_TIMESTAMP
ますか?
CURRENT_TIMESTAMP
として使用できますPRIMARY KEY
か?
2つ以上の異なるINSERTが同じになる可能性はありCURRENT_TIMESTAMP
ますか?
回答:
ドキュメントに従って、の精度CURRENT_TIMESTAMP
はマイクロ秒です。したがって、衝突の確率は低くなりますが、可能です。
今起きないバグを想像非常に稀に、データベースエラーが発生します。それをデバッグするのはどれほど難しいですか?これは、少なくとも決定論的なバグよりもはるかに悪いバグです。
より広範なコンテキスト:シーケンスでのこれらの小さなニュアンスを回避する必要がある場合があります。これは、MySQLに慣れている場合は特に厄介です。
さらに、トランザクションを使用している場合(ほとんどのWebフレームワーク、特にJavaのフレームワークは実行します)、トランザクション内のタイムスタンプは同じになります!デモ:
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)
またね?2つの選択、まったく同じ結果。私はそれほど速くタイプしません。;-)
-
シーケンスの使用を避けて簡単にIDが必要な場合は、レコードの実際の識別子からハッシュ値を生成します。たとえば、データベースに人間が含まれていて、その生年月日、母親の旧姓、本名がそれらを一意に識別していることがわかっている場合は、
md5(mother_name || '-' || given_name || '-' birthday);
IDとして。それ以外に、CreationDate
テーブルにインデックスを付けた後に列を使用できますが、それはキーではありません(idです)。
Ps一般に、DBを可能な限り確定的にすることは非常に良い習慣です。つまりは、同じ操作はDBで正確に同じ変更を作成する必要があります。タイムスタンプベースのIDは、この重要な機能に失敗します。何かをデバッグまたはシミュレーションしたい場合はどうなりますか?操作を再生すると、同じオブジェクトが異なるIDで作成されます...追跡するのは難しくなく、多くの作業時間を節約できます。
Ps2上記の理由により、将来コードをチェックする人は誰でも、タイムスタンプで生成されたIDを確認することはできません。
INSERT
、複数の行を実行すると、それらはすべて同じになりcurrent_timestamp
ます。そして、あなたにはトリガーがあります...
CURRENT_TIMESTAMPが2つの後続のINSERT(または複数の行を持つ単一のINSERT)に2つの同一の値を提供することが可能だからではありません。
代わりに、時間ベースのUUIDを使用してください:uuid_generate_v1mc()。
厳密に言えば、いいえ。なぜなら、CURRENT_TIMESTAMP
は関数であり、制約を形成できるのは1つ以上のテーブル列だけだからですPRIMARY KEY
。
あなたが作成することを意味する場合はPRIMARY KEY
、デフォルト値を持つ列の制約をCURRENT_TIMESTAMP
、その答えは:はい、あなたがすることができます。あなたが息子の頭からリンゴを撃つことを妨げるようなものは何もないように、あなたがそれをすることを妨げるものは何もありません。質問の目的を定義しない限り、質問はまだ意味がありません。列とテーブルはどのような種類のデータを保持することになっていますか?どのルールを実装しようとしていますか?
一般的に、アイデアがあるため、重複キーエラーに実行するためにバインドされてCURRENT_TIMESTAMP
いるSTABLE
同じトランザクション(トランザクションの開始時刻)に同じ値を返す関数。同じトランザクション内の複数のINSERTは、すでに説明されている他の回答と同様に、衝突するようにバインドされています。マニュアル:
これらの関数は現在のトランザクションの開始時間を返すため、それらの値はトランザクション中に変更されません。これは機能と見なされます。1つのトランザクションが「現在の」時間の一貫した概念を持つことができるようにして、同じトランザクション内の複数の変更が同じタイムスタンプを持つようにすることを目的としています。
Postgresのタイムスタンプは、最大6の小数桁(マイクロ秒の分解能)を表す8バイトの整数として実装されます。
場合は(名前のものを使用すると、マイクロあたり1個以下の行を保持することになっているテーブルを構築しているし、その条件を変更するつもりはないsensor_reading_per_microsecond
)、そして、それは意味をなさないかもしれません。行が重複すると、重複キー違反エラーが発生するはずです。ただし、これはエキゾチックな例外です。そして、データ型timestamptz
(ではないtimestamp
)がおそらく望ましいでしょう。見る:
代わりに、代わりに代理シリアル主キーを使用します。そしてUNIQUE
、タイムスタンプ列に制約を追加します。RDBMSの実装の詳細に依存せずに、起こりうる複雑さを減らします。
sensor_reading_per_microsecond
各読み取りのタイミングが前の読み取りと完全に同期していることを完全に保証できない場合でも、衝突する可能性があります。サブマイクロ秒の偏差(これは多くの場合不可能ではありません)はスキームを壊します。一般的に私はまだこれを完全に避けます。(あなたが指摘したように、そのような場合、結果として生じる衝突が望ましいかもしれません!)