Ke hoʻololi nei iā EAV me JSONB ma PostgreSQL

TL; DR: Hiki iā JSONB ke hoʻomaʻamaʻa nui i ka hoʻomohala ʻana i ka schema database me ka ʻole e kaumaha ana i ka hana nīnau.

Hōʻike

E lawe kākou i kekahi laʻana maʻamau, ʻo ia paha kekahi o nā hihia hoʻohana kahiko loa ma ka honua o nā ʻikepili pili: loaʻa iā mākou kahi hui, a pono mākou e mālama i kekahi mau waiwai (ʻano) o kēia hui. Akā, ʻaʻole like nā ʻano waiwai a pau, a hiki ke hoʻohui ʻia nā waiwai hou aʻe i ka wā e hiki mai ana.

ʻO ka hopena maʻalahi loa i kēia pilikia, ʻo ia ka hana ʻana i kahi kolamu ma ka papa ʻikepili no kēlā me kēia waiwai waiwai a hoʻopiha wale i nā mea e pono ai no kahi ʻano hui kikoʻī. Nui! Hoʻoholo ʻia ka pilikia... a hiki i kāu papaʻaina ke loaʻa nā miliona o nā moʻolelo a pono ʻoe e hoʻohui i kahi moʻolelo hou.

E noʻonoʻo kākou i ke ʻano EAV (Hui-Hui-Waiwai), he mea maʻamau. Aia kekahi papa ʻaina i nā hui (nā moʻolelo), aia kekahi papa ʻaina i nā inoa waiwai (ʻano), a ʻo kahi papa ʻekolu e hoʻopili ai i nā hui i ko lākou mau ʻano a loaʻa nā waiwai o kēia mau ʻano no ka hui o kēia manawa. Hāʻawi kēia iā ʻoe e loaʻa i nā ʻano waiwai like ʻole no nā mea like ʻole, a me ka hoʻohui ʻana i nā waiwai ma ka lele, me ka ʻole o ka hoʻololi ʻana i ka ʻōnaehana waihona.

Eia naʻe, ʻaʻole wau e kākau i kēia pou inā ʻaʻole he mau hemahema i ke ala EVA. No ka laʻana, ʻo ka hoʻihoʻi ʻana i hoʻokahi a ʻoi aku paha nā hui me hoʻokahi hiʻohiʻona e pono ai i ʻelua hui ʻana i ka nīnau: ʻo ka hui mua me ka papa ʻano, ʻo ka hui ʻelua me ka papa waiwai. Inā ʻelua mau ʻano o ka hui, a laila pono ʻehā hui! Eia kekahi, mālama mau ʻia nā ʻano a pau ma ke ʻano he mau kaula, e hopena i ke ʻano koi no ka hopena a me ka māhele WHERE. Inā kākau ʻoe i nā nīnau he nui, he mea makehewa kēia ma ke ʻano o ka hoʻohana waiwai.

ʻOiai kēia mau hemahema, ua hoʻohana lōʻihi ʻia ʻo EAV e hoʻoponopono i kēia mau pilikia. He mau hemahema hiki ʻole ke pale ʻia kēia, a ʻaʻohe mea ʻoi aku ka maikaʻi.
Akā ua puka mai kahi "ʻenehana" hou ma PostgreSQL ...

E hoʻomaka ana me PostgreSQL 9.4, ua hoʻohui ʻia ke ʻano ʻikepili JSONB no ka mālama ʻana i ka ʻikepili binary JSON. ʻOiai ʻo ka mālama ʻana iā JSON ma kēia ʻano, ʻoi aku ka nui o ka manawa a me ka manawa ma mua o ka JSON kikokikona maʻamau, ʻoi aku ka wikiwiki o nā hana me ia. Kākoʻo pū ʻo JSONB i ka kuhikuhi ʻana, e wikiwiki ana i nā nīnau.

Hiki i ke ʻano ʻikepili JSONB ke hoʻololi i ke ʻano EAV paʻakikī ma ka hoʻohui ʻana i kahi kolamu JSONB hoʻokahi i kā mākou papa ʻaina, me ka maʻalahi o ka hoʻolālā ʻikepili. Eia naʻe, manaʻo nui ka poʻe he kumu kūʻai kēia ma ka hana… ʻO ia ke kumu aʻu i kākau ai i kēia ʻatikala.

Hoʻonohonoho i kahi waihona hoʻāʻo

No kēia hoʻohālikelike, hana wau i ka waihona ma kahi hoʻokomo hou o PostgreSQL 9.5 ma ka hale $80. ʻO DigitalOcean Ubuntu 14.04 Ma hope o ka hoʻonohonoho ʻana i kekahi mau palena ma postgresql.conf ua holo wau kēia palapala me ka psql. No ka hōʻike ʻana i ka ʻikepili ma ke ʻano he EAV, ua hana ʻia nā papa ma lalo nei:

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
);

Aia ma lalo kahi papa kahi e mālama ʻia ai nā ʻikepili like, akā me nā ʻano i loko o kahi kolamu JSONB - nā mea waiwai.

CREATE TABLE entity_jsonb (
  id          SERIAL PRIMARY KEY, 
  name        TEXT, 
  description TEXT,
  properties  JSONB
);

ʻOi aku ka maʻalahi, ʻaʻole anei? A laila ua hoʻohui ʻia i nā papa ʻaina (ka hui & entity_jsonb) 10 miliona mau moʻolelo, a no laila, ua hoʻopiha ʻia ka papaʻaina me nā ʻikepili like kahi i hoʻohana ʻia ai ke kumu EAV a me ke ala me ke kolamu JSONB - entity_jsonb.propertiesNo laila, ua loaʻa iā mākou nā ʻano ʻikepili like ʻole ma ka pūʻulu holoʻokoʻa o nā waiwai. ʻikepili laʻana:

{
  id:          1
  name:        "Entity1"
  description: "Test entity no. 1"
  properties:  {
    color:        "red"
    lenght:       120
    width:        3.1882420
    hassomething: true
    country:      "Belgium"
  } 
}

No laila, i kēia manawa ua loaʻa iā mākou ka ʻikepili like no nā koho ʻelua. E hoʻomaka kākou e hoʻohālikelike i nā hoʻokō i ke ola maoli!

Hoʻomaʻamaʻa i ka hoʻolālā

Ua ʻōlelo ʻia ma mua ua maʻalahi ka hoʻolālā ʻikepili: hoʻokahi papa, me ka hoʻohana ʻana i kahi kolamu JSONB no nā waiwai, ma kahi o ʻekolu mau papa no EAV. Akā, pehea kēia e unuhi ai i nā nīnau? ʻO ka hoʻonui ʻana i kahi waiwai hui hoʻokahi e like me kēia:

-- 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;

E like me kāu e ʻike ai, ʻaʻole maʻalahi ka hulina hope. No ka hoʻonui i ka waiwai o kahi waiwai i kahi mea JSONB, pono mākou e hoʻohana i ka hana jsonb_set(), a pono e hāʻawi i kā mākou waiwai hou ma ke ʻano he mea JSONB. Akā naʻe, ʻaʻole pono mākou e ʻike i kahi mea hōʻike ma mua. Ke nānā nei i ka laʻana EAV, pono mākou e ʻike i ka entity_id a me entity_attribute_id e hana i ka hoʻopou. Inā makemake ʻoe e hoʻohou i kahi waiwai ma kahi kolamu JSONB e pili ana i ka inoa mea, hana ʻia ma kahi laina maʻalahi.

E koho kāua i ka hui a mākou i hōʻano hou ai ma muli o kona kala hou:

-- 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';

Manaʻo wau hiki iā mākou ke ʻae ʻoi aku ka pōkole o ka lua (me ka ʻole o ka hui!) Ua lanakila ʻo JSONB ma ʻaneʻi! Hoʻohana mākou i ka JSON ->> mea hoʻohana e kiʻi i ke kala ma ke ʻano he waiwai kikokikona mai ka mea JSONB. Aia kekahi ala ʻelua e hoʻokō ai i ka hopena like i ka hoʻohālike JSONB me ka hoʻohana ʻana i ka @> mea hoʻohana:

-- JSONB 
SELECT name 
FROM entity_jsonb 
WHERE properties @> '{"color": "blue"}';

ʻOi aku ka paʻakikī o kēia: nānā mākou inā aia ka mea JSON ma ke kolamu waiwai i ka mea ma ka ʻaoʻao ʻākau o ka mea hoʻohana @>. ʻAʻole hiki ke heluhelu ʻia, ʻoi aku ka hana (e nānā i lalo).

E maʻalahi ka hoʻohana ʻana iā JSONB inā pono ʻoe e koho i nā waiwai he nui i ka manawa hoʻokahi. ʻO kēia kahi e ʻālohilohi maoli ai ke ala JSONB: koho wale mākou i nā waiwai e like me nā kolamu hou i kā mākou hoʻonohonoho hopena, me ka ʻole o ka pono e hui pū:

-- JSONB 
SELECT name
  , properties ->> 'color'
  , properties ->> 'country'
FROM entity_jsonb 
WHERE id = 120;

Me EAV, pono ʻoe i ʻelua hui no kēlā me kēia waiwai āu e makemake ai e nīnau. I koʻu manaʻo, hōʻike nā nīnau ma luna nei i kahi maʻalahi maʻalahi i ka hoʻolālā waihona. Hiki iā ʻoe ke ʻike i nā hiʻohiʻona hou aʻe o ke kākau ʻana i nā nīnau JSONB i loko kēia pou.
ʻO ka manawa kēia e kamaʻilio e pili ana i ka hana.

'Ohanahana

E hoʻohālikelike i ka hana aʻu i hoʻohana ai E HOAKAKA I KA HOIKE i nā nīnau e helu i ka manawa hoʻokō. Ua hoʻokō ʻia kēlā me kēia nīnau i ʻekolu manawa, no ka mea, ʻoi aku ka lōʻihi o ka mea hoʻolālā nīnau i ka manawa mua. ʻO ka mea mua, holo wau i nā nīnau me ka ʻole o nā kuhikuhi. He mea pono kēia no JSONB, no ka mea, ʻaʻole hiki i nā hui i koi ʻia no EAV ke hoʻohana i nā kuhikuhi (ʻaʻole i kuhikuhi ʻia nā kī kī haole). Ma hope o kēlā, ua hana au i papa kuhikuhi ma nā kolamu kī haole ʻelua o ka papa waiwai EAV, a me kahi kuhikuhi. KAHAI no ke kolamu JSONB.

Hōʻike nā hōʻano hou ʻikepili i nā hopena manawa aʻe (ma ms). E hoʻomaopopo he logarithmic ka pālākiō:

Ke hoʻololi nei iā EAV me JSONB ma PostgreSQL

ʻIke mākou he ʻoi aku ka wikiwiki o JSONB (> 50000x) ma mua o EAV me ka ʻole o nā kuhikuhi, no ke kumu i ʻōlelo ʻia ma luna. Ke kuhikuhi mākou i nā kolamu kī nui, aneane nalo ka ʻokoʻa, akā ʻoi aku ka wikiwiki o JSONB ma mua o EAV. E hoʻomanaʻo, ʻaʻohe hopena o ka papa kuhikuhi ma ka kolamu JSONB ma ʻaneʻi, no ka mea ʻaʻole mākou e hoʻohana i ke kolamu waiwai i nā pae loiloi.

No ke koho ʻikepili e pili ana i ka waiwai waiwai, loaʻa iā mākou nā hopena aʻe (ka unahi maʻamau):

Ke hoʻololi nei iā EAV me JSONB ma PostgreSQL

Hiki iā ʻoe ke ʻike ua ʻoi aku ka wikiwiki o JSONB ma mua o EAV me ka ʻole o nā kuhikuhi, akā ke kuhikuhi ʻia ʻo EAV, ʻoi aku ka wikiwiki ma mua o JSONB. Akā, ʻike wau ua like nā manawa no nā nīnau JSONB, kahi i alakaʻi iaʻu i ka ʻoiaʻiʻo ʻaʻole i hoʻāla ʻia nā index GIN. ʻIke ʻia, ke hoʻohana ʻoe i kahi index GIN ma kahi kolamu me nā waiwai nui, hoʻohana wale ia i ka wā e hoʻohana ai i ka @> hoʻokomo. Ua hoʻohana au i kēia ma kahi hoʻāʻo hou, a he hopena nui loa ia i ka manawa: 0,153 ms wale nō! He 15000 manawa ʻoi aku ka wikiwiki ma mua o EAV a he 25000 manawa ʻoi aku ka wikiwiki ma mua o ka mea hoʻohana ->>.

Manaʻo wau ua wikiwiki loa!

Ka nui o nā papa ʻikepili

E hoʻohālikelike kākou i ka nui o ka pākaukau no nā ala ʻelua. I ka psql, hiki iā mākou ke hōʻike i ka nui o nā papa a me nā kuhikuhi me ka hoʻohana ʻana i ke kauoha dti+

Ke hoʻololi nei iā EAV me JSONB ma PostgreSQL

Me ka hoʻokokoke EAV, ʻoi aku ka nui o ka papa ʻaina ma kahi o 3068 MB, a ʻo nā helu kuhikuhi a hiki i 3427 MB, no ka huina o 6,43 GB. Ke hoʻohana nei i ke ala JSONB, hoʻohana ka papa ʻaina i ka 1817 MB a me nā kuhikuhi 318 MB, no ka huina o 2,08 GB. ʻO ka hapakolu kēlā o ka nui! ʻO kēia ʻoiaʻiʻo i kāhāhā iki iaʻu, no ka mea, mālama mākou i nā inoa waiwai i kēlā me kēia mea JSONB.

Akā, ʻōlelo nā helu no lākou iho: ma EAV, mālama mākou i ʻelua mau kī haole integer no ka waiwai waiwai, e loaʻa ana i 8 bytes o ka ʻikepili hou. Eia kekahi, ma EAV, mālama ʻia nā waiwai waiwai āpau ma ke ʻano he kikokikona, ʻoiai ʻo JSONB e hoʻohana i nā helu helu a me nā loina i loko inā hiki, e hopena i kahi wāwae liʻiliʻi.

Nā hopena

Ma ke ʻano holoʻokoʻa, manaʻo wau ʻo ka mālama ʻana i nā waiwai waiwai ma ka format JSONB hiki ke maʻalahi i ka hoʻolālā a me ka mālama ʻana i kāu waihona. Inā hoʻokō ʻoe i nā nīnau he nui, ʻoi aku ka maikaʻi o ka mālama ʻana i nā mea āpau ma ka papa like me ka hui. ʻO ka ʻoiaʻiʻo o ka hoʻomaʻamaʻa ʻana i nā pilina ʻikepili he mea hou aku, akā ʻoi aku ka liʻiliʻi o ka waihona ʻikepili i ʻike ʻia.

Eia kekahi, ma muli o nā hopena benchmark, hiki iā mākou ke hoʻoholo he liʻiliʻi loa ka hoʻopaʻi hana. I kekahi mau hihia, ʻoi aku ka wikiwiki o JSONB ma mua o EAV, e ʻoi aku ka maikaʻi. Eia nō naʻe, ʻaʻole i uhi ʻia kēia pae ʻāina i nā ʻano āpau (e laʻa, nā hui me ka nui o nā waiwai, ka piʻi nui ʻana o ka nui o nā waiwai i ka ʻikepili i loaʻa, a me nā mea ʻē aʻe), no laila inā loaʻa iā ʻoe nā manaʻo no ka hoʻomaikaʻi ʻana, e ʻoluʻolu e waiho iā lākou i nā manaʻo!

Source: www.habr.com

E kūʻai i ka hoʻokipa hilinaʻi no nā pūnaewele me ka pale DDoS, nā kikowaena VPS VDS 🔥 E kūʻai i ka hoʻokipa pūnaewele hilinaʻi me ka pale DDoS, nā kikowaena VPS VDS | ProHoster