web-dev-qa-db-ja.com

Postgresは、MS SQL Serverの「NEWSEQUENTIALID」のような機能を提供して、UUIDを主キーとしてより効率的にしますか

Microsoft SQL Serverは NEWID コマンドを提供して新しいGUID(Microsoftバージョンの [〜#〜] uuid [〜 #〜] )主キー値として使用できる値(それらの uniqueidentifier データ型で)。これらは本質的に順次ではないため、インデックスの更新は非効率的な。

または、MS SQL Serverは NEWSEQUENTIALID コマンドを提供します。ドキュメントを引用するには:

GUIDこれは、任意の値よりも大きいGUID Windowsの起動以降、指定されたコンピューター上でこの関数によって以前に生成されました。Windowsの再起動後、GUIDは、より低い範囲から再開できますが、グローバルに一意です。GUID列が行識別子として使用される場合、NEWSEQUENTIALIDを使用すると、NEWID関数を使用するよりも高速になります。これは、NEWID関数がランダムなアクティビティを引き起こし、キャッシュされるデータページの数が少ないためです。NEWSEQUENTIALIDを使用すると、データページとインデックスページを完全に埋めることもできます。

Postgresでより効率的にインデックス化されたUUIDを取得する方法はありますか?

10
Basil Bourque

_uuid-ossp_ モジュール

PostgreSQLは、 ITU-T Rec。によって提供される標準化されたUUID生成アルゴリズムを使用します。 X.667ISO/IEC 9834-8:2005 、および RFC 4122。 From _uuid-ossp_、 のドキュメント

Uuid-osspモジュールは、いくつかの標準アルゴリズムの1つを使用して、Universally Unique Identifier(UUID)を生成する機能を提供します。特定の特別なUUID定数を生成する関数もあります。

uuid_generate_v1()この関数は、バージョン1のUUIDを生成します。これには、コンピューターのMACアドレスとタイムスタンプが含まれます。この種類のUUIDは、識別子を作成したコンピューターのIDとそれを作成した時刻を明らかにすることに注意してください。これにより、特定のセキュリティ依存のアプリケーションには不適切になる場合があります。

MACアドレスが変わらない限り、あなたは黄金になるでしょう。

つまり、@ a_horse_with_no_nameに同意します。

私の理解から、これはSQL Serverでのみ必要です。これは、テーブルがクラスター化インデックスに格納されるため、ランダムな挿入がヒープテーブルよりも遅くなるためです。 Postgresにはそのような概念はありません、ので、それがPostgresに影響を与えるとは思いません

実際には、衝突が少なくなり、セキュリティが向上する可能性があるため、私はそれを採用します。そして、私はuuid_generate_v4()を使用します

uuid_generate_v4()この関数は、完全に乱数から派生したバージョン4のUUIDを生成します。

4
Evan Carroll

はい、Tomas Vondraは、MSSQL newsequentialidに基づいてPostgreSQLのシーケンシャルuuid拡張を作成しましたが、予測可能性は低くなっています。

主キーはシーケンシャルなのでデータをすばやく見つけるためにインデックスで使用されるため、完全にランダムなUUIDを使用すると、利点が失われます。

完全に連続したUUIDを使用すると、予測可能になり、UUIDを使用するという当初の考えに反して、それらはグローバルに一意になります。

Vondraの拡張機能は、両方の世界のビットを使用しています:「...完全に連続した接頭辞を生成する代わりに、値はしばらくの間連続ですが、時々折り返されます。折り返しによって予測可能性が排除されます...」

PostgreSQLにインストールする方法:Ubuntuでの前提条件:

postgresql-server-dev-11

インストール:

git clone https://github.com/tvondra/sequential-uuids.git
cd sequential-uuids/
make
Sudo make install

postgreSQL内:

CREATE EXTENSION sequential-uuids;

例によってそれを動作させます:

DROP SEQUENCE IF EXISTS tablename_names_seq;
DROP TABLE IF EXISTS names;
CREATE SEQUENCE tablename_names_seq AS integer;
CREATE TABLE names(id uuid NOT NULL DEFAULT uuid_sequence_nextval('tablename_names_seq'::regclass),name varchar(40));
INSERT INTO names (name) VALUES ('William McKinley'),('Theodore Roosevelt'),('William Taft'),('Woodrow Wilson'),('Warren Harding'),('Calvin Coolidge'),('Herbert C. Hoover'),('Franklin Delano Roosevelt'),('Harry S Truman'),('Dwight David Eisenhower'),('John Fitzgerald Kennedy'),('Lyndon Baines Johnson'),('Richard Milhous Nixon'),('Gerald R. Ford'),('James (Jimmy) Earl Carter, Jr.'),('Ronald Wilson Reagan'),('George H. W. Bush'),('William (Bill) Jefferson Clinton'),('George W. Bush'),('Barack Obama'),('Donald Trump');

...私の場合に作成されます:

db=# select * from names;
id | name
--------------------------------------+----------------------------------
00005b41-8b07-3daa-216e-30b3e8177705 | William McKinley
00004ce4-1183-7689-47a0-a56d7e8e987c | Theodore Roosevelt
...
000042a0-2e72-c92b-6d61-7a79a5bf3b7e | Barack Obama
00002d51-34c3-a682-12ab-0d6287394899 | Donald Trump

ソース: https://github.com/tvondra/sequential-uuidshttps://www.2ndquadrant.com/en/blog/sequential-uuid-generators/

1
Bastiaan Wakkie