web-dev-qa-db-ja.com

1つの列に配列または複数の値を保存する方法

Postgres 7.4の実行(ええ、アップグレードの最中です)

1〜100個の選択したアイテムをデータベースの1つのフィールドに保存する必要があります。 98%の場合、1つの項目が入力され、2%の場合(その場合)は複数の項目が入力されます。

アイテムはテキストの説明にすぎず、(現時点では)30文字以下です。ユーザーが選択する静的な値です。

目的のデータの保存に使用される最適な列データ型を知りたい。私はBLOBを考えていましたが、これが行き過ぎかどうかは知りませんでした。たぶんJSON?

また、私はENUMについて考えましたが、Postgres 7.4を実行しているので、今のところ、これを実際に行うことはできません

また、入力したアイテムを簡単に識別できるようにしたいので、マッピングや参照テーブルはありません。

29
Phill Pafford

ここにはいくつか質問がありますので、個別に対処します。

選択した多数のアイテムをデータベースの1つのフィールドに保存する必要があります

私の一般的なルールは:しないでください。これは、必須外部キーを持つ2番目のテーブル(または3番目)以外のものです。確かに、今は簡単に見えるかもしれませんが、これらのアイテムを個別に実際にクエリする必要がある場合にユースケースが登場するとどうなりますか?また、遅延インスタンシエーションのオプションが増え、複数のフレームワーク/言語でより一貫したエクスペリエンスが得られることも意味します。さらに、接続タイムアウトの問題が発生する可能性は低くなります(30,000文字が多い)。

ENUMの使用を検討しているとおっしゃいました。これらの値は修正されていますか?事前に知っていますか?もしそうなら、これは私の構造になります:

ベーステーブル(現在のテーブル):

| id primary_key sequence
| -- other columns here.

アイテム表:

| id primary_key sequence
| descript VARCHAR(30) UNIQUE

地図表:

| base_id  bigint
| items_id bigint

マップテーブルには外部キーがあるため、base_idはベーステーブルにマップされ、items_idはアイテムテーブルにマップされます。

DBからこれを簡単に取得したい場合は、結合を行うビューを作成します。挿入ルールと更新ルールを作成して、実際には1つのテーブルのみを処理することもできます。

データの保存に使用する形式は何ですか?

このようなことをしなければならない場合、文字で区切られた文字列を使用しないのはなぜですか? CSV、XML、またはJSONよりも処理能力が低く、短くなります。

どの列タイプを使用してデータを保存する必要がありますか?

個人的には、TEXTを使用します。これをBLOBにすることで多くの利益を得られるとは思えませんが、私の経験では、何らかの形式のIDEを使用している場合、TEXTは読みやすくなります。

41
cwallenpoole

さて、最近のPostgresバージョンには array type があります(PG 7.4については100%ではありません)。 GINまたはGistインデックスを使用して、インデックスを作成することもできます。構文は次のとおりです。

create table foo (
  bar  int[] default '{}'
);

select * from foo where bar && array[1] -- equivalent to bar && '{1}'::int[]

create index on foo using gin (bar); -- allows to use an index in the above query

しかし、前の答えが示唆するように、適切に正規化する方が良いでしょう。

6