{"id":52584,"date":"2019-11-12T00:00:00","date_gmt":"2019-11-11T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/zamena-eav-na-jsonb-v-postgresql"},"modified":"2020-02-18T14:00:21","modified_gmt":"2020-02-18T11:00:21","slug":"zamena-eav-na-jsonb-v-postgresql","status":"publish","type":"post","link":"https:\/\/prohoster.info\/lv\/blog\/administrirovanie\/zamena-eav-na-jsonb-v-postgresql","title":{"rendered":"EAV nomai\u0146a uz JSONB PostgreSQL","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<blockquote><p>TL; DR: JSONB var iev\u0113rojami atvieglot datu b\u0101zes sh\u0113mas izstr\u0101di, neupur\u0113jot vaic\u0101jumu veiktsp\u0113ju.<\/p><\/blockquote>\n<p><\/p>\n<h3>Ievads<\/h3>\n<p>\nApskat\u012bsim klasisku piem\u0113ru, iesp\u0113jams, vienu no sen\u0101kajiem veidiem, k\u0101 izmantot rel\u0101ciju datu b\u0101zes (Datu b\u0101ze): mums ir entit\u0101te, un ir nepiecie\u0161ams saglab\u0101t noteiktus \u0161\u012bs entit\u0101tes \u012bpa\u0161umus (atrib\u016btus). Tom\u0113r ne visas instances var b\u016bt ar vien\u0101du \u012bpa\u0161umu kopu, turkl\u0101t n\u0101kotn\u0113 ir iesp\u0113jams pievienot v\u0113l \u012bpa\u0161umus.<\/p>\n<p>Vienk\u0101r\u0161\u0101kais risin\u0101jums \u0161ai probl\u0113mai ir izveidot kolonu datu b\u0101zes tabul\u0101 katram \u012bpa\u0161uma v\u0113rt\u012bbai un aizpild\u012bt tikai t\u0101s, kas nepiecie\u0161amas konkr\u0113tai entit\u0101tes instancei. Lieliski! Probl\u0113ma atrisin\u0101ta\u2026 l\u012bdz br\u012bdim, kad j\u016bsu tabul\u0101 ir miljoni ierakstu un jums ir nepiecie\u0161ams pievienot jaunu ierakstu.<\/p>\n<p>Apskat\u012bsim EAV paraugu (<noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Entity%E2%80%93attribute%E2%80%93value_model\">Entity-Attribute-Value<\/a><\/noindex>), tas tiek izmantots diezgan bie\u017ei. Viena tabula satur entit\u0101tes (ierakstus), otra tabula satur \u012bpa\u0161umu (atrib\u016btu) nosaukumus, savuk\u0101rt tre\u0161\u0101 tabula sasaista entit\u0101tes ar to atrib\u016btiem un satur \u0161o atrib\u016btu v\u0113rt\u012bbas pa\u0161reiz\u0113jai entit\u0101tei. Tas dod iesp\u0113ju uztur\u0113t da\u017e\u0101dus \u012bpa\u0161umu komplektus da\u017e\u0101d\u0101m objektiem, k\u0101 ar\u012b pievienot \u012bpa\u0161umus \u201cuz vietas\u201d, nenomainot datu b\u0101zes strukt\u016bru.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nTom\u0113r es neizsniegtu \u0161o piez\u012bmi, ja EVA pieejai neb\u016btu tr\u016bkumu. Piem\u0113ram, lai ieg\u016btu vienu vai vair\u0101kas entit\u0101tes ar 1 atrib\u016btu, piepras\u012bjum\u0101 ir nepiecie\u0161ami 2 apvienojumi: pirmais - apvienojums ar atrib\u016btu tabulu, otrais - apvienojums ar v\u0113rt\u012bbu tabulu. Ja entit\u0101tei ir 2 atrib\u016bti, tad jau nepiecie\u0161ami 4 apvienojumi! Turkl\u0101t visi atrib\u016bti parasti tiek uzglab\u0101ti k\u0101 virknes, kas noved pie tipu konversijas, gan rezult\u0101tam, gan WHERE nosac\u012bjumam. Ja j\u016bs rakst\u0101t daudz piepras\u012bjumu, tas ir diezgan iz\u0161\u0137\u0113rd\u012bgi resursu izmanto\u0161anas zi\u0146\u0101.<\/p>\n<p>Neskatoties uz \u0161iem ac\u012bmredzamajiem tr\u016bkumiem, EAV jau sen tiek izmantots \u0161\u0101du probl\u0113mu risin\u0101\u0161anai. Tie bija neizb\u0113gami tr\u016bkumi, un lab\u0101kas alternat\u012bvas vienk\u0101r\u0161i nebija. <br \/>\nBet tad PostgreSQL par\u0101d\u012bj\u0101s jauna \u201ctehnolo\u0123ija\u201d...<\/p>\n<p>S\u0101kot no PostgreSQL 9.4, tika pievienots JSONB datu tips, lai uzglab\u0101tu JSON bin\u0101ros datus. Lai gan uzglab\u0101\u0161ana \u0161aj\u0101 form\u0101t\u0101 parasti aiz\u0146em nedaudz vair\u0101k vietas un laika nek\u0101 vienk\u0101r\u0161s teksta JSON, oper\u0101ciju izpilde ir daudz \u0101tr\u0101ka. JSONB ar\u012b atbalsta indekso\u0161anu, kas padara piepras\u012bjumus v\u0113l \u0101tr\u0101kus.<\/p>\n<p>JSONB datu tips \u013cauj mums nomain\u012bt apgr\u016btin\u0101to EAV modeli, tikai pievienojot vienu JSONB kolonnu m\u016bsu entit\u0101\u0161u tabulai, kas iev\u0113rojami vienk\u0101r\u0161o datu b\u0101zes projekt\u0113\u0161anu. Tom\u0113r daudzi apgalvo, ka tam j\u0101ietver veiktsp\u0113jas samazin\u0101jums\u2026 L\u016bk, k\u0101p\u0113c es uzrakst\u012bju \u0161o rakstu.<\/p>\n<h3>Testa datu b\u0101zes iestat\u012b\u0161ana<\/h3>\n<p>\n\u0160im sal\u012bdzin\u0101jumam es izveidoju datu b\u0101zi jaun\u0101 PostgreSQL 9.5 instal\u0101cij\u0101 par 80 dol\u0101riem. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.digitalocean.com\/\">DigitalOcean<\/a><\/noindex> Ubuntu 14.04. P\u0113c da\u017e\u0101du parametru iestat\u012b\u0161anas postgresql.conf es palaidu <noindex><a rel=\"nofollow\" href=\"https:\/\/gist.github.com\/coussej\/80c385332ce37df6687f\">\u0161is<\/a><\/noindex> skriptu, izmantojot psql. Lai att\u0113lotu datus EAV form\u0101t\u0101, tika izveidotas \u0161\u0101das tabulas:<\/p>\n<pre><code class=\"pgsql\">CREATE TABLE entity ( \n  id           SERIAL PRIMARY KEY, \n  name         TEXT, \n  description  TEXT\n);\nCREATE TABLE entity_attribute (\n  id          SERIAL PRIMARY KEY, \n  name        TEXT\n);\nCREATE TABLE entity_attribute_value (\n  id                  SERIAL PRIMARY KEY, \n  entity_id           INT    REFERENCES entity(id), \n  entity_attribute_id INT    REFERENCES entity_attribute(id), \n  value               TEXT\n);\n<\/code><\/pre>\n<p>\nZem\u0101k ir tabula, kur\u0101 tiks glab\u0101ti tie pa\u0161i dati, bet ar atrib\u016btiem JSONB tipa kolonn\u0101 \u2013 <i>properties<\/i>.<\/p>\n<pre><code class=\"pgsql\">CREATE TABLE entity_jsonb (\n  id          SERIAL PRIMARY KEY, \n  name        TEXT, \n  description TEXT,\n  properties  JSONB\n);\n<\/code><\/pre>\n<p>\nIzskat\u0101s daudz vienk\u0101r\u0161\u0101k, vai ne? P\u0113c tam tika pievienoti 10 miljoni ierakstu tabul\u0101m (<i>entity<\/i> &amp; <i>entity_jsonb<\/i>) un attiec\u012bgi tika aizpild\u012bti ar vien\u0101diem datiem tabul\u0101s, kur\u0101s tiek izmantots EAV modelis un pieeja ar JSONB kolonnu \u2013 <i>entity_jsonb.properties<\/i>. T\u0101d\u0113j\u0101di m\u0113s ieguv\u0101m vair\u0101kus da\u017e\u0101dus datu tipus starp visiem \u012bpa\u0161\u012bbu kopumiem. Datu piem\u0113rs:<\/p>\n<pre><code class=\"json\">{\n  id:          1\n  name:        \"Entity1\"\n  description: \"Test entity no. 1\"\n  properties:  {\n    color:        \"sarkans\"\n    length:       120\n    width:        3.1882420\n    hassomething: true\n    country:      \"Be\u013c\u0123ija\"\n  } \n}<\/code><\/pre>\n<p>\nT\u0101tad, tagad mums ir vien\u0101di dati div\u0101m versij\u0101m. S\u0101ksim sal\u012bdzin\u0101t ievie\u0161anu darb\u012bb\u0101!<\/p>\n<h3>Dizaina vienk\u0101r\u0161o\u0161ana<\/h3>\n<p>\nIepriek\u0161 tika min\u0113ts, ka datu b\u0101zes dizains ir iev\u0113rojami vienk\u0101r\u0161ots: viena tabula, izmantojot JSONB kolonnu \u012bpa\u0161\u012bb\u0101m, viet\u0101 tr\u012bs tabulu izmanto\u0161anai EAV. Bet k\u0101 tas atspogu\u013cojas vaic\u0101jumos? Viens \u012bpa\u0161\u012bbas atjaunin\u0101jums entit\u0101tei izskat\u0101s \u0161\u0101di:<\/p>\n<pre><code class=\"pgsql\">-- EAV\nUPDATE entity_attribute_value \nSET value = 'zils' \nWHERE entity_attribute_id = 1 \n  AND entity_id = 120;\n\n-- JSONB\nUPDATE entity_jsonb \nSET properties = jsonb_set(properties, '{\"color\"}', '\"zils\"') \nWHERE id = 120;\n<\/code><\/pre>\n<p>\nK\u0101 redzam, p\u0113d\u0113jais vaic\u0101jums neizskat\u0101s vienk\u0101r\u0161\u0101ks. Lai atjaunin\u0101tu \u012bpa\u0161uma v\u0113rt\u012bbu JSONB objekt\u0101, mums j\u0101dara izmantot funkciju <noindex><a rel=\"nofollow\" href=\"http:\/\/www.postgresql.org\/docs\/9.5\/static\/functions-json.html\">jsonb_set()<\/a><\/noindex>, un mums j\u0101nodod m\u016bsu jaun\u0101 v\u0113rt\u012bba k\u0101 JSONB objekts. Tom\u0113r mums iepriek\u0161 nav j\u0101zina nek\u0101di identifikatori. Apl\u016bkojot EAV piem\u0113ru, mums j\u0101zina gan entity_id, gan entity_attribute_id, lai veiktu atjaunin\u0101jumu. Ja v\u0113laties atjaunin\u0101t \u012bpa\u0161\u012bbu JSONB kolonn\u0101, pamatojoties uz objekta nosaukumu, \u2013 to visu var veikt ar vienk\u0101r\u0161u rindi\u0146u.<\/p>\n<p>Tagad izv\u0113l\u0113simies \u0161o ent\u012btiju, kuru m\u0113s tikko atjaunin\u0101j\u0101m, pamatojoties uz t\u0101s jauno kr\u0101su:<\/p>\n<pre><code class=\"pgsql\">-- EAV\nSELECT e.name \nFROM entity e \n  INNER JOIN entity_attribute_value eav ON e.id = eav.entity_id\n  INNER JOIN entity_attribute ea ON eav.entity_attribute_id = ea.id\nWHERE ea.name = 'color' AND eav.value = 'zils';\n\n-- JSONB\nSELECT name \nFROM entity_jsonb \nWHERE properties -&gt;&gt; 'color' = 'zils';\n<\/code><\/pre>\n<p>\nEs dom\u0101ju, ka m\u0113s varam piekrist, ka otrais ir \u012bs\u0101ks (bez apvieno\u0161an\u0101s!), un attiec\u012bgi viegl\u0101k las\u0101ms. \u0160eit uzvara JSONB! M\u0113s izmantojam JSON operatoru -&gt;&gt;, lai ieg\u016btu kr\u0101su k\u0101 tekstu\u0101lo v\u0113rt\u012bbu no JSONB objekta. Past\u0101v ar\u012b otra pieeja, lai sasniegtu to pa\u0161u rezult\u0101tu JSONB model\u012b, izmantojot operatoru @&gt;:<\/p>\n<pre><code class=\"pgsql\">-- JSONB \nSELECT name \nFROM entity_jsonb \nWHERE properties @&gt; '{\"color\": \"zils\"}';\n<\/code><\/pre>\n<p>\nTas ir nedaudz sare\u017e\u0123\u012bt\u0101k: m\u0113s p\u0101rbaud\u0101m, vai JSON objekts kolonn\u0101 satur objektu, kas atrodas labaj\u0101 pus\u0113 no operatora @&gt;. Maz\u0101k las\u0101ms, bet efekt\u012bv\u0101ks (skat. t\u0101l\u0101k). <\/p>\n<p>Vienk\u0101r\u0161osim JSONB izmanto\u0161anu v\u0113l vair\u0101k, kad jums ir nepiecie\u0161ams izv\u0113l\u0113ties vair\u0101kus \u012bpa\u0161umus vienlaikus. \u0160eit tie\u0161\u0101m piem\u0113rots ir JSONB pieejas: m\u0113s vienk\u0101r\u0161i izv\u0113lamies \u012bpa\u0161\u012bbas k\u0101 papildu kolonnas m\u016bsu rezult\u0101tu kop\u0101 bez nepiecie\u0161am\u012bbas p\u0113c apvieno\u0161an\u0101s:<\/p>\n<pre><code class=\"pgsql\">-- JSONB \nSELECT name\n  , properties -&gt;&gt; 'color'\n  , properties -&gt;&gt; 'country'\nFROM entity_jsonb \nWHERE id = 120;\n<\/code><\/pre>\n<p>\nAr EAV jums b\u016bs nepiecie\u0161amas 2 apvieno\u0161an\u0101s katram \u012bpa\u0161umam, ko v\u0113laties piepras\u012bt. Manupr\u0101t, iepriek\u0161 min\u0113tie vaic\u0101jumi par\u0101da lielu simplifik\u0101ciju datub\u0101zes dizain\u0101. Skatiet vair\u0101k piem\u0113ru tam, k\u0101 rakst\u012bt vaic\u0101jumus uz JSONB, iesp\u0113jams, ar\u012b <noindex><a rel=\"nofollow\" href=\"http:\/\/schinckel.net\/2014\/05\/25\/querying-json-in-postgres\/\">this<\/a><\/noindex> rakst\u0101.<br \/>\nTagad ir pien\u0101cis laiks run\u0101t par veiktsp\u0113ju.<\/p>\n<h3>Veiktsp\u0113ja<\/h3>\n<p>\nLai sal\u012bdzin\u0101tu veiktsp\u0113ju, es izmantoju <noindex><a rel=\"nofollow\" href=\"http:\/\/www.postgresql.org\/docs\/9.1\/static\/sql-explain.html\">EXPLAIN ANALYZE<\/a><\/noindex> va piepras\u012bjumos, lai apr\u0113\u0137in\u0101tu izpildes laiku. Katrs piepras\u012bjums tika izpild\u012bts vismaz tr\u012bs reizes, jo pirmaj\u0101 reiz\u0113 piepras\u012bjumu pl\u0101not\u0101jam nepiecie\u0161ams vair\u0101k laika. S\u0101kum\u0101 es veicu piepras\u012bjumus bez jebk\u0101diem indeksiem. Ac\u012bmredzot, tas deva priek\u0161roc\u012bbu JSONB, jo saist\u012b\u0161an\u0101s, kas nepiecie\u0161amas EAV, nevar\u0113ja izmantot indeksus (\u0101rzemju atsl\u0113gu lauki nebija indeks\u0113ti). P\u0113c tam es izveidoju indeksu diviem \u0101r\u0113jo atsl\u0113gu kolonn\u0101m EAV v\u0113rt\u012bbu tabul\u0101, k\u0101 ar\u012b indeksu <noindex><a rel=\"nofollow\" href=\"http:\/\/www.postgresql.org\/docs\/9.1\/static\/textsearch-indexes.html\">GIN<\/a><\/noindex> JSONB kolonnai.<\/p>\n<p>Datu atjaunin\u0101jumi par\u0101d\u012bja sekojo\u0161us rezult\u0101tus p\u0113c laika (ms). L\u016bdzu, \u0146emiet v\u0113r\u0101, ka m\u0113rogs ir logaritmisks:<\/p>\n<p><img decoding=\"async\" alt=\"EAV nomai\u0146a uz JSONB PostgreSQL\" src=\"\/wp-content\/uploads\/2019\/11\/8a12ccd7a46d04868b1cc5fcaf01a581.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nRedzam, ka JSONB ir daudz (&gt; 50000-x) \u0101tr\u0101ks nek\u0101 EAV, kad indeksi netiek izmantoti, k\u0101 min\u0113ts iepriek\u0161. Kad m\u0113s indeks\u0113jam kolonnas ar prim\u0101raj\u0101m atsl\u0113g\u0101m, at\u0161\u0137ir\u012bba gandr\u012bz izz\u016bd, bet JSONB joproj\u0101m ir 1,3 reizes \u0101tr\u0101ks nek\u0101 EAV. L\u016bdzu, \u0146emiet v\u0113r\u0101, ka indekss JSONB kolonn\u0101 \u0161eit neietekm\u0113 kaut ko, jo m\u0113s neizmantojam \u012bpa\u0161\u012bbu kolonnu v\u0113rt\u0113\u0161anas krit\u0113rijos. <\/p>\n<p>Lai atlas\u012btu datus p\u0113c \u012bpa\u0161\u012bbas v\u0113rt\u012bbas, m\u0113s ieg\u016bstam \u0161\u0101dus rezult\u0101tus (parasts m\u0113rogs):<\/p>\n<p><img decoding=\"async\" alt=\"EAV nomai\u0146a uz JSONB PostgreSQL\" src=\"\/wp-content\/uploads\/2019\/11\/e9a1fd797ef60132e661da686f6214a3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVar paman\u012bt, ka JSONB atkal str\u0101d\u0101 \u0101tr\u0101k nek\u0101 EAV bez indeksiem, bet kad EAV ir ar indeksiem \u2013 tas tom\u0113r darbojas \u0101tr\u0101k nek\u0101 JSONB. Bet tad es paman\u012bju, ka laiks JSONB piepras\u012bjumiem bija vien\u0101ds, kas pamudin\u0101ja mani dom\u0101t, ka GIN indekss nedarbojas. Izskat\u0101s, ka, izmantojot GIN indeksu kolonn\u0101 ar aizpild\u012bt\u0101m \u012bpa\u0161\u012bb\u0101m, tas darbojas tikai, izmantojot iek\u013cau\u0161anas operatoru @&gt;. Es to izmantoju jaun\u0101 test\u0101, kas b\u016btiski ietekm\u0113ja laiku: tikai 0,153 ms! Tas ir 15000 reizes \u0101tr\u0101k nek\u0101 EAV, un 25000 reizes \u0101tr\u0101k nek\u0101 operators -&gt;&gt;. <\/p>\n<p>Dom\u0101ju, ka tas bija pietiekami \u0101tri!<\/p>\n<h3>DB tabulu izm\u0113rs<\/h3>\n<p>\nSal\u012bdzin\u0101sim tabulu izm\u0113rus abos pieejas veidos. psql m\u0113s varam par\u0101d\u012bt visu tabulu un indeksu izm\u0113rus ar komandu <b>dti+<\/b><\/p>\n<p><img decoding=\"async\" alt=\"EAV nomai\u0146a uz JSONB PostgreSQL\" src=\"\/wp-content\/uploads\/2019\/11\/c6c1fe7901fe9ae2bd446cf4ae99b923.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEAV pieejas tabulu izm\u0113ri ir apm\u0113ram 3068 MB, bet indeksi \u2013 l\u012bdz 3427 MB, kas kop\u0101 veido 6,43 GB. Izmantojot pieeju ar JSONB, tiek izmantoti 1817 MB tabulai un 318 MB indeksiem, kop\u0101 2,08 GB. Tas ir 3 reizes maz\u0101k! \u0160is fakts mani nedaudz p\u0101rsteidza, jo m\u0113s glab\u0101jam \u012bpa\u0161\u012bbu nosaukumus katr\u0101 JSONB objekt\u0101. <\/p>\n<p>Tom\u0113r skait\u013ci run\u0101 pa\u0161i par sevi: EAV m\u0113s uzglab\u0101jam 2 veselus \u0101r\u0113jos atsl\u0113gas atrib\u016btu v\u0113rt\u012bbai, k\u0101 rezult\u0101t\u0101 ieg\u016bstam 8 baitus papildu datu. Turkl\u0101t EAV visus atrib\u016btu v\u0113rt\u012bbas uzglab\u0101 tekst\u0101, kam\u0113r JSONB izmantos skaitliskas un lo\u0123iskas v\u0113rt\u012bbas tur, kur tas ir iesp\u0113jams, k\u0101 rezult\u0101t\u0101 ieg\u016bstam maz\u0101ku apjomu.<\/p>\n<h3>Secin\u0101jumi<\/h3>\n<p>\nKopum\u0101 es dom\u0101ju, ka \u012bpa\u0161\u012bbu saglab\u0101\u0161ana JSONB form\u0101t\u0101 var iev\u0113rojami vienk\u0101r\u0161ot j\u016bsu datu b\u0101zes projekt\u0113\u0161anu un apkopi. Ja j\u016bs veicat daudz vaic\u0101jumu, tad viss, kas ir uzglab\u0101ts vien\u0101 tabul\u0101 ar entit\u0101ti, tie\u0161\u0101m darbosies efekt\u012bv\u0101k. Un tas, ka tas vienk\u0101r\u0161o datu mijiedarb\u012bbu, jau ir plus, bet ar\u012b rezult\u0101t\u0101 ieg\u016bt\u0101 datu b\u0101ze ir 3 reizes maz\u0101ka p\u0113c apjoma.<\/p>\n<p>T\u0101pat p\u0113c veiktajiem testiem var izdar\u012bt secin\u0101jumu, ka veiktsp\u0113jas zudumi ir \u013coti nenoz\u012bm\u012bgi. Da\u017eos gad\u012bjumos JSONB darbojas pat \u0101tr\u0101k nek\u0101 EAV, padarot to v\u0113l lab\u0101kus. Tom\u0113r \u0161is standarta tests, protams, neaptver visus aspektus (piem\u0113ram, entit\u0101tes ar \u013coti lielu \u012bpa\u0161\u012bbu skaitu, b\u016btisks eso\u0161o datu \u012bpa\u0161\u012bbu skaita pieaugums...), t\u0101d\u0113\u013c, ja jums ir k\u0101di ieteikumi par to, k\u0101 tos uzlabot, l\u016bdzu, nevilcinieties atst\u0101t koment\u0101rus!<br \/>\n<br \/>Avots: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/475178\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>TL; DR: JSONB \u043c\u043e\u0436\u0435\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0441\u0445\u0435\u043c\u044b \u0411\u0414 \u0431\u0435\u0437 \u0443\u0449\u0435\u0440\u0431\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u0445. \u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u041f\u0440\u0438\u0432\u0435\u0434\u0435\u043c \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u0437 \u0441\u0442\u0430\u0440\u0435\u0439\u0448\u0438\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u043c\u0438\u0440\u0435 \u0440\u0435\u043b\u044f\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0411\u0414 (\u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445): \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c, \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 (\u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b) \u044d\u0442\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438. \u041d\u043e \u043d\u0435 \u0432\u0441\u0435 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b \u043c\u043e\u0433\u0443\u0442 \u0438\u043c\u0435\u044e\u0442 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0441\u0432\u043e\u0439\u0441\u0442\u0432, \u043a \u0442\u043e\u043c\u0443 \u0436\u0435 \u0432 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-52584","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.4 - aioseo.com -->\n\t<meta name=\"description\" content=\"TL; DR: JSONB \u043c\u043e\u0436\u0435\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0441\u0445\u0435\u043c\u044b \u0411\u0414 \u0431\u0435\u0437 \u0443\u0449\u0435\u0440\u0431\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u0445. \u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u041f\u0440\u0438\u0432\u0435\u0434\u0435\u043c \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u0437 \u0441\u0442\u0430\u0440\u0435\u0439\u0448\u0438\u0445.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/lv\/blog\/administrirovanie\/zamena-eav-na-jsonb-v-postgresql\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"lv_LV\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0417\u0430\u043c\u0435\u043d\u0430 EAV \u043d\u0430 JSONB \u0432 PostgreSQL | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"TL; DR: JSONB \u043c\u043e\u0436\u0435\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0441\u0445\u0435\u043c\u044b \u0411\u0414 \u0431\u0435\u0437 \u0443\u0449\u0435\u0440\u0431\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u0445. \u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u041f\u0440\u0438\u0432\u0435\u0434\u0435\u043c \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u0437 \u0441\u0442\u0430\u0440\u0435\u0439\u0448\u0438\u0445.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/lv\/blog\/administrirovanie\/zamena-eav-na-jsonb-v-postgresql\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-11-11T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T11:00:21+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47EAV aizvieto\u0161ana ar JSONB PostgreSQL | ProHoster","description":"TL; DR: JSONB var iev\u0113rojami vienk\u0101r\u0161ot datu b\u0101zes sh\u0113mu izstr\u0101di bez veiktsp\u0113jas zuduma vaic\u0101jumos. Ievads Apskat\u012bsim klasisku piem\u0113ru, iesp\u0113jams, vienu no vec\u0101kajiem.","canonical_url":"https:\/\/prohoster.info\/lv\/blog\/administrirovanie\/zamena-eav-na-jsonb-v-postgresql","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"lv_LV","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0417\u0430\u043c\u0435\u043d\u0430 EAV \u043d\u0430 JSONB \u0432 PostgreSQL | ProHoster","og:description":"TL; DR: JSONB \u043c\u043e\u0436\u0435\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0441\u0445\u0435\u043c\u044b \u0411\u0414 \u0431\u0435\u0437 \u0443\u0449\u0435\u0440\u0431\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u0445. \u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u041f\u0440\u0438\u0432\u0435\u0434\u0435\u043c \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u0437 \u0441\u0442\u0430\u0440\u0435\u0439\u0448\u0438\u0445.","og:url":"https:\/\/prohoster.info\/lv\/blog\/administrirovanie\/zamena-eav-na-jsonb-v-postgresql","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-11-11T21:00:00+00:00","article:modified_time":"2020-02-18T11:00:21+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"52584","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-24 04:07:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 20:40:27","updated":"2026-01-24 04:07:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/posts\/52584","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/comments?post=52584"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/posts\/52584\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/media?parent=52584"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/categories?post=52584"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/tags?post=52584"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}