要求に応じた解決策
この不幸な設計に固執している間、最速のクエリはcrosstab()
を使用することです。 、追加モジュールtablefunc
によって提供されます 。この関連する回答の十分な詳細:
尋ねられた質問について:
SELECT * FROM crosstab(
$$SELECT e.id, ef.name, ef.value
FROM entry e
LEFT JOIN entry_fields ef
ON ef.entryid = e.id
AND ef.name = ANY ('{result,output,code,command}'::text[])
ORDER BY 1, 2$$
,$$SELECT unnest('{result,output,code,command}'::text[])$$
) AS ct (id int, result text, output text, code text, command text);
データベース設計
巨大ながない場合 さまざまなフィールドの数が増えると、はるかにシンプルで効率的になります 3つのテーブルすべてを1つの単純なテーブルにマージするには:
CREATE TABLE entry (
entry_id serial PRIMARY KEY
,field1 text
,field2 text
, ... more fields
);
値のないフィールドはNULL
にすることができます 。 NULL
ストレージは非常に安い (基本的に、NULLビットマップの列ごとに1ビット):
数百の異なる列があり、エントリごとに入力される列が少ない場合でも、使用するディスク容量ははるかに少なくなります。
クエリは簡単になります:
SELECT entry_id, result, output, code, command
FROM enty;
列が多すぎて、それが単なる誤った設計ではない場合(多くの場合、これははるかに少ない列に折りたたむことができます)、データ型を検討してください hstore
またはjson
/ jsonb
(Postgres 9.4の場合) EAV
ストレージ。
Maximum Columns per Table 250 - 1600 depending on column types
この関連する回答を別の方法で検討してください:
そして、dba.SEのEAV構造の典型的なユースケース/問題に関するこの質問: