TL; DR: JSONB ã¯ãã¯ãšãªã®ããã©ãŒãã³ã¹ãç ç²ã«ããããšãªããããŒã¿ããŒã¹ ã¹ããŒãã®éçºãå€§å¹ ã«ç°¡çŽ åã§ããŸãã
å°å ¥
ãããããªã¬ãŒã·ã§ãã« ããŒã¿ããŒã¹ (ããŒã¿ããŒã¹) ã®äžçã§æãå€ã䜿çšäŸã® XNUMX ã€ã§ããå€å žçãªäŸã瀺ããŸãããããšã³ãã£ãã£ãããããã®ãšã³ãã£ãã£ã®ç¹å®ã®ãããã㣠(å±æ§) ãä¿åããå¿ èŠããããŸãã ãã ãããã¹ãŠã®ã€ã³ã¹ã¿ã³ã¹ãåãããããã£ã®ã»ãããæã€ããã§ã¯ãªããå°æ¥ããã«å€ãã®ããããã£ãè¿œå ãããå¯èœæ§ããããŸãã
ãã®åé¡ã解決ããæãç°¡åãªæ¹æ³ã¯ãããŒã¿ããŒã¹ ããŒãã«ã«ããããã£å€ããšã«åãäœæããç¹å®ã®ãšã³ãã£ã㣠ã€ã³ã¹ã¿ã³ã¹ã«å¿ èŠãªåãåçŽã«å ¥åããããšã§ãã çŽ æŽãããïŒ åé¡ã¯è§£æ±ºããŸãã...ããŒãã«ã«æ°çŸäžã®ã¬ã³ãŒããå«ãŸããŠãããæ°ããã¬ã³ãŒããè¿œå ããå¿ èŠããããŸã§ã¯ã
EAV ãã¿ãŒã³ãèããŠã¿ãŸããã (
ãã ããEVA ã®ã¢ãããŒãã«ããã€ãã®æ¬ ç¹ããªããã°ãç§ã¯ãã®èšäºãæžããŠããªãã£ãã§ãããã ãããã£ãŠãããšãã°ããããã 1 ã€ã®å±æ§ãæ〠2 ã€ä»¥äžã®ãšã³ãã£ãã£ãååŸããã«ã¯ãã¯ãšãªã§ 2 ã€ã®çµåãå¿
èŠã§ãã4 ã€ç®ã¯å±æ§ããŒãã«ãšã®çµåãXNUMX ã€ç®ã¯å€ããŒãã«ãšã®çµåã§ãã ãšã³ãã£ãã£ã« XNUMX ã€ã®å±æ§ãããå ŽåãXNUMX ã€ã®çµåãå¿
èŠã§ãã ããã«ãéåžžããã¹ãŠã®å±æ§ã¯æååãšããŠä¿åããããããçµæãš WHERE å¥ã®äž¡æ¹ã§åãã£ã¹ããè¡ãããŸãã 倧éã®ã¯ãšãªãäœæãããšããªãœãŒã¹ã®äœ¿çšãšããç¹ã§éåžžã«ç¡é§ã«ãªããŸãã
ãããã®æãããªæ¬ ç¹ã«ãããããããEAV ã¯ãã®çš®ã®åé¡ã解決ããããã«é·ãé䜿çšãããŠããŸããã ãããã¯é¿ããããªãæ¬ ç¹ã§ãããããããåªãã代æ¿æ段ã¯ãããŸããã§ããã
ããããPostgreSQL ã«æ°ããããã¯ãããžãŒããç»å ŽããŸãã...
PostgreSQL 9.4 以éãJSON ãã€ã㪠ããŒã¿ãä¿åããããã« JSONB ããŒã¿åãè¿œå ãããŸããã ãã®åœ¢åŒã§ JSON ãä¿åãããšãéåžžããã¬ãŒã³ ããã¹ãã® JSON ãããå€å°å€ãã®ã¹ããŒã¹ãšæéãããããŸãããæäœã®å®è¡ã¯ã¯ããã«é«éã«ãªããŸãã JSONB ã¯ã€ã³ããã¯ã¹äœæããµããŒãããŠãããããã¯ãšãªãããã«é«éã«ãªããŸãã
JSONB ããŒã¿åã䜿çšãããšããšã³ãã£ã㣠ããŒãã«ã« JSONB åã XNUMX ã€è¿œå ããã ãã§é¢å㪠EAV ãã¿ãŒã³ã眮ãæããããšãã§ãããããããŒã¿ããŒã¹èšèšãå€§å¹ ã«ç°¡çŽ åãããŸãã ããããããã«ã¯çç£æ§ã®äœäžã䌎ãã¯ãã ãšå€ãã®äººã䞻匵ããŠããŸã...ããã§ç§ã¯ãã®èšäºãæžããŸããã
ãã¹ãããŒã¿ããŒã¹ã®ã»ããã¢ãã
ãã®æ¯èŒã®ããã«ã$9.5 ãã«ãã® PostgreSQL 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
);
ããªãã·ã³ãã«ã«èŠããŸããã 次ã«ããšã³ãã£ã㣠ããŒãã«ã«è¿œå ãããŸãã (ãšã³ãã£ã㣠& ãšã³ãã£ãã£_jsonb) 10 äžã¬ã³ãŒããããã«å¿ããŠãEAV ãã¿ãŒã³ãš JSONB åã䜿çšããã¢ãããŒãã䜿çšããŠãããŒãã«ã«åãããŒã¿ãå ¥åãããŸãã - ãšã³ãã£ãã£_jsonb.propertiesã ãããã£ãŠãããããã£ã®ã»ããå šäœã®äžããããã€ãã®ç°ãªãããŒã¿åãåãåããŸããã ããŒã¿äŸ:
{
id: 1
name: "Entity1"
description: "Test entity no. 1"
properties: {
color: "red"
lenght: 120
width: 3.1882420
hassomething: true
country: "Belgium"
}
}
ããã§ãäž¡æ¹ã®ãªãã·ã§ã³ã«å¯ŸããŠåãããŒã¿ãåŸãããŸããã è·å Žã§ã®å®è£ ã®æ¯èŒãå§ããŸããã!
èšèšãç°¡çŽ åãã
ããŒã¿ããŒã¹èšèšãå€§å¹ ã«ç°¡çŽ åãããããšã¯åè¿°ããŸãããEAV ã« XNUMX ã€ã®ããŒãã«ã䜿çšãã代ããã«ãããããã£ã« JSONB åã䜿çšããããšã§ XNUMX ã€ã®ããŒãã«ã«ãªããŸããã ããããããã¯ãªã¯ãšã¹ãã«ã©ã®ããã«åæ ãããã®ã§ãããã? XNUMX ã€ã®ãšã³ãã£ã㣠ããããã£ãæŽæ°ãããšã次ã®ããã«ãªããŸãã
-- 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';
XNUMX çªç®ã®æ¹ãçã (çµåããªã) ãããããèªã¿ãããããšã«åæã§ãããšæããŸãã ããã§JSONBãåã¡ãŸãïŒ JSON ->> æŒç®åã䜿çšããŠãJSONB ãªããžã§ã¯ãããããã¹ãå€ãšããŠè²ãååŸããŸãã @> æŒç®åã䜿çšã㊠JSONB ã¢ãã«ã§åãçµæãéæãã XNUMX çªç®ã®æ¹æ³ããããŸãã
-- 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 ã¯ãšãªã®èšè¿°æ¹æ³ã®ãã®ä»ã®äŸãåç
§ããŠãã ããã
ä»åºŠã¯ããã©ãŒãã³ã¹ã«ã€ããŠè©±ããŸãã
ÐÑПОзвПЎОÑелÑМПÑÑÑ
ç§ã䜿çšããããã©ãŒãã³ã¹ãæ¯èŒããã«ã¯
ããŒã¿æŽæ°ã®æéïŒããªç§ïŒã§ã¯ä»¥äžã®çµæãåŸãããŸããã ã¹ã±ãŒã«ã察æ°ã§ããããšã«æ³šæããŠãã ããã
åè¿°ã®çç±ã«ãããã€ã³ããã¯ã¹ã䜿çšããªãå ŽåãJSONB 㯠EAV ãããã¯ããã« (> 50000-x) é«éã§ããããšãããããŸãã äž»ããŒã䜿çšããŠåã«ã€ã³ããã¯ã¹ãä»ãããšãå·®ã¯ã»ãšãã©ãªããªããŸãããããã§ã JSONB 㯠EAV ãã 1,3 åé«éã§ãã è©äŸ¡åºæºã§ããããã£åã䜿çšããŠããªããããJSONB åã®ã€ã³ããã¯ã¹ã¯ããã§ã¯å¹æããªãããšã«æ³šæããŠãã ããã
ããããã£å€ã«åºã¥ããŠããŒã¿ãéžæãããšã次ã®çµæãåŸãããŸã (éåžžã®ã¹ã±ãŒã«)ã
JSONB ã¯ã€ã³ããã¯ã¹ãªãã® EAV ãããé«éã«åäœããŸãããã€ã³ããã¯ã¹ããã® EAV ã®å Žåã§ããJSONB ãããé«éã«åäœããããšãããããŸãã ããããJSONB ã¯ãšãªã®æéãåãã§ããããšãããããGIN ã€ã³ããã¯ã¹ãæ©èœããªããšããäºå®ã«æ°ã¥ããŸããã ã©ããããããããã£ãèšå®ãããå㧠GIN ã€ã³ããã¯ã¹ã䜿çšããå Žåããã㯠include æŒç®å @> ã䜿çšããå Žåã«ã®ã¿æå¹ã«ãªããŸãã ãããæ°ãããã¹ãã§äœ¿çšããŸããããæéã«å€§ããªåœ±é¿ãäžããŸãã: ããã 0,153 ããªç§ã§ããã ããã¯ãEAV ãã 15000 åã->> æŒç®åãã 25000 åé«éã§ãã
ååéãã£ããšæããŸãïŒ
ããŒã¿ããŒã¹ããŒãã«ã®ãµã€ãº
äž¡æ¹ã®ã¢ãããŒãã®ããŒãã« ãµã€ãºãæ¯èŒããŠã¿ãŸãããã psql ã§ã¯ã次ã®ã³ãã³ãã䜿çšããŠãã¹ãŠã®ããŒãã«ãšã€ã³ããã¯ã¹ã®ãµã€ãºã衚瀺ã§ããŸãã dti+
EAV ã¢ãããŒãã®å ŽåãããŒãã« ãµã€ãºã¯çŽ 3068 MBãã€ã³ããã¯ã¹ã¯æ倧 3427 MB ã§ãåèš 6,43 GB ã«ãªããŸãã JSONB ã¢ãããŒãã§ã¯ãããŒãã«ã« 1817 MBãã€ã³ããã¯ã¹ã« 318 MBãã€ãŸã 2,08 GB ã䜿çšãããŸãã ãªããš3åãå°ãªãããšãå€æïŒ ãã¹ãŠã® JSONB ãªããžã§ã¯ãã«ããããã£åãæ ŒçŽããŠããããããã®äºå®ã«ã¯å°ãé©ããŸããã
ããããããã§ãæ°åããã¹ãŠãç©èªã£ãŠããŸããEAV ã§ã¯å±æ§å€ããšã« 2 ã€ã®æŽæ°å€éšããŒãä¿åããããã8 ãã€ãã®è¿œå ããŒã¿ãçããŸãã ããã«ãEAV ã¯ãã¹ãŠã®ããããã£å€ãããã¹ããšããŠä¿åããŸãããJSONB ã¯å¯èœãªéãå éšã§æ°å€ãšããŒã«å€ã䜿çšããããããããããªã³ããå°ãããªããŸãã
çµæ
å šäœãšããŠããšã³ãã£ã㣠ããããã£ã JSONB 圢åŒã§ä¿åãããšãããŒã¿ããŒã¹ã®èšèšãšä¿å®ãã¯ããã«ç°¡åã«ãªããšæããŸãã å€æ°ã®ã¯ãšãªãå®è¡ããŠããå Žåã¯ããã¹ãŠããšã³ãã£ãã£ãšåãããŒãã«ã«ä¿æãããšãå®éã«ã¯ããå¹ççã«åäœããŸãã ããã«ããããŒã¿éã®ããåããç°¡çŽ åããããšããäºå®ã¯ãã§ã«ãã©ã¹ã§ãããçµæãšããŠåŸãããããŒã¿ããŒã¹ã®å®¹é㯠3 åã® XNUMX ã«ãªããŸãã
ãŸããå®è¡ããããã¹ãã«åºã¥ããŠãããã©ãŒãã³ã¹ã®äœäžã¯éåžžã«ãããã§ãããšçµè«ä»ããããšãã§ããŸãã å Žåã«ãã£ãŠã¯ãJSONB 㯠EAV ãããé«éã§ãããããã«åªããŠããŸãã ãã ãããã®ãã³ãããŒã¯ã¯ãã¹ãŠã®åŽé¢ãã«ããŒããŠããããã§ã¯ãããŸãã (äŸ: éåžžã«å€æ°ã®ããããã£ãæã€ãšã³ãã£ãã£ãæ¢åããŒã¿ã®ããããã£æ°ã®å€§å¹
ãªå¢å ãªã©)ããã®ãããããããæ¹åããæ¹æ³ã«ã€ããŠã®ææ¡ãããã°ã ããæ°è»œã«ã³ã¡ã³ããæ®ããŠãã ããïŒ
åºæïŒ habr.com