TL; DR: JSONB ืืืื ืืคืฉื ืืืื ืืช ืคืืชืื ืกืืืืช ืืกื ื ืชืื ืื ืืืื ืืืงืจืื ืืช ืืืฆืืขื ืืฉืืืืชืืช.
ืืืื
ืืื ื ืืชื ืืืืื ืงืืืกืืช ืืืื ืืืงืจื ืืฉืืืืฉ ืืขืชืืงืื ืืืืชืจ ืืขืืื ืฉื ืืกื ื ืชืื ืื ืืืกื (ืืกืืก ื ืชืื ืื): ืืฉ ืื ื ืืฉืืช, ืืื ืื ื ืฆืจืืืื ืืฉืืืจ ืืืคืืื ืื ืืกืืืืื (ืืืคืืื ืื) ืฉื ืืืฉืืช ืืื. ืื ืืืชืื ืฉืื ืืื ืืืืคืขืื ืืฉ ืืช ืืืชื ืงืืืฆืช ืืืคืืื ืื, ืืืืชืื ืฉืืชืืืกืคื ืืืคืืื ืื ื ืืกืคืื ืืขืชืื.
ืืืจื ืืงืื ืืืืชืจ ืืคืชืืจ ืืขืื ืื ืืื ืืืฆืืจ ืขืืืื ืืืืืช ืืกื ืื ืชืื ืื ืขืืืจ ืื ืขืจื ืืืคืืื, ืืคืฉืื ืืืื ืืช ืืื ืืืจืืฉืื ืขืืืจ ืืืคืข ืืฉืืช ืกืคืฆืืคื. ืืืื! ืืืขืื ื ืคืชืจื... ืขื ืฉืืืืื ืฉืื ืชืืื ืืืืืื ื ืจืฉืืืืช ืืืชื ืฆืจืื ืืืืกืืฃ ืจืฉืืื ืืืฉื.
ืฉืงืื ืืช ืืคืืก ื-EAV (
ืขื ืืืช, ืื ืืืืชื ืืืชื ืืช ืืคืืกื ืืื ืื ืื ืืื ืืื ืืกืจืื ืืช ืืืืฉืช EVA. ืื, ืืืฉื, ืืื ืืืฉืื ืืฉืืช ืืืช ืื ืืืชืจ ืฉืืฉ ืืื ืชืืื ื ืืืช ืืื ืืืช, ื ืืจืฉืืช 1 ืืฆืืจืคืืช ืืฉืืืืชื: ืืจืืฉืื ื ืืื ืฆืืจืืฃ ืขื ืืืืช ืืชืืื ืืช, ืืฉื ืืื ืืื ืฆืืจืืฃ ืขื ืืืืช ืืขืจืืื. ืื ืืืฉืืช ืืฉ 2 ืชืืื ืืช, ืืฉ ืฆืืจื ื-2 ืืฆืืจืคืืช! ืื ืืกืฃ, ืื ืืชืืื ืืช ืืืืืกื ืืช ืืืจื ืืื ืืืืจืืืืช, ืื ืฉืืืจื ืืืืืช ืกืื ืื ืขืืืจ ืืชืืฆืื ืืื ืขืืืจ ืกืขืืฃ WHERE. ืื ืืชื ืืืชื ืืจืื ืฉืืืืชืืช, ืื ืื ืื ืืืืื ื ืืืืื ืช ืฉืืืืฉ ืืืฉืืืื.
ืืืจืืช ืืืกืจืื ืืช ืืืจืืจืื ืืืื, ื ืขืฉื ืฉืืืืฉ ื-EAV ืืืจ ืืื ืจื ืืื ืืคืชืืจ ืืขืืืช ืืกืื ืื. ืืื ืืื ืืกืจืื ืืช ืืืชื ื ืื ืขืื, ืืคืฉืื ืื ืืืืชื ืืืืจื ืืืื ืืืื ืืืชืจ.
ืืื ืื ืืืคืืขื "ืืื ืืืืืื" ืืืฉื ื-PostgreSQL...
ืืื ื-PostgreSQL 9.4, ืกืื ืื ืชืื ืื JSONB ื ืืกืฃ ืืืืกืื ื ืชืื ืื ืืื ืืจืืื ืฉื JSON. ืืืจืืช ืฉืืืกืื JSON ืืคืืจืื ืื ืืืงื ืืืจื ืืื ืงืฆืช ืืืชืจ ืืงืื ืืืื ืืืฉืจ JSON ืืืงืกื ืจืืื, ืืืฆืืข ืืคืขืืืืช ืื ืืื ืืจืื ืืืชืจ ืืืืจ. JSONB ืชืืื ืื ืืืื ืืงืก, ืื ืฉืืืคื ืืช ืืฉืืืืชืืช ืืืืืจ ืขืื ืืืชืจ.
ืกืื ืื ืชืื ืื JSONB ืืืคืฉืจ ืื ื ืืืืืืฃ ืืช ืชืื ืืช ื-EAV ืืืกืืจืืืช ืขื ืืื ืืืกืคืช ืขืืืืช JSONB ืืืช ืืืื ืืืืืช ืืืฉืืืืช ืฉืื ื, ืื ืฉืืคืฉื ืืืื ืืช ืขืืฆืื ืืกื ืื ืชืื ืื. ืืื ืจืืื ืืืขื ืื ืฉืื ืฆืจืื ืืืืืช ืืืืื ืืืจืืื ืืคืจืืื... ืืื ืืชืืชื ืืช ืืืืืจ ืืื.
ืืงืืช ืืกื ื ืชืื ืื ืืืืืงืืช
ืืฆืืจื ืืฉืืืื ืื, ืืฆืจืชื ืืช ืืกื ืื ืชืื ืื ืขื ืืชืงื ื ืืืฉื ืฉื PostgreSQL 9.5 ื-build $80
CREATE TABLE entity (
id SERIAL PRIMARY KEY,
name TEXT,
description TEXT
);
CREATE TABLE entity_attribute (
id SERIAL PRIMARY KEY,
name TEXT
);
CREATE TABLE entity_attribute_value (
id SERIAL PRIMARY KEY,
entity_id INT REFERENCES entity(id),
entity_attribute_id INT REFERENCES entity_attribute(id),
value TEXT
);
ืืืื ืืืื ืฉืื ืืืฉืืจื ืืืชื ื ืชืื ืื, ืื ืขื ืชืืื ืืช ืืขืืืืช ืกืื JSONB - ื ืืกืื.
CREATE TABLE entity_jsonb (
id SERIAL PRIMARY KEY,
name TEXT,
description TEXT,
properties JSONB
);
ื ืจืื ืืจืื ืืืชืจ ืคืฉืื, ืื? ืืืืจ ืืื ืืื ืืชืืืกืฃ ืืืืืืืช ืืืฉืืืืช (ืืฉืืช & entity_jsonb) 10 ืืืืืื ืจืฉืืืืช, ืืืืชืื ืืื, ืืืืื ืืชืืืื ืืืืชื ื ืชืื ืื ืืืืฆืขืืช ืืคืืก ื-EAV ืืืืืฉื ืขื ืขืืืืช JSONB - entity_jsonb.properties. ืืคืืื, ืงืืืื ื ืืกืคืจ ืกืืื ื ืชืื ืื ืฉืื ืื ืืื ืื ืืขืจื ืืืืคืืื ืื. ื ืชืื ืื ืืืืืื:
{
id: 1
name: "Entity1"
description: "Test entity no. 1"
properties: {
color: "red"
lenght: 120
width: 3.1882420
hassomething: true
country: "Belgium"
}
}
ืื ืขืืฉืื ืืฉ ืื ื ืืช ืืืชื ื ืชืื ืื ืขืืืจ ืฉืชื ืืืคืฉืจืืืืช. ืืืื ื ืชืืื ืืืฉืืืช ืืืฉืืืื ืืขืืืื!
ืคืฉื ืืช ืืขืืฆืื ืฉืื
ื ืืืจ ืืขืืจ ืื ืขืืฆืื ืืกื ืื ืชืื ืื ืืื ืืคืืฉื ืืืื: ืืืื ืืืช, ืขื ืืื ืฉืืืืฉ ืืขืืืืช JSONB ืืืืคืืื ืื, ืืืงืื ืฉืืืืฉ ืืฉืืืฉ ืืืืืืช ืขืืืจ EAV. ืืื ืืื ืื ืื ืืืื ืืืืื ืืืงืฉืืช? ืขืืืื ืืืคืืื ืืฉืืช ืืื ื ืจืื ืื:
-- EAV
UPDATE entity_attribute_value
SET value = 'blue'
WHERE entity_attribute_id = 1
AND entity_id = 120;
-- JSONB
UPDATE entity_jsonb
SET properties = jsonb_set(properties, '{"color"}', '"blue"')
WHERE id = 120;
ืืคื ืฉืืชื ืืืื ืืจืืืช, ืืืงืฉื ืืืืจืื ื ืื ื ืจืืืช ืคืฉืืื ืืืชืจ. ืืื ืืขืืื ืืช ืืขืจื ืฉื ืืืคืืื ืืืืืืืงื JSONB ืขืืื ื ืืืฉืชืืฉ ืืคืื ืงืฆืื
ืืขืช, ืืืื ื ืืืจ ืืช ืืืฉืืช ืฉืขืืื ื ืื ืขืชื ืขื ืกืื ืืฆืืข ืืืืฉ ืฉืื:
-- EAV
SELECT e.name
FROM entity e
INNER JOIN entity_attribute_value eav ON e.id = eav.entity_id
INNER JOIN entity_attribute ea ON eav.entity_attribute_id = ea.id
WHERE ea.name = 'color' AND eav.value = 'blue';
-- JSONB
SELECT name
FROM entity_jsonb
WHERE properties ->> 'color' = 'blue';
ืื ื ืืืฉื ืฉืื ืื ื ืืืืืื ืืืกืืื ืฉืืฉื ื ืงืฆืจ ืืืชืจ (ืืื ืืฆืืจืคืืช!), ืืืื ืงืจืื ืืืชืจ. JSONB ืื ืฆื ืืื! ืื ื ืืฉืชืืฉืื ืืืืคืจืืืจ JSON ->> ืืื ืืงืื ืืช ืืฆืืข ืืขืจื ืืงืกื ืืืืืืืงื JSONB. ืืฉื ื ืื ืืจื ืฉื ืืื ืืืฉืื ืืช ืืืชื ืชืืฆืื ืืืืื JSONB ืืืืฆืขืืช ืืืืคืจืืืจ @>:
-- JSONB
SELECT name
FROM entity_jsonb
WHERE properties @> '{"color": "blue"}';
ืื ืงืฆืช ืืืชืจ ืืกืืื: ืื ืื ื ืืืืงืื ืื ืืืืืืงื JSON ืืขืืืืช ืืืืคืืื ืื ืฉืื ืืืื ืืืืืืงื ืฉื ืืฆื ืืืืื ืืืืคืจืืืจ @>. ืคืืืช ืงืจืื, ืคืจืืืืงืืืื ืืืชืจ (ืจืื ืืืื).
ืืืื ื ืืคืื ืืช ืืฉืืืืฉ ื-JSONB ืืงื ืขืื ืืืชืจ ืืืฉืจ ืขืืืื ืืืืืจ ืืกืคืจ ืืืคืืื ืื ืื-ืืื ืืช. ืืื ืืืืช ื ืื ืกืช ืืชืืื ื ืืืฉืช JSONB: ืื ื ืคืฉืื ืืืืจืื ืืืคืืื ืื ืืขืืืืืช ื ืืกืคืืช ืืขืจืืช ืืชืืฆืืืช ืฉืื ื ืืื ืฆืืจื ืืืฆืืจืคืืช:
-- JSONB
SELECT name
, properties ->> 'color'
, properties ->> 'country'
FROM entity_jsonb
WHERE id = 120;
ืขื EAV ืชืฆืืจื 2 ืืฆืืจืคืืช ืืื ื ืืก ืฉืืชื ืจืืฆื ืืฉืืื. ืืืขืชื, ืืฉืืืืชืืช ืืขืื ืืจืืืช ืคืฉืืืช ืจืื ืืขืืฆืื ืืกื ืื ืชืื ืื. ืจืื ืืืืืืืช ื ืืกืคืืช ืืืฆื ืืืชืื ืฉืืืืชืืช JSONB, ืื ื
ืขืืฉืื ืืืืข ืืืื ืืืืจ ืขื ืืืฆืืขืื.
ืคืจืืืืงืืืืืืช
ืืื ืืืฉืืืช ืืืฆืืขืื ืืฉืชืืฉืชื
ืขืืืื ืื ืชืื ืื ืืจืื ืืช ืืชืืฆืืืช ืืืืืช ืืืื ืืื ืฉื ืืื (ื-ms). ืฉืืื ืื ืฉืืกืงืืื ืืื ืืืืจืืชืืืช:
ืื ื ืจืืืื ืฉ-JSONB ืืืืจ ืืืจืื (>50000-x) ื-EAV ืื ืืื ื ืืฉืชืืฉ ืืืื ืืงืกืื, ืืืกืืื ืฉืฆืืื ื ืืขืื. ืืืฉืจ ืื ื ืืืงืกืื ืขืืืืืช ืขื ืืคืชืืืช ืจืืฉืืื, ืืืืื ืืืขื ื ืขืื, ืืื JSONB ืขืืืื ืืืืจ ืคื 1,3 ื-EAV. ืฉืืื ืื ืฉืืืื ืืงืก ืืขืืืืช JSONB ืืื ืืฉืคืขื ืืื ืืืืืื ืฉืืื ื ื ืืฉืชืืฉืื ืืขืืืืช ืืืืคืืื ืื ืืงืจืืืจืืื ื ืืืขืจืื.
ืืืืืจืช ื ืชืื ืื ืืืืืกืกืื ืขื ืขืจื ืื ืืก, ื ืงืื ืืช ืืชืืฆืืืช ืืืืืช (ืงื ื ืืืื ืจืืื):
ืืชื ืืืื ืืฉืื ืื ืฉ-JSONB ืฉืื ืขืืื ืืืจ ืืืชืจ ื-EAV ืืื ืืื ืืงืกืื, ืืื ืืืฉืจ EAV ืขื ืืื ืืงืกืื, ืืื ืขืืืื ืขืืื ืืืจ ืืืชืจ ื-JSONB. ืืื ืื ืจืืืชื ืฉืืืื ืื ืขืืืจ ืฉืืืืชืืช JSONB ืืืื, ืื ืืจื ืื ืืขืืืื ืฉืืื ืืงืกื GIN ืื ืขืืืืื. ืืื ืื ืจืื ืืืฉืจ ืืชื ืืฉืชืืฉ ืืืื ืืงืก GIN ืขื ืขืืืื ืขื ืืืคืืื ืื ืืืืืืกืื, ืื ื ืื ืก ืืชืืงืฃ ืจืง ืืืฉืจ ืืชื ืืฉืชืืฉ ืืืืคืจืืืจ include @>. ืืฉืชืืฉืชื ืืื ืืืืืงื ืืืฉื ืืืืืชื ืื ืืฉืคืขื ืขืฆืืื ืขื ืืืื: ืจืง 0,153ms! ืื ืืืืจ ืคื 15000 ื-EAV ืืคื 25000 ืืืจ ืืืชืจ ืืืืคืขืื ->>.
ืื ื ืืืฉื ืฉืื ืืื ืืกืคืืง ืืืืจ!
ืืืื ืืืืช ืืกื ื ืชืื ืื
ืืื ื ืฉืืื ืืช ืืืื ืืืืื ืขืืืจ ืฉืชื ืืืืฉืืช. ื-psql ื ืืื ืืืจืืืช ืืช ืืืืื ืฉื ืื ืืืืืืืช ืืืืื ืืงืกืื ืืืืฆืขืืช ืืคืงืืื dti+
ืขืืืจ ืืืฉืช ื-EAV, ืืืื ืืืืื ืื ืืกืืืืืช 3068 ืืื-ืืืื ืืืื ืืงืกืื ืฉื ืขื 3427 ืืื-ืืืื ืขืืืจ ืกื ืฉื 6,43 ื'ืืื-ืืืื. ืืืฉืช JSONB ืืฉืชืืฉืช ื-1817 MB ืขืืืจ ืืืืื ื-318 MB ืขืืืจ ืืืื ืืงืกืื, ืฉืื 2,08 GB. ืื ืืืฆื ืคื 3 ืคืืืช! ืขืืืื ืื ืืคืชืืขื ืืืชื ืืขื ืืืืืื ืฉืื ื ืืืืกื ืื ืฉืืืช ื ืืกืื ืืื ืืืืืืงื JSONB.
ืืื ืขืืืื, ืืืกืคืจืื ืืืืจืื ืืขื ืขืฆืื: ื-EAV ืื ื ืืืืกื ืื 2 ืืคืชืืืช ืืจืื ืฉืืืื ืืื ืขืจื ืชืืื ื, ืืืชืืฆืื ืืื 8 ืืชืื ืฉื ื ืชืื ืื ื ืืกืคืื. ืื ืืกืฃ, EAV ืืืืกื ืืช ืื ืขืจืื ืื ืืกืื ืืืงืกื, ืืขืื ืฉ-JSONB ืืฉืชืืฉ ืืขืจืืื ืืกืคืจืืื ืืืืืืื ืืื ืืืืคื ืคื ืืื ืืืืืช ืืืคืฉืจ, ืืืชืืฆืื ืืื ืืืืขืช ืจืื ืงืื ื ืืืชืจ.
ืชืืฆืืืช ืฉื
ืืกื ืืื, ืื ื ืืืฉื ืฉืฉืืืจืช ืืืคืืื ื ืืฉืืช ืืคืืจืื JSONB ืืืืื ืืืงื ืขื ืืขืืฆืื ืืืชืืืืงื ืฉื ืืกื ืื ืชืื ืื ืฉืื. ืื ืืชื ืืคืขืื ืืจืื ืฉืืืืชืืช, ืฉืืืจื ืขื ืืื ืืืืชื ืืืื ืืื ืืืฉืืช ืชืขืืื ืืฆืืจื ืืขืืื ืืืชืจ. ืืืขืืืื ืฉืื ืืคืฉื ืืช ืืืื ืืจืืงืฆืื ืืื ืื ืชืื ืื ืืื ืืืจ ืืชืจืื, ืืื ืืกื ืื ืชืื ืื ืืืชืงืื ืงืื ืคื 3 ืื ืคื.
ืืื ืื, ืขื ืกืื ืืืืืงืืช ืฉืืืฆืขื, ืื ื ืืืืืื ืืืกืืง ืฉืืคืกื ืืืืฆืืขืื ืืื ืืืื ืื ืืฉืืขืืชื. ืืืงืจืื ืืกืืืืื, JSONB ืืคืืื ืืืืจ ืืืชืจ ื-EAV, ืื ืฉืืืคื ืืืชื ืืคืืื ืืื ืืืชืจ. ืขื ืืืช, ืจืฃ ืื ืืืืื ืืื ื ืืืกื ืืช ืื ืืืืืืื (ืืืฉื ืืฉืืืืช ืขื ืืกืคืจ ืืืื ืืืื ืฉื ื ืืกืื, ืืืืื ืืฉืืขืืชื ืืืกืคืจ ืืืืคืืื ืื ืฉื ื ืชืื ืื ืงืืืืื,...), ืื ืื ืืฉ ืื ืืฆืขืืช ืืื ืืฉืคืจ ืืืชื , ืื ื ืื ืชืืกืก ืืืฉืืืจ ืืชืืืืืช!
ืืงืืจ: www.habr.com