Řešení podle požadavků
I když zůstal u tohoto nešťastného návrhu, nejrychlejší dotaz by byl pomocí crosstab()
, který poskytuje doplňkový modul tablefunc
. Dostatek podrobností v této související odpovědi:
Na položenou otázku:
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);
Návrh databáze
Pokud nemáte obrovské množství různých polí, bude to mnohem jednodušší a efektivnější sloučit všechny tři tabulky do jedné jednoduché tabulky:
CREATE TABLE entry (
entry_id serial PRIMARY KEY
,field1 text
,field2 text
, ... more fields
);
Pole bez hodnot mohou být NULL
. NULL
úložiště je velmi levné (v NULL bitmapě v podstatě 1 bit na sloupec):
- Kolik místa na disku je potřeba k uložení hodnoty NULL pomocí postgresql DB?
- Udělejte hodnotu null sloupce zabírají další místo v PostgreSQL?
I když máte stovky různých sloupců a na jeden záznam jich je vyplněno jen několik, zabere to mnohem méně místa na disku.
Váš dotaz se stává triviálním:
SELECT entry_id, result, output, code, command
FROM enty;
Pokud máte příliš mnoho sloupců a nejedná se pouze o zavádějící návrh (často to lze složit do mnohem menšího počtu sloupců), zvažte datové typy hstore
nebo json
/ jsonb
(v Postgres 9.4) pro EAV
úložiště.
Maximum Columns per Table 250 - 1600 depending on column types
Zvažte tuto související odpověď s alternativami:
A tato otázka ohledně typických případů použití / problémů struktur EAV na dba.SE: