web-dev-qa-db-ja.com

PostgreSQL:生成された列

PostgreSQLは生成された列をサポートしていますか? virtual columns とも呼ばれます。 IDENTITY columns について話しているのはではありません

この注目すべき機能に関する情報は見つかりませんが、SQL Server、およびMariaDBとMySQLの最新バージョンで利用できることは知っています。

この機能は SQL:20 標準で言及されており、2006年頃にPostgreSQLフォーラムでいくつかの議論がありましたが、この件に関して重要なことは何も見つかりません。

SOについてはいくつかの議論がありますが、現在はかなり古く、時代遅れの可能性があります。

16
Manngo

これが目的のものかどうかはわかりませんが、属性表記_row.full_name_と関数表記full_name(row)はpostgresqlでは同等です。

それはあなたがテーブルを取ることを意味します

_CREATE TABLE people (
  first_name text,
  last_name text
);
_

そして関数:

_CREATE FUNCTION full_name(people) RETURNS text AS $$
  SELECT $1.first_name || ' ' || $1.last_name;
$$ LANGUAGE SQL;
_

次のように呼び出します。

_select full_name from people
_

それが必要ですか?

処理速度を上げるために、式インデックスを作成できます。

_CREATE INDEX people_full_name_idx ON people
USING GIN (to_tsvector('english', full_name(people)));
_

または、すべてをマテリアライズドビューに保存します。

ここからの例: http://bernardoamc.github.io/sql/2015/05/11/postgres-virtual-columns/

17
Fabian Zeindl

いいえ、これは現在(Postgres 9.6以降)サポートされていません。

インデックスを作成する必要のない単純な計算の場合は、トリガーまたはビューを使用するのが唯一の回避策です。

はい: GENERATED ALWAYS AS … STORED

Postgres 12SQL:20 標準で言及されているように、生成された列の機能を追加します。

値はINSERTまたはUPDATEのときに生成され、他の値と同様に行とともに格納されます。

生成されたものは、同じテーブルのベース列、または 不変関数 に基づいている必要があります。

構文は単純で、 CREATE TABLE

GENERATED ALWAYS AS ( generation_expr ) STORED 

例:

CREATE TABLE people (
    ...,
    height_cm NUMERIC,
    height_in NUMERIC GENERATED ALWAYS AS ( height_cm / 2.54 ) STORED
);

特徴:

  • インデックスを付けることができます。
  • SQL標準の一部。

警告:

  • 同じテーブルの列に基づく(関連するテーブルではない)
  • パーティション化は許可されていません(パーティションキーの一部にすることはできません)
  • データは常に行に書き込まれ、ストレージにスペースをとります
    • 将来の機能は、ストレージなしでオンザフライで計算された値にVIRTUALを提供する可能性があります
  • 単一世代の深さ(生成された別の列ではなくベース列を使用)
  • GENERATED BY DEFAULTはありません(値を上書きすることはできません)
  • BEFOREトリガーでgen-colにアクセスできません(値はまだ決定されていません)
  • 関数は不変でなければならない

見る:

5
Basil Bourque

ユースケースによっては、新しい列を宣言し、挿入/更新時にトリガーを設定することで、この種の動作を実現できます。

可能な場合は上記の回答を使用して、既存のデータから派生する可能性のあるデータの重複を回避しますが、これはうまく機能し、一度計算して保存する計算集約型の派生フィールドに役立ちます。

このアプローチは、18桁のキーが15桁しかないことがある問題(最後の3桁はチェックサムにすぎない)に対処するために検討しましたが、外部キーの関係を強制できるようにしたいと考えました。

トリガーに関するPGドキュメント: https://www.postgresql.org/docs/9.6/sql-createtrigger.html

W3の例: https://www.w3resource.com/PostgreSQL/postgresql-triggers.php

0
Allen Phelps