सच कहूं, तो सबसे अच्छा विकल्प "ईएवी नहीं" है। hstore
. का उपयोग करते हुए देखें फ़ील्ड, XML
, या json
।
PostgreSQL में प्रति-डेटाटाइप तालिकाओं का उपयोग करने के लिए कोई प्रदर्शन लाभ नहीं है। NULL
मानों को एक कॉम्पैक्ट NULL
. में संग्रहित किया जाता है बिटमैप, इसलिए इससे बहुत कम फर्क पड़ता है कि क्या आपके पास (NULL, NULL, NULL, 42, NULL, NULL)
जैसा टपल है। या सिर्फ (42)
।
यह आपको CHECK
. जोड़ने की अनुमति भी देता है बाधा यह लागू करती है कि ठीक एक फ़ील्ड गैर-NULL
होना चाहिए , इसलिए आपको विभिन्न प्रकार के एकाधिक मान नहीं मिलते हैं।
डेमो:
regress=> CREATE TABLE eav_ugh (
entity_id integer,
int_value integer,
numeric_value numeric,
text_value text,
timestamp_value timestamp with time zone,
CONSTRAINT only_one_non_null CHECK (
(int_value IS NOT NULL AND numeric_value IS NULL AND text_value IS NULL AND timestamp_value IS NULL) OR
(int_value IS NULL AND numeric_value IS NOT NULL AND text_value IS NULL AND timestamp_value IS NULL) OR
(int_value IS NULL AND numeric_value IS NULL AND text_value IS NOT NULL AND timestamp_value IS NULL) OR
(int_value IS NULL AND numeric_value IS NULL AND text_value IS NULL AND timestamp_value IS NOT NULL)
)
);
CREATE TABLE
regress=> insert into eav_ugh (entity_id, numeric_value) select x, x from generate_series(1,5000) x;
INSERT 0 5000
regress=> select pg_relation_size('eav_ugh');
pg_relation_size
------------------
229376
(1 row)
regress=> CREATE TABLE no_null_cols(entity_id integer, numeric_value numeric);
CREATE TABLE
regress=> insert into no_null_cols (entity_id, numeric_value) select x, x from generate_series(1,5000) x;
INSERT 0 5000
regress=> select pg_relation_size('no_null_cols');
pg_relation_size
------------------
229376
(1 row)
regress=> SELECT sum(pg_column_size(eav_ugh)) FROM eav_ugh;
sum
--------
164997
(1 row)
regress=> SELECT sum(pg_column_size(no_null_cols)) FROM no_null_cols;
sum
--------
164997
(1 row)
इस मामले में अलाइन बिटमैप संभवतः संरेखण आवश्यकताओं के कारण कोई स्थान नहीं जोड़ रहा है।