InsertステートメントのPostgresでUUIDを生成しますか?


368

私の質問はかなり単純です。私はUUIDの概念を認識しており、DB内の「ストア」から各「アイテム」を参照するためにUUIDを生成したいと思います。妥当な権利だと思いますか?

問題は、次の行がエラーを返すことです。

honeydb=# insert into items values(
uuid_generate_v4(), 54.321, 31, 'desc 1', 31.94);
ERROR:  function uuid_generate_v4() does not exist
LINE 2: uuid_generate_v4(), 54.321, 31, 'desc 1', 31.94);
        ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

私は次のページを読みました:http : //www.postgresql.org/docs/current/static/uuid-ossp.html

ここに画像の説明を入力してください

Ubuntu 10.04 x64でPostgres 8.4を実行しています。


8
Postgres は、データ型としてUUIDをネイティブでサポートし、インデックスを作成して主キーとして使用することもできます。ただし、列のデフォルト値を設定するなど、UUID値を生成するには、Postgres拡張(プラグイン)が必要です。Postgresの多くのビルド(ディストリビューション)には、このような拡張機能が含まれていますが、拡張機能はアクティブ化されません。有効にする方法については、Craig Ringerの正解をご覧ください。
バジルブルク2014年

2
uuid-osspをインストールしてもこのエラーが発生する場合は、関数の前にスキーマ名を付けてみてください。例:select dbo.uuid_generate_v4()
Richard

回答:


435

uuid-osspはcontribモジュールであるため、デフォルトではサーバーにロードされません。それを使用するには、データベースにロードする必要があります。

最新のPostgreSQLバージョン(9.1以降)の場合は簡単です。

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

ただし、9.0以下では、代わりにSQLスクリプトを実行して拡張機能をロードする必要があります。8.4のcontribモジュールのドキュメントを参照してください。

Pg 9.1以降の場合は、代わりに現在のcontribドキュメントとをお読みくださいCREATE EXTENSION。これらの機能は、8.4などの9.0以前のバージョンには存在しません。

PostgreSQLのパッケージバージョンを使用している場合は、contribモジュールと拡張機能を含む個別のパッケージをインストールする必要がある場合があります。パッケージマネージャデータベースで「postgres」と「contrib」を検索します。


6
@advocateディストリビューションでパッケージ化されたPostgreSQLを使用しているので、それだけで、apt-get install postgresql-contribまたは同様にできるはずです。apt-cache search postgresql |grep contrib必要なパッケージ名を見つけてください。
クレイグリンガー

2
sudo apt-get install postgresql-contribが正常に実行されました。次に、psql -d dbname -f SHAREDIR / contrib / module.sqlを実行する必要がありましたが、動作します!!! uuid_generate_v1();を選択します。今すぐ1を返します。本当にありがとう!
anon58192932

5
postgresql-contribパッケージをインストールしない場合、次のエラーが発生することに注意してください。エラー:拡張制御ファイル "/usr/share/postgresql/9.3/extension/uuid-ossp.control"を開けませんでした:そのようなファイルまたはディレクトリはありません
Drew Noakes

1
エラー文字列がGoogleで打ち消されたときに、そのコメントを投稿しました。また、少なくともUbuntuでは、特定のパッケージ名が表示されます。
Drew Noakes

2
拡張機能にuuid-osspがすでに含まれているデータベースをインポートした場合、uuid_generate_v4()が機能しない可能性があります。その場合は、拡張機能を削除し、再度作成するだけで機能します。
Dragos Rusu 2015

302

拡張機能なし(チート)

SELECT uuid_in(md5(random()::text || clock_timestamp()::text)::cstring);

output>> c2d29867-3d0b-d497-9191-18a9d8ee7830

(少なくとも8.4で動作します)

  • clock_timestamp()説明してくれた@Erwin Brandstetterに感謝します。

有効なv4 UUIDが必要な場合

SELECT uuid_in(overlay(overlay(md5(random()::text || ':' || clock_timestamp()::text) placing '4' from 13) placing to_hex(floor(random()*(11-8+1) + 8)::int)::text from 17)::cstring);

ここに画像の説明を入力してください * @Denis Stafichuk @Karstenおよび@autronixに感謝


また、最近のPostgresでは、次のように簡単にキャストできます。

SELECT md5(random()::text || clock_timestamp()::text)::uuid


5
PSをフォローアップするには:SELECTuuid_in(md5(random()::text || now()::text)::cstring);
Blaskovicz 14

4
@MattDiPasqualeおそらくを使用するよりも「良い」uuid-osspとは言えませんが、たとえば、拡張機能をインストールするための十分な権限がないPostgreSQLインスタンスで作業しています。
Stefan Haberl 14

25
@JosephLennox:clock_timestamp()どちらの場合もこれより優れた選択肢です。とは異なり、now()またはCURRENT_TIMESTAMP揮発性であり、実際の現在時刻を返します。SELECT uuid_in(md5(random()::text || clock_timestamp()::text)::cstring);また、最近のPostgresでは、簡単にキャストできますSELECT md5(random()::text || clock_timestamp()::text)::uuid。使用例:stackoverflow.com/a/8335376/939860
Erwin Brandstetter 2015

17
いいえ。これがまったくうまくいかない場合は、まったくの幸運です。UUIDには形式があり、ランダムな16進文字が一緒にスローされるだけではありません。アプリケーションがその数字をチェックして、対応するuuidのバージョンを確認し、それに応じて何かを行うと、コードで失敗します。
TuncayGöncüoğlu2016年

7
@TuncayGöncüoğlu:有効なv4 UUIDを生成するのはかなり簡単です(ただし、文字列オーバーレイアプローチは2ビットのランダム性を浪費します):select overlay(overlay(md5(random()::text || ':' || clock_timestamp()::text) placing '4' from 13) placing '8' from 17)::uuid;
Karsten

75

クレイグ・リンガー答えは正しいです。Postgres 9.1以降の情報が少しあります…

拡張機能は利用できますか?

拡張機能は、Postgresインストール用にすでにビルドされている場合(Postgres lingoのクラスター)にのみインストールできます。たとえば、提供されたMac OS Xのインストーラーの一部として含まれているuuid-ossp拡張機能を見つけました EnterpriseDB.com。数十の拡張機能のいずれかが利用できる場合があります。

Postgresクラスターでuuid-ossp拡張が利用可能かどうかを確認するには、このSQLを実行してpg_available_extensionsシステムカタログ。

SELECT * FROM pg_available_extensions;

拡張機能をインストール

そのUUID関連の拡張機能をインストールするには、次のSQLに示されているように、CREATE EXTENSIONコマンドを使用します。

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

注意してください:反対の文書にもかかわらず、拡張名の前後のQUOTATION MARK文字が必要であることがわかりました。

SQL標準委員会またはPostgresチームは、そのコマンドに奇妙な名前を選択しました。私の考えでは、彼らは「INSTALL EXTENSION」や「USE EXTENSION」のようなものを選んだはずです。

インストールの確認

このSQLを実行してpg_extensionシステムカタログを照会することにより、拡張機能が目的のデータベースに正常にインストールされたことを確認できます。

SELECT * FROM pg_extension;

デフォルト値としてのUUID

詳細については、質問を参照してください: PostgresのUUID列のデフォルト値を

古い方法

上記の情報は、Postgres 9.1に追加された新しい拡張機能を使用しています。以前のバージョンでは、.sqlファイル内のスクリプトを見つけて実行する必要がありました。拡張機能は、インストールを簡単にするために追加されました。拡張機能のユーザー/コンシューマー側の作業を減らすために、拡張機能作成者の作業を少し増やします。私を見てブログ投稿を。

UUIDのタイプ

ちなみに、質問のコードは関数を呼び出しますuuid_generate_v4()。これにより、バージョン4と呼ばれるタイプが生成されます、128ビットのほぼすべてがランダムに生成されます。これは、行の小さなセットでの限定的な使用には問題ありませんが、衝突の可能性を事実上排除したい場合は、UUIDの別の「バージョン」を使用します。

たとえば、元のバージョン1では、ホストコンピューターのMACアドレスと現在の日時および任意の数値を組み合わせているため、衝突の可能性はほとんどありません。

詳細については、関連する質問に対する私の回答を参照しください。


1
またCREATE EXTENSION IF NOT EXISTS ...、(スクリプトなどで)確認したくない場合に使用することもできます
Uwe Allner

2
バージョン4のUUIDは、「行の小さなセットでの使用が制限される」だけでなく、ほぼすべてのサイズのデータ​​セットに適しています。50%の確率で衝突が発生する場合でも、1秒あたり10億UUIDを約85年間(または、今日の最大のデータベースより数千倍大きい約4500万テラバイトのデータ)生成する必要があります。NSAでない限り、バージョン4はほぼすべての目的に適しています。一方、バージョン1は、MACアドレスが順番に割り当てられる(そして、しばしばスプーフィングされるか利用できない)という事実に悩まされており、それが後のバージョンが導入された理由の一部です。
ジャズ

1
@BasilBourque v1の問題は、正しく実装された場合に衝突する可能性ではなく、正しく実装されていない可能性です。Wikipediaの説明によると、「バージョン1と2のUUIDの一意性は、他の製造プロセスと同様に、一意のMACアドレスをカードに正しく割り当てるネットワークカードメーカーにも依存します。また、一部のコンテナー化または仮想化環境では、基盤となるハードウェアからの真のMACアドレスを使用できません。多くのコンテナーが同じMACを持っているが、独自のclockseqカウンターがある場合、それらのv1 UUIDが衝突する可能性があります。
ジャズ

1
ただし、@ BasilBourque v1の弱点は私のコメントの主要なポイントではありません。元の答えは、v1よりも衝突の可能性が高いため、v4は大規模なデータセットには適していないと示唆しています。これは誤解を招く可能性があり、誤っている可能性があります。ただし、v1の衝突確率は実装に依存するため、計算が困難です。
ジャズ

1
@BasilBourqueたとえば、node-uuidプロジェクトは、それらのclockseqカウンターが4.6e18の1と同じになるように(2つのプロセスがv1 UUIDの同じシーケンスを生成するように)計算します。これはごくわずかですが、v4での即時衝突の可能性(5.3e36に1つ)よりもはるかに可能性が高くなります。明らかに、v4 UUIDを生成する時間が長いほど、衝突が発生する可能性が高くなりますが、これはv1には当てはまりませんが、衝突の確率がノードのv1実装の確率を超える前に、15億2000万個のv4 UUIDを生成する必要があります。ほとんどの人は、テーブルごとに15億2000万のレコードを持っていません。
ジャズ

61

pgcrypto 拡張

Postgres 9.4以降、pgcryptoモジュールにはgen_random_uuid()関数が含まれています。この関数は、乱数ベースのバージョン4タイプのUUIDの 1つを生成します。

まだ利用できない場合は、contribモジュールを入手してください。

sudo apt-get install postgresql-contrib-9.4

pgcryptoモジュールを使用します。

CREATE EXTENSION "pgcrypto";

これでgen_random_uuid()関数が使用可能になります。

使用例。

INSERT INTO items VALUES( gen_random_uuid(), 54.321, 31, 'desc 1', 31.94 ) ;


モジュールに関するPostgresドキュメントuuid-ossp からの引用。

注:ランダムに生成された(バージョン4)UUIDのみが必要な場合は、代わりにpgcryptoモジュールのgen_random_uuid()関数の使用を検討してください。


3
はい、ただしblog.starkandwayne.com/2015/05/23/…も参照してください。フラグメンテーションについて警告し、代わりにuuid-osspを提案しています。
Malik


しかし、Postgresは上記のコメントにリンクポストは決定的と間違って作り、最新バージョンでは、インデックスをクラスタ化されていないと我々は正方形の1にすぐに戻っています
マイケルGoldshteyn

1
@MichaelGoldshteyn:いいえ、Postgresはいませんクラスタ化インデックスがあり(Postgres 12以降)
a_horse_with_no_name

3
ALTER TABLE table_name ALTER COLUMN id SET DEFAULT uuid_in((md5((random())::text))::cstring);

@ZuzELの回答を読んだ後、上記のコードを列IDのデフォルト値として使用しましたが、うまくいきます。


1

今後のPostgreSQL 13はネイティブでサポートされます 、拡張機能を有効にする必要なし gen_random_uuid()を。

PostgreSQLには、UUIDを生成する関数が1つ含まれています。

gen_random_uuid ()  uuid

この関数は、バージョン4(ランダム)UUIDを返します。これは最も一般的に使用されるタイプのUUIDであり、ほとんどのアプリケーションに適しています。

db <> fiddleデモ

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.