Oplossing zoals gevraagd
Hoewel je vastzit aan dit ongelukkige ontwerp, zou de snelste zoekopdracht zijn met crosstab()
, geleverd door de aanvullende module tablefunc
. Voldoende details in dit gerelateerde antwoord:
Voor de gestelde vraag:
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);
Databaseontwerp
Als je geen enorme . hebt aantal verschillende velden, wordt het veel eenvoudiger en efficiënter om alle drie de tabellen samen te voegen tot één eenvoudige tabel:
CREATE TABLE entry (
entry_id serial PRIMARY KEY
,field1 text
,field2 text
, ... more fields
);
Velden zonder waarden kunnen NULL
zijn . NULL
opslag is erg goedkoop (in principe 1 bit per kolom in de NULL-bitmap):
- Hoeveel schijfruimte is er nodig om een NULL-waarde op te slaan met behulp van postgresql DB?
- Doe nullable kolommen extra ruimte innemen in PostgreSQL?
Zelfs als je honderden verschillende kolommen hebt, en er zijn er maar een paar per item gevuld, zal dit nog steeds veel minder schijfruimte in beslag nemen.
Je vraag wordt triviaal:
SELECT entry_id, result, output, code, command
FROM enty;
Als je te veel kolommen hebt, en dat is niet alleen een misleidend ontwerp (vaak kan dit in veel minder kolommen worden gevouwen), overweeg dan de gegevenstypen hstore
of json
/ jsonb
(in Postgres 9.4) voor EAV
opslag.
Maximum Columns per Table 250 - 1600 depending on column types
Overweeg dit gerelateerde antwoord met alternatieven:
En deze vraag over typische gebruiksgevallen / problemen van EAV-structuren op dba.SE: