5

TEXTなどの配列を含む複合型があります。これをメインテーブル内で使用して、複合型の配列を作成しています。
INSERTコマンドを生成するにはどうすればよいですか(複合型のデフォルトのフィールド名を使用せずに)?コンポジットの配列を使用してTEMPORARYTABLEを作成し、それをメインテーブルに挿入できますか?

例えば:

DROP TABLE collection;
DROP TABLE book_set;
DROP TYPE book;

CREATE TYPE book AS ( title TEXT, authors TEXT[], extra_spare TEXT );
CREATE TEMPORARY TABLE book_set ( books book[] );
CREATE TABLE shelf_collection ( shelf INT, position INT, books book[] );

-- Prefer to specify the fields I want, and NOT extra_spare as shown here!
-- AND it doesn't yet work... needs more casting?
INSERT INTO book_set( books ) VALUES (
      ( 'book1', array[ ( 'author1', 'author2' ) ], '' ),
      ( 'book2', array[ ( 'author3' )            ], '' ) ); 

-- And this obviously does not work yet!
INSERT INTO shelf_collection( shelf, position, books ) VALUES ( 1, 2, book_set ); 

最初のINSERTは、次のメッセージで失敗します。

エラー:INSERTにはターゲット列よりも多くの式があります。

array[]構文の有無にかかわらず同じように失敗します。

私の実際の使用法は非常に複雑で、コンポジットには他のコンポジットが含まれており、多くのフィールドがあります。

パフォーマンス上の理由から(取得に結合は必要ありません)、ここでは複数のテーブルを使用していません。また、内部のコンポジットと配列が個別に参照されることはありません。

私はperl(5.14.2)andDBI(1.616)とを使用してpsql(9.1.7)います。


より詳しい情報:

以下は機能しますが、本のすべてのフィールドを指定する必要がないように変更するにはどうすればよいですか。

DROP TABLE shelf_collection;
DROP TYPE book;

CREATE TYPE  book AS          ( title TEXT, authors TEXT[], extra_spare TEXT );
CREATE TABLE shelf_collection ( shelf INT, position INT, books book[] );

INSERT INTO shelf_collection VALUES ( 12, 23, array[ROW( 'book title 1', array[ 'author1', 'author2' ], '' )::book] );

SELECT * FROM shelf_collection;
4

1 に答える 1

4

PostgreSQL配列は便利な抽象化です(非標準、追加する必要があります)が、簡単に悪用される可能性があります-これはまさにあなたがやろうとしていることだと思います.

データベーススキーマを正規化しないための言い訳とショートカットとして配列を使用しようとしています。いくつかのクラッジでうまくいくかもしれませんが、これは長期的には価値がありません.

配列を使い続けると、SQL を本当に便利にする多くの構造を利用できなくなります。たとえば、book_set特定の著者についてテーブルを効果的に検索することはできません。

正しい設計は正規化することです -book_set著者の配列を含めるべきではありません。代わりに、別のテーブルauthorsと別のリンク テーブルを作成しますbook_author

確かに、正規化されたアプローチでは、データを挿入するのはより厄介であり、クエリを実行するのはやや厄介です。結合を実行する必要があります。

ただし、考えられるほぼすべてのクエリを作成できます。また、適切なインデックスを使用すると、データ セットが非常に大きい場合でも非常に高速に動作します。

于 2013-01-09T06:39:20.547 に答える