web-dev-qa-db-ja.com

ID列とは何ですか?

私はPostgreSQLの 7/01にスケジュールされたcommit-fest を確認していましたが、Pgがすぐに「ID列」を取得する可能性が高いことがわかりました。

information_schema.columns でいくつかの言及を見つけましたが、それほど多くはありません

is_identity         yes_or_no         Applies to a feature not available in PostgreSQL
identity_generation character_data    Applies to a feature not available in PostgreSQL
identity_start      character_data    Applies to a feature not available in PostgreSQL
identity_increment  character_data    Applies to a feature not available in PostgreSQL
identity_maximum    character_data    Applies to a feature not available in PostgreSQL
identity_minimum    character_data    Applies to a feature not available in PostgreSQL
identity_cycle      yes_or_no         Applies to a feature not available in PostgreSQL

ウィキペディアのページ もあまり言いません

ID列は、その値がサーバーによって管理され、通常は変更できないという点で主キーとは異なります。多くの場合、ID列は主キーとして使用されます。ただし、常にそうであるとは限りません。

でも、他には何も見えません。 ID列はどのように機能しますか?それらは新しい機能を提供しますか、またはこれはシーケンスを作成するための単なる標準的な方法ですか?新機能の内訳とその機能

7
Evan Carroll

PG 10で実際にどのように実装されているか

テストスイートの予想される出力を使用して、それらが実際にどのように実装されているかを確認できます。

これから取り除くいくつかのキー。

  • 開始する場所とスキップする数を、テーブル作成時の句またはALTER TABLESTART 7 INCREMENT BY 5を使用して指定できます。

  • ID列を含むテーブルに挿入すると、ID列をOVERRIDING USER VALUEできるようになり、競合する行を強制的に置き換えます。

    INSERT INTO t OVERRIDING USER VALUE VALUES (10, 'xyz');
    
    -- this isn't currently allowed.
    CREATE TABLE t ( a serial PRIMARY KEY, b text );
    INSERT INTO t (a,b) VALUES (1,'foo');
    INSERT INTO t (a,b) VALUES (1,'bar');
    
  • GENERATED ALWAYSを指定して生成を確実にすると、OVERRIDING SYSTEM VALUEだけでそれを無視する必要があります。そうしないと、ID列の値を指定する行をINSERT実行するとエラーが発生します。

    ERROR:  cannot insert into column "a"
    DETAIL:  Column "a" is an identity column defined as GENERATED ALWAYS.
    HINT:  Use OVERRIDING SYSTEM VALUE to override.
    
  • ID列はNOT NULLである必要があります

  • 権限はテーブルから伝播し、基礎となるシーケンスはなくなります。

  • IDは、RESTARTを使用して別の時点で完全にリセットできます。

これらの詳細については、PostgreSQL 10のドキュメントをご覧ください。

  • ALTER TABLE

    ALTER [ COLUMN ] column_name ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ]
    ALTER [ COLUMN ] column_name DROP IDENTITY [ IF EXISTS ]
    ALTER [ COLUMN ] column_name { SET GENERATED { ALWAYS | BY DEFAULT } | SET sequence_option | RESTART [ [ WITH ] restart ] } [...]
    
  • CREATE TABLE

    GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ]
    
  • CREATE SEQUENCE 上記のsequence_optionを提供します
4
Evan Carroll

これは、標準にある機能を実装するためのものです。 (ドラフトからコピー、日付:2011-12-21):

4.15.11ID列

ベーステーブルBTの列には、オプションで1つ以下のID列を含めることができます。 ID列の宣言されたタイプは、スケール0(ゼロ)の正確な数値タイプ、たとえばINTEGER、またはソースタイプがスケール0(ゼロ)の正確な数値タイプである特殊タイプのいずれかです。 ID列には、開始値、増分、最大値、最小値、およびサイクルオプションがあります...
... ID列の定義では、_GENERATED ALWAYS_または_GENERATED BY DEFAULT_を指定できます。

これは、列のプロパティであり、基本的に、列の値はDBMSではなくユーザーによって、特定の方法で提供されることを示しています。と制限(増加/減少、最大/最小値を持つ、最大/最小値に達した場合の循環)。

シーケンスジェネレーター(通常、単に「シーケンス」と呼ばれます)は、関連するSQL標準機能です。これは、このような値を提供するメカニズムであり、ID列に使用できます。 。

微妙な違いに注意してください。SEQUENCEは、1つ以上のID列に値を提供するために、または自由に使用できるオブジェクトです。


これまでに、さまざまなDBMSが同様の機能をさまざまな方法と構文で実装しています(MySQL:_AUTO_INCREMENT_、SQL Server:IDENTITY (seed, increment)、PostgreSQL:serial using SEQUENCE、 Oracle:トリガーなどの使用)および最近追加されたシーケンスジェネレーター(バージョン2012のSQL Serverおよび12cのOracle)。

これまでPostgresはシーケンスジェネレーターを実装しました(これは、特別なマクロserialおよびbigserialまたはnextval()関数を使用して、列に値を提供するために使用できます)が標準にあるように、ID列の構文はまだ実装されていません。

ID列(およびserial列とのわずかな違い)とSQL標準からのさまざまな構文(_GENERATED ALWAYS_、_NEXT VALUE FOR_など)の定義は、この機能の目的です。 ID列はシーケンスを使用するため、シーケンスの実装でもいくつかの変更/改善を行う必要がある場合があります。

リンク ID列 (見たページから)をたどると、次のことがわかります。

ID列

From:ピーターアイゼントラウト
宛先:pgsql-hackers件名:ID列
日付:2016-08-31 04:00:42
メッセージID:[email protected]


ID列を実装する別の試みを次に示します。これは、PostgreSQLのシリアル列の標準準拠のバリアントです。また、シリアル列にあるいくつかの使いやすさの問題も修正されます。

  • テーブル(*)に加えてシーケンスに権限を設定する必要があります
  • _CREATE TABLE_/LIKEはデフォルトをコピーしますが、同じシーケンスを参照します
  • _ALTER TABLE_では直列性を追加/削除できません
  • デフォルトを削除してもシーケンスは削除されません
  • シリアルはある種の特別なマクロであるため、少し奇妙です

(*)以前に投稿した_NEXT VALUE FOR_のものを利用したかったので、まだ実際には実装されていませんが、そこで行う作業がまだあります。

...

2017年9月更新:この機能はPostgres 10にあるようですが、数日/週後にリリースされます: What's Postgres 10の新機能:ID列


Oracleは、バージョン12cでID列とシーケンスも実装しています。構文は、私がチェックした限り、標準に従っています:
Oracle Database 12cリリース1(12.1)のID列

12cデータベースには、数値型を使用して定義されたテーブル列に対してID句を定義する機能が導入されています。構文は次のとおりです。

_GENERATED
[ ALWAYS | BY DEFAULT [ ON NULL ] ]
AS IDENTITY [ ( identity_options ) ]
_
22
ypercubeᵀᴹ