{"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\/et\/blog\/administrirovanie\/zamena-eav-na-jsonb-v-postgresql","title":{"rendered":"EAV asendamine JSONB-ga PostgreSQL-is","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<blockquote><p>TL; DR: JSONB v\u00f5ib oluliselt lihtsustada andmebaasi skeemi arendamist, ilma et see kahjustaks p\u00e4ringute j\u00f5udlust.<\/p><\/blockquote>\n<p><\/p>\n<h3>Sissejuhatus<\/h3>\n<p>\nToome klassikalise n\u00e4ite, mis on t\u00f5en\u00e4oliselt \u00fcks vanimaid rakendusi relatsiooniliste andmebaaside (andmebaas) maailmas: meil on \u00fcksus ja on vaja salvestada selle \u00fcksuse teatud omadused (atribuutid). Kuid mitte k\u00f5ik eksemplarid ei pruugi omada sama omaduste komplekti, lisaks v\u00f5ib tulevikus olla vajalik uusi omadusi lisada.<\/p>\n<p>Lihtsaim viis selle probleemi lahendamiseks on luua andmebaasitabelis iga omaduse v\u00e4\u00e4rtuse jaoks veerg ja lihtsalt t\u00e4ita need, mis on vajalikud konkreetse \u00fcksuse eksemplari jaoks. Suurep\u00e4rane! Probleem on lahendatud\u2026 kuni teie tabelis on miljoneid kirjeid ja teil on vaja lisada uus kirje.<\/p>\n<p>Kaalume EAV mustrit (<noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Entity%E2%80%93attribute%E2%80%93value_model\">Entity-Attribute-Value<\/a><\/noindex>), mida kasutatakse \u00fcsna sageli. \u00dcks tabel sisaldab \u00fcksusi (kirjeid), teine tabel sisaldab omaduste (atribuutide) nimesid ja kolmas tabel seob \u00fcksused nende atribuutidega ning sisaldab nende atribuutide v\u00e4\u00e4rtust kohaliku \u00fcksuse jaoks. See v\u00f5imaldab teil omada erinevaid omaduste komplekte erinevate objektide jaoks ja lisada omadusi \u201ereisi jooksul\u201c, muutes andmebaasi struktuuri.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nKuid ma ei kirjutaks seda m\u00e4rkust, kui EVA l\u00e4henemisega seonduvad puudused ei oleks olemas. N\u00e4iteks, et saada \u00fchte v\u00f5i mitut entsust, millel on 1 atribuut, on p\u00e4ringus vajalik 2 liitumist: esimene \u2013 liitumine atribuutide tabeliga, teine \u2013 liitumine v\u00e4\u00e4rtuste tabeliga. Kui entsusel on 2 atribuuti, siis on juba vajalik 4 liitumist! Lisaks, k\u00f5ik atribuudid on tavaliselt salvestatud stringidena, mis toob kaasa t\u00fc\u00fcpide teisendamise nii tulemuseks kui ka WHERE tingimuseks. Kui te kirjutate palju p\u00e4ringuid, siis on see ressursikasutuse seisukohalt \u00fcsna raiskav.<\/p>\n<p>Sellest hoolimata on EAV-i juba ammu kasutatud selliste probleemide lahendamiseks. Need olid v\u00e4ltimatud puudused ja paremat alternatiivi polnud lihtsalt olemas. <br \/>\nAga siis ilmus PostgreSQL-i uus \u201etehnoloogia\u201c\u2026<\/p>\n<p>Alates PostgreSQL 9.4-st on lisatud JSONB andmet\u00fc\u00fcp JSON-i binaarsete andmete salvestamiseks. Kuigi JSON-i salvestamine selles formaadis v\u00f5tab tavaliselt veidi rohkem ruumi ja aega kui lihtne tekstiline JSON, toimub selle t\u00f6\u00f6tlemine palju kiiremini. Samuti toetab JSONB indekseerimist, mis muudab selle p\u00e4ringud veelgi kiiremaks.<\/p>\n<p>JSONB andmet\u00fc\u00fcp v\u00f5imaldab meil asendada mahuka EAV mustri, lisades vaid \u00fche JSONB veeru meie entiteetide tabelisse, mis lihtsustab oluliselt andmebaasi kujundamist. Kuid paljud v\u00e4idavad, et see peaks tingima j\u00f5udluse languse\u2026 Just sellep\u00e4rast ma selle artikli kirjutasin.<\/p>\n<h3>Testandmebaasi seadistamine<\/h3>\n<p>\nSelle v\u00f5rdluse jaoks l\u00f5in andmebaasi uue PostgreSQL 9.5 paigalduse peal 80-dollarilisel s\u00fcsteemil <noindex><a rel=\"nofollow\" href=\"https:\/\/www.digitalocean.com\/\">DigitalOcean<\/a><\/noindex> Ubuntu 14.04. P\u00e4rast postgresql.conf-i m\u00f5ningate seadete seadistamist k\u00e4ivitasin <noindex><a rel=\"nofollow\" href=\"https:\/\/gist.github.com\/coussej\/80c385332ce37df6687f\">see<\/a><\/noindex> skripti psql abil. EAV kujul andmete esitamiseks loodi j\u00e4rgmised tabelid:<\/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>\nAllpool on tabel, kus salvestatakse samad andmed, kuid atribuutide veerg on JSONB t\u00fc\u00fcpi \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>\nN\u00e4eb kordades lihtsam v\u00e4lja, eks? Seej\u00e4rel lisati entiteetide tabelitesse (<i>entity<\/i> &amp; <i>entity_jsonb<\/i>) 10 miljonit kirjet ning vastavalt t\u00e4ideti samade andmetega tabelid, kus kasutatakse EAV mustrit ja JSONB veeru l\u00e4henemist \u2013 <i>entity_jsonb.properties<\/i>. Nii saime erinevaid andmet\u00fc\u00fcpe kogu atribuudi hulgast. Andmete n\u00e4ide:<\/p>\n<pre><code class=\"json\">{\n  id:          1\n  name:        \"Entity1\"\n  description: \"Test entity no. 1\"\n  properties:  {\n    color:        \"red\"\n    length:      120\n    width:       3.1882420\n    hasSomething: true\n    country:      \"Belgium\"\n  } \n}<\/code><\/pre>\n<p>\nN\u00fc\u00fcd on meil samad andmed kahe variandi jaoks. Alustame nende rakenduste v\u00f5rdlemist!<\/p>\n<h3>Kujunduse lihtsustamine<\/h3>\n<p>\nOlen juba varem maininud, et andmebaasi disain on oluliselt lihtsustunud: \u00fcks tabel, t\u00e4nu JSONB veeru kasutamisele omaduste jaoks, selle asemel et kasutada kolme tabelit EAV jaoks. Kuidas see aga p\u00e4ringutes kajastub? Entiteedi \u00fche omaduse v\u00e4rskendamine n\u00e4eb v\u00e4lja j\u00e4rgmine:<\/p>\n<pre><code class=\"pgsql\">-- EAV\nUPDATE entity_attribute_value \nSET value = 'blue' \nWHERE entity_attribute_id = 1 \n  AND entity_id = 120;\n\n-- JSONB\nUPDATE entity_jsonb \nSET properties = jsonb_set(properties, '{\"color\"}', '\"blue\"') \nWHERE id = 120;\n<\/code><\/pre>\n<p>\nNagu me n\u00e4eme, ei tundu viimane p\u00e4ring lihtsam. Et v\u00e4rskendada omaduse v\u00e4\u00e4rtust JSONB objektis, peame kasutama funktsiooni <noindex><a rel=\"nofollow\" href=\"http:\/\/www.postgresql.org\/docs\/9.5\/static\/functions-json.html\">jsonb_set()<\/a><\/noindex>, ja peame edastama meie uue v\u00e4\u00e4rtuse JSONB objektina. Siiski ei pea me eelnevalt mingit identifikaatorit teadma. EAV n\u00e4ite p\u00f5hjal peame teadma nii entity_id kui entity_attribute_id, et teostada v\u00e4rskendust. Kui soovite v\u00e4rskendada omadust JSONB veerus objekti nime p\u00f5hjal, \u2013 siis toimub see k\u00f5ik \u00fche lihtsa lausega.<\/p>\n<p>N\u00fc\u00fcd valime selle entiteedi, mida just v\u00e4rskendasime, tema uue v\u00e4rvi tingimuse alusel:<\/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 = 'blue';\n\n-- JSONB\nSELECT name \nFROM entity_jsonb \nWHERE properties -&gt;&gt; 'color' = 'blue';\n<\/code><\/pre>\n<p>\nMina arvan, et me saame n\u00f5ustuda, et teine on l\u00fchem (ilma joinita!), ja seega lugeda kergemini. Siin on JSONB v\u00f5it! Kasutame JSON operaatorit -&gt;&gt;, et saada v\u00e4rv tekstiv\u00e4\u00e4rtusena JSONB objektist. Samuti on olemas teine v\u00f5imalus sama tulemuse saavutamiseks JSONB mudelis, kasutades operaatorit @&gt;:<\/p>\n<pre><code class=\"pgsql\">-- JSONB \nSELECT name \nFROM entity_jsonb \nWHERE properties @&gt; '{\"color\": \"blue\"}';\n<\/code><\/pre>\n<p>\nSee on veidi keerulisem: me kontrollime, kas JSON objekt veerus properties sisaldab objekti, mis on paremal pool operaatorit @&gt;. V\u00e4hem loetav, kuid tootlikum (vt hiljem). <\/p>\n<p>Lihtsustame JSONB kasutamist veelgi, kui peate valima korraga mitu omadust. Just siin sobib JSONB l\u00e4henemine t\u00f5eliselt h\u00e4sti: me valime lihtsalt omadused lisakolumnitena meie tulemuste kogumis ilma vajaduseta \u00fchinemiste j\u00e4rele:<\/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>\nEAV korral vajate igaks omaduseks, mida soovite k\u00fcsida, 2 \u00fchinemist. Minu arvates n\u00e4itavad eeltoodud p\u00e4ringud suurt lihtsustamist andmebaasi disainis. Vaadake rohkem n\u00e4iteid JSONB p\u00e4ringute kirjutamisest ka <noindex><a rel=\"nofollow\" href=\"http:\/\/schinckel.net\/2014\/05\/25\/querying-json-in-postgres\/\">selles<\/a><\/noindex> postitusest.<br \/>\nN\u00fc\u00fcd on aeg r\u00e4\u00e4kida tootlikkusest.<\/p>\n<h3>T\u00f5husus<\/h3>\n<p>\nTootlikkuse v\u00f5rdlemiseks kasutasin <noindex><a rel=\"nofollow\" href=\"http:\/\/www.postgresql.org\/docs\/9.1\/static\/sql-explain.html\">EXPLAIN ANALYZE<\/a><\/noindex> p\u00e4ringutes, et kokku lugeda t\u00e4itmise aega. Iga p\u00e4ring viidi l\u00e4bi v\u00e4hemalt kolm korda, kuna esmakordne p\u00e4ring n\u00f5udis p\u00e4ringute planeerijalt rohkem aega. Alguses tegin p\u00e4ringud ilma mingite indeksiteta. Selgelt oli see JSONB eelise aspekt, kuna EAV jaoks vajalikud \u00fchendused ei saanud kasutada indekseid (v\u00e4list\u00e4htede v\u00e4lja ei indeksitud). Seej\u00e4rel l\u00f5in indeksi kahe EAV v\u00e4\u00e4rtuste tabeli v\u00e4list\u00e4htede veeru jaoks ja ka indeksi <noindex><a rel=\"nofollow\" href=\"http:\/\/www.postgresql.org\/docs\/9.1\/static\/textsearch-indexes.html\">GIN<\/a><\/noindex> JSONB veeru jaoks.<\/p>\n<p>Andmete v\u00e4rskendamine n\u00e4itas j\u00e4rgmisi tulemusi aja osas (ms). Pange t\u00e4hele, et skaala on logaritmiline:<\/p>\n<p><img decoding=\"async\" alt=\"EAV asendamine JSONB-ga PostgreSQL-is\" src=\"\/wp-content\/uploads\/2019\/11\/8a12ccd7a46d04868b1cc5fcaf01a581.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nN\u00e4eme, et JSONB on palju (&gt; 50000-kordselt) kiirem kui EAV, kui indekseid ei kasutata, p\u00f5hjuse t\u00f5ttu, nagu eespool mainitud. Kui indekseme veergu peav\u00f5tmete j\u00e4rgi, siis vahe peaaegu kaob, kuid JSONB on siiski 1,3 korda kiirem kui EAV. T\u00e4helepanu, et siin ei m\u00f5juta JSONB veeru indeks midagi, kuna me ei kasuta omaduste veergu hindamiskriteeriumides. <\/p>\n<p>Omaduse v\u00e4\u00e4rtuse p\u00f5hjal andmete valimiseks saame j\u00e4rgmised tulemused (tavaline skaala):<\/p>\n<p><img decoding=\"async\" alt=\"EAV asendamine JSONB-ga PostgreSQL-is\" src=\"\/wp-content\/uploads\/2019\/11\/e9a1fd797ef60132e661da686f6214a3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nV\u00f5ime m\u00e4rgata, et JSONB t\u00f6\u00f6tab j\u00e4lle kiiremini kui EAV ilma indeksiteta, kuid kui EAV-l on indeksid \u2013 t\u00f6\u00f6tab see siiski kiiremini kui JSONB. Kuid p\u00e4rast n\u00e4gin, et JSONB p\u00e4ringute aeg oli sama, see juhtis mind j\u00e4reldusele, et GIN-indeks ei t\u00f6\u00f6ta. Tundub, et kui kasutate GIN-indeksit omadustest t\u00e4idetud veeru jaoks, kehtib see ainult @&gt; operaatoreid kasutades. Kasutasin seda uues testis, mis m\u00f5jutas aega tohutult: ainult 0,153 ms! See on 15000 korda kiiremini kui EAV ja 25000 korda kiiremini kui -&gt;&gt; operaator. <\/p>\n<p>Arvan, et see oli piisavalt kiire!<\/p>\n<h3>Andmebaasi tabelite suurused<\/h3>\n<p>\nV\u00f5rdleme tabelite suurusi m\u00f5lema l\u00e4henemise korral. psql-is saame k\u00f5ikide tabelite ja indeksite suurused \u00e4ra n\u00e4idata k\u00e4suga <b>dti+<\/b><\/p>\n<p><img decoding=\"async\" alt=\"EAV asendamine JSONB-ga PostgreSQL-is\" src=\"\/wp-content\/uploads\/2019\/11\/c6c1fe7901fe9ae2bd446cf4ae99b923.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEAV l\u00e4henemise korral on tabelite suurused umbes 3068 MB ja indeksite suurused kuni 3427 MB, kokku 6,43 GB. JSONB l\u00e4henemise korral kasutatakse 1817 MB tabeli jaoks ja 318 MB indeksite jaoks, kokku 2,08 GB. See on kolm korda v\u00e4hem! See fakt \u00fcllatas mind veidi, kuna salvestame omaduste nimed igas JSONB objektis. <\/p>\n<p>Kuid numbrid r\u00e4\u00e4givad enda eest: EAV-s salvestame 2 t\u00e4isarvulist v\u00e4list v\u00f5tit atribuutv\u00e4\u00e4rtusele, mille tulemusena saame 8 baiti t\u00e4iendavaid andmeid. Lisaks salvestatakse EAV-s k\u00f5ik omaduste v\u00e4\u00e4rtused tekstina, samas kui JSONB kasutab numbrilisi ja loogilisi v\u00e4\u00e4rtusi seal, kus see on v\u00f5imalik, mis toob kaasa v\u00e4iksema mahu.<\/p>\n<h3>Summary<\/h3>\n<p>\n\u00dcldiselt arvan, et isendite omaduste salvestamine JSONB formaadis v\u00f5ib oluliselt lihtsustada teie andmebaasi kavandamist ja hooldamist. Kui teete palju p\u00e4ringuid, siis k\u00f5ik, mis on salvestatud \u00fchte tabelisse isendiga, t\u00f6\u00f6tab t\u00f5eliselt t\u00f5husamalt. Ja t\u00f5siasi, et see lihtsustab andmete vahelist suhtlemist, on juba pluss, kuid ka tulemuseks olev andmebaas on kolm korda v\u00e4iksema mahuga.<\/p>\n<p>Samuti, tehtud testide p\u00f5hjal, v\u00f5ib kokkuv\u00f5tteks \u00f6elda, et j\u00f5udluskaod on v\u00e4ga v\u00e4ikesed. M\u00f5nes olukorras t\u00f6\u00f6tab JSONB isegi kiiremini kui EAV, mis teeb selle veelgi paremaks. Siiski ei kata see standardtest kindlasti k\u00f5iki aspekte (n\u00e4iteks isendid, millel on v\u00e4ga palju omadusi, olulised suurendused olemasolevate andmete omaduste arvus,...), seega, kui teil on ettepanekuid nende parandamiseks, siis \u00e4rge kartke j\u00e4tta kommentaare!<br \/>\n<br \/>Allikas: <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.1.1 - 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\/et\/blog\/administrirovanie\/zamena-eav-na-jsonb-v-postgresql\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"et_EE\" \/>\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\/et\/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 asendamine JSONB-ga PostgreSQL-is | ProHoster","description":"TL; DR: JSONB v\u00f5ib oluliselt lihtsustada andmebaasi skeemi arendamist ilma p\u00e4ringute j\u00f5udlusele kahjustamata. Sissejuhatus. Toome esile klassikalise n\u00e4ite, t\u00f5en\u00e4oliselt \u00fcks vanimaid.","canonical_url":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/zamena-eav-na-jsonb-v-postgresql","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"et_EE","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\/et\/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\/et\/wp-json\/wp\/v2\/posts\/52584","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/comments?post=52584"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts\/52584\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/media?parent=52584"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/categories?post=52584"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/tags?post=52584"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}