Solusi seperti yang diminta
Saat terjebak dengan desain yang tidak menguntungkan ini, kueri tercepat adalah dengan crosstab()
, disediakan oleh modul tambahan tablefunc
. Banyak detail dalam jawaban terkait ini:
Untuk pertanyaan yang diajukan:
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);
Desain basis data
Jika Anda tidak memiliki besar sejumlah bidang yang berbeda, akan lebih sederhana dan lebih efisien untuk menggabungkan ketiga tabel menjadi satu tabel sederhana:
CREATE TABLE entry (
entry_id serial PRIMARY KEY
,field1 text
,field2 text
, ... more fields
);
Kolom tanpa nilai dapat berupa NULL
. NULL
penyimpanan sangat murah (pada dasarnya 1 bit per kolom dalam bitmap NULL):
- Berapa banyak ruang disk yang diperlukan untuk menyimpan nilai NULL menggunakan DB postgresql?
- Dapat dibatalkan kolom menempati ruang tambahan di PostgreSQL?
Bahkan jika Anda memiliki ratusan kolom berbeda, dan hanya sedikit yang terisi per entri, ini masih akan menggunakan lebih sedikit ruang disk.
Permintaan Anda menjadi sepele:
SELECT entry_id, result, output, code, command
FROM enty;
Jika Anda memiliki terlalu banyak kolom, dan itu bukan hanya desain yang salah arah (seringkali, ini dapat dilipat menjadi lebih sedikit kolom), pertimbangkan tipe data hstore
atau json
/ jsonb
(di Postgres 9.4) untuk EAV
penyimpanan.
Per halaman "Tentang" Postgres :
Maximum Columns per Table 250 - 1600 depending on column types
Pertimbangkan jawaban terkait ini dengan alternatif:
Dan pertanyaan ini tentang kasus penggunaan/masalah umum struktur EAV di dba.SE: