{"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\/sq\/blog\/administrirovanie\/zamena-eav-na-jsonb-v-postgresql","title":{"rendered":"Z\u00ebvend\u00ebsimi i EAV me JSONB n\u00eb PostgreSQL","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<blockquote><p>TL; DR: JSONB mund t\u00eb thjeshtoj\u00eb ndjesh\u00ebm zhvillimin e skem\u00ebs s\u00eb DB pa b\u00ebr\u00eb kompromis n\u00eb performanc\u00ebn e k\u00ebrkesave.<\/p><\/blockquote>\n<p><\/p>\n<h3>Hyrje<\/h3>\n<p>\nLe t\u00eb marrim nj\u00eb shembull klasik, ndoshta nj\u00ebrin prej varianteve m\u00eb t\u00eb vjetra t\u00eb p\u00ebrdorimit n\u00eb bot\u00eb t\u00eb DB-ve relacional (t\u00eb dh\u00ebnash): kemi nj\u00eb entitet dhe duhet t\u00eb ruajm\u00eb disa pron\u00ebsi (atribute) t\u00eb k\u00ebtij entiteti. Por jo t\u00eb gjitha instancat mund t\u00eb ken\u00eb t\u00eb nj\u00ebjtin grup pronash, dhe gjithashtu, n\u00eb t\u00eb ardhmen, \u00ebsht\u00eb e mundur t\u00eb shtohen edhe pron\u00ebsi t\u00eb tjera.<\/p>\n<p>M\u00ebnyra m\u00eb e thjesht\u00eb p\u00ebr t\u00eb zgjidhur k\u00ebt\u00eb problem \u00ebsht\u00eb krijimi i nj\u00eb kolone n\u00eb tabel\u00ebn e DB p\u00ebr \u00e7do vler\u00eb pron\u00ebsie, dhe thjesht mbushja e atyre q\u00eb jan\u00eb t\u00eb nevojshme p\u00ebr nj\u00eb instanc\u00eb t\u00eb caktuar t\u00eb entitetit. Shum\u00eb mir\u00eb! Problemi \u00ebsht\u00eb zgjidhur... deri n\u00eb momentin kur tabela juaj ka miliona regjistrime dhe ju duheni t\u00eb shtoni nj\u00eb regjistrim t\u00eb ri.<\/p>\n<p>Le t\u00eb shqyrtojm\u00eb modelin EAV (<noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Entity%E2%80%93attribute%E2%80%93value_model\">Entity-Attribute-Value<\/a><\/noindex>), i cili ndodhet mjaft shpesh. Nj\u00eb tabel\u00eb p\u00ebrmban entitetet (regjistrimet), nj\u00eb tabel\u00eb tjet\u00ebr p\u00ebrmban emrat e pronarive (atributeve), dhe nj\u00eb tabel\u00eb e tret\u00eb lidhet entitetet me atributet e tyre dhe p\u00ebrmban vler\u00ebn e k\u00ebtyre atribut\u00ebve p\u00ebr entitetin aktual. Kjo ju jep mund\u00ebsin\u00eb t\u00eb keni grupe t\u00eb ndryshme pronash p\u00ebr objekte t\u00eb ndryshme, si dhe t\u00eb shtoni prona \"n\u00eb flak\u00eb\", pa ndryshuar struktur\u00ebn e DB.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nMegjithat\u00eb, nuk do ta shkruaja k\u00ebt\u00eb sh\u00ebnim n\u00ebse nuk do ishin disavantazhe n\u00eb qasjen me p\u00ebrdorimin e EVA. P\u00ebr shembull, p\u00ebr t\u00eb marr\u00eb nj\u00eb ose m\u00eb shum\u00eb entitete q\u00eb kan\u00eb 1 atribut, k\u00ebrkohen 2 bashkime n\u00eb k\u00ebrkes\u00eb: e para \u2013 nj\u00eb bashkim me tabel\u00ebn e atributeve, e dyta \u2013 nj\u00eb bashkim me tabel\u00ebn e vlerave. N\u00ebse entiteti ka 2 atribute, at\u00ebher\u00eb k\u00ebrkohen 4 bashkime! P\u00ebr m\u00eb tep\u00ebr, t\u00eb gjith\u00eb atributet zakonisht ruhen si vargje, \u00e7ka \u00e7on n\u00eb konvertim t\u00eb tipit, si p\u00ebr rezultatin, ashtu edhe p\u00ebr kushtin WHERE. N\u00ebse shkruani shum\u00eb k\u00ebrkesa, kjo \u00ebsht\u00eb mjaft e shp\u00ebrdorueshme, nga pik\u00ebpamja e p\u00ebrdorimit t\u00eb burimeve.<\/p>\n<p>Pavar\u00ebsisht k\u00ebtyre disavantazheve t\u00eb dukshme, EAV ka qen\u00eb prej koh\u00ebsh i p\u00ebrdorur p\u00ebr t'i zgjidhur k\u00ebt\u00eb lloj problemesh. K\u00ebto ishin disavantazhe t\u00eb pashmangshme, dhe nuk kishte nj\u00eb alternativ\u00eb m\u00eb t\u00eb mir\u00eb. <br \/>\nPor pastaj, nj\u00eb \"teknologji\" e re u shfaq n\u00eb PostgreSQL...<\/p>\n<p>Q\u00eb nga PostgreSQL 9.4, \u00ebsht\u00eb shtuar tipi i t\u00eb dh\u00ebnave JSONB p\u00ebr t\u00eb ruajtur t\u00eb dh\u00ebna JSON n\u00eb format binar. Edhe pse ruajtja e JSON n\u00eb k\u00ebt\u00eb format zakonisht merr pak m\u00eb shum\u00eb hap\u00ebsir\u00eb dhe koh\u00eb se sa JSON-i i thjesht\u00eb tekstual, kryerja e operacioneve me t\u00eb ndodh shum\u00eb m\u00eb shpejt. Po ashtu, JSONB mb\u00ebshtet indeksimin, q\u00eb i b\u00ebn k\u00ebrkesat ndaj tij edhe m\u00eb t\u00eb shpejta.<\/p>\n<p>Tipi i t\u00eb dh\u00ebnave JSONB na lejon t\u00eb z\u00ebvend\u00ebsojm\u00eb modelin e mbi-ngarkuar EAV duke shtuar vet\u00ebm nj\u00eb kolon\u00eb JSONB n\u00eb tabel\u00ebn ton\u00eb t\u00eb entiteteve, gj\u00eb q\u00eb e thjeshton ndjesh\u00ebm projektimin e baz\u00ebs s\u00eb t\u00eb dh\u00ebnave. Por shum\u00eb njer\u00ebz argumentojn\u00eb se kjo duhet t\u00eb shoq\u00ebrohet me nj\u00eb ulje t\u00eb performanc\u00ebs\u2026 Kjo \u00ebsht\u00eb arsyeja pse u shfaq ky artikull.<\/p>\n<h3>Konfigurimi i baz\u00ebs s\u00eb t\u00eb dh\u00ebnave t\u00eb testit<\/h3>\n<p>\nP\u00ebr k\u00ebt\u00eb krahasim krijova nj\u00eb baz\u00eb t\u00eb dh\u00ebnash n\u00eb nj\u00eb instalim t\u00eb ri t\u00eb PostgreSQL 9.5 n\u00eb nj\u00eb paket\u00eb 80-dollar\u00ebsh <noindex><a rel=\"nofollow\" href=\"https:\/\/www.digitalocean.com\/\">DigitalOcean<\/a><\/noindex> Ubuntu 14.04. Pas konfigurimit t\u00eb disa parametrave n\u00eb postgresql.conf, fillova <noindex><a rel=\"nofollow\" href=\"https:\/\/gist.github.com\/coussej\/80c385332ce37df6687f\">k\u00ebt\u00eb<\/a><\/noindex> sk\u0440\u0438\u043ftin duke p\u00ebrdorur psql. P\u00ebr t\u00eb paraqitur t\u00eb dh\u00ebnat n\u00eb formatin EAV u krijuan tabelat e m\u00ebposhtme:<\/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>\nM\u00eb posht\u00eb \u00ebsht\u00eb tabela ku do t\u00eb ruhet t\u00eb nj\u00ebjtat t\u00eb dh\u00ebna, por me atributet n\u00eb kolon\u00ebn e tipit JSONB \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>\nDuket shum\u00eb m\u00eb e thjesht\u00eb, apo jo? Pastaj u shtuan n\u00eb tabelat e entiteteve (<i>entity<\/i> &amp; <i>entity_jsonb<\/i>) 10 milion\u00eb rekorde dhe p\u00ebrkat\u00ebsisht, u mbush\u00ebn me t\u00eb dh\u00ebna t\u00eb nj\u00ebjta tabelat ku p\u00ebrdoret modeli EAV dhe qasja me kolumn\u00ebn JSONB \u2013 <i>entity_jsonb.properties<\/i>. Pra, k\u00ebshtu mor\u00ebm disa lloje t\u00eb ndryshme t\u00eb t\u00eb dh\u00ebnave midis gjith\u00eb setit t\u00eb vetive. Shembuj t\u00eb dh\u00ebnash:<\/p>\n<pre><code class=\"json\">{\n  id:          1\n  name:        \"Entity1\"\n  description: \"Test entity no. 1\"\n  properties:  {\n    color:        \"red\"\n    lenght:       120\n    width:        3.1882420\n    hassomething: true\n    country:      \"Belgium\"\n  } \n}<\/code><\/pre>\n<p>\nK\u00ebshtu, tani kemi t\u00eb dh\u00ebna t\u00eb nj\u00ebjta p\u00ebr dy variante. Le t\u00eb fillojm\u00eb t\u00eb krahasojm\u00eb implementimet n\u00eb pun\u00eb!<\/p>\n<h3>Thjesht\u00ebsimi i dizajnit<\/h3>\n<p>\nM\u00eb par\u00eb u tha se dizajni i DB ishte thjeshtuar ndjesh\u00ebm: nj\u00eb tabel\u00eb, p\u00ebr shkak t\u00eb p\u00ebrdorimit t\u00eb kolon\u00ebs JSONB p\u00ebr vetit\u00eb, n\u00eb vend t\u00eb p\u00ebrdorimit t\u00eb tre tabelave p\u00ebr EAV. Por si ndikon kjo n\u00eb k\u00ebrkesa? P\u00ebrdit\u00ebsimi i nj\u00eb veti t\u00eb entitetit duket si n\u00eb vijim:<\/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>\nSi e shohim, k\u00ebrkesa e fundit nuk duket m\u00eb e thjesht\u00eb. P\u00ebr t\u00eb p\u00ebrdit\u00ebsuar vler\u00ebn e pron\u00ebs n\u00eb objektin JSONB, ne duhet t\u00eb p\u00ebrdorim funksionin <noindex><a rel=\"nofollow\" href=\"http:\/\/www.postgresql.org\/docs\/9.5\/static\/functions-json.html\">jsonb_set()<\/a><\/noindex>, dhe duhet t\u00eb kalojm\u00eb vler\u00ebn ton\u00eb t\u00eb re si nj\u00eb objekt JSONB. Megjithat\u00eb, nuk na nevojitet t\u00eb dim\u00eb ndonj\u00eb identifikues paraprakisht. Duke e par\u00eb shembullin me EAV, na nevojitet t\u00eb dim\u00eb si entity_id ashtu edhe entity_attribute_id p\u00ebr t\u00eb kryer p\u00ebrdit\u00ebsimin. N\u00ebse d\u00ebshironi t\u00eb p\u00ebrdit\u00ebsoni pron\u00ebn n\u00eb kolumn\u00ebn JSONB n\u00eb baz\u00eb t\u00eb emrit t\u00eb objektit, kjo b\u00ebhet me nj\u00eb rresht t\u00eb thjesht\u00eb.<\/p>\n<p>Tani le t\u00eb zgjedhim at\u00eb entitet q\u00eb sapo e p\u00ebrdit\u00ebsuam, sipas kushteve t\u00eb ngjyr\u00ebs s\u00eb tij t\u00eb re:<\/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>\nMendoj se mund t\u00eb pajtohemi se e dyta \u00ebsht\u00eb m\u00eb e shkurt\u00ebr (pa join!), dhe p\u00ebr pasoj\u00eb m\u00eb e lexueshme. K\u00ebtu JSONB fiton! Ne p\u00ebrdorim operatorin JSON -&gt;&gt; p\u00ebr t\u00eb marr\u00eb ngjyr\u00ebn si vler\u00eb tekstuale nga objekti JSONB. Ekziston gjithashtu nj\u00eb m\u00ebnyr\u00eb tjet\u00ebr p\u00ebr t\u00eb arritur t\u00eb nj\u00ebjtin rezultat n\u00eb modelin JSONB duke p\u00ebrdorur operatorin @&gt;:<\/p>\n<pre><code class=\"pgsql\">-- JSONB \nSELECT name \nFROM entity_jsonb \nWHERE properties @&gt; '{\"color\": \"blue\"}';\n<\/code><\/pre>\n<p>\nKjo \u00ebsht\u00eb pak m\u00eb e komplikuar: ne kontrollojm\u00eb n\u00ebse objekti JSON n\u00eb kolumn\u00ebn e pronave p\u00ebrmban objektin q\u00eb ndodhet n\u00eb t\u00eb djatht\u00ebn e operatorit @&gt;. M\u00eb pak e lexueshme, por m\u00eb efikase (shih m\u00eb posht\u00eb). <\/p>\n<p>Le t\u00eb thjeshtojm\u00eb p\u00ebrdorimin e JSONB edhe m\u00eb shum\u00eb, kur ju nevojitet t\u00eb zgjidhni disa prona nj\u00ebkoh\u00ebsisht. K\u00ebtu \u00ebsht\u00eb ku qasja JSONB merr vler\u00ebn m\u00eb t\u00eb madhe: ne thjesht zgjedhim pronat si kolona shtes\u00eb n\u00eb grupin ton\u00eb t\u00eb rezultateve pa nevoj\u00ebn p\u00ebr bashkime:<\/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>\nMe EAV ju do t'ju duhen 2 bashkime p\u00ebr \u00e7do pron\u00eb q\u00eb d\u00ebshironi t\u00eb k\u00ebrkoni. N\u00eb mendimin tim, k\u00ebrkesat e m\u00ebsip\u00ebrme tregojn\u00eb nj\u00eb thjeshtim t\u00eb madh n\u00eb dizajnin e baz\u00ebs s\u00eb t\u00eb dh\u00ebnave. Mund t\u00eb shihni m\u00eb shum\u00eb shembuj se si t\u00eb shkruani k\u00ebrkesa ndaj JSONB, ndoshta gjithashtu n\u00eb <noindex><a rel=\"nofollow\" href=\"http:\/\/schinckel.net\/2014\/05\/25\/querying-json-in-postgres\/\">k\u00ebt\u00eb<\/a><\/noindex> post.<br \/>\nTani \u00ebsht\u00eb koha p\u00ebr t\u00eb folur p\u00ebr performanc\u00ebn.<\/p>\n<h3>Performanca<\/h3>\n<p>\nP\u00ebr t\u00eb krahasuar performanc\u00ebn, kam p\u00ebrdorur <noindex><a rel=\"nofollow\" href=\"http:\/\/www.postgresql.org\/docs\/9.1\/static\/sql-explain.html\">EXPLAIN ANALYZE<\/a><\/noindex> n\u00eb k\u00ebrkesat, p\u00ebr llogaritjen e koh\u00ebs s\u00eb ekzekutimit. \u00c7do k\u00ebrkes\u00eb u ekzekutua t\u00eb pakt\u00ebn tri her\u00eb, sepse her\u00ebn e par\u00eb planifikuesi i k\u00ebrkesave kishte nevoj\u00eb p\u00ebr m\u00eb shum\u00eb koh\u00eb. Fillimisht, un\u00eb ekzekutova k\u00ebrkesat pa asnj\u00eb indeks. \u00cbsht\u00eb e qart\u00eb se kjo sh\u00ebrbeu si nj\u00eb avantazh p\u00ebr JSONB, pasi bashkimet, t\u00eb nevojshme p\u00ebr EAV, nuk mund t\u00eb p\u00ebrdornin indekset (fushat e \u00e7el\u00ebsit t\u00eb jasht\u00ebm nuk ishin t\u00eb indeksuara). Pas k\u00ebsaj, un\u00eb krijova nj\u00eb indeks p\u00ebr 2 kolona t\u00eb \u00e7el\u00ebsit t\u00eb jasht\u00ebm n\u00eb tabel\u00ebn e vlerave EAV, si dhe nj\u00eb indeks <noindex><a rel=\"nofollow\" href=\"http:\/\/www.postgresql.org\/docs\/9.1\/static\/textsearch-indexes.html\">GIN<\/a><\/noindex> p\u00ebr kolon\u00ebn JSONB.<\/p>\n<p>P\u00ebrdit\u00ebsimet e t\u00eb dh\u00ebnave treguan rezultatet e m\u00ebposhtme n\u00eb koh\u00eb (n\u00eb ms). Vini re se shkalla \u00ebsht\u00eb logaritmike:<\/p>\n<p><img decoding=\"async\" alt=\"Z\u00ebvend\u00ebsimi i EAV me JSONB n\u00eb PostgreSQL\" src=\"\/wp-content\/uploads\/2019\/11\/8a12ccd7a46d04868b1cc5fcaf01a581.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nShohim se JSONB \u00ebsht\u00eb shum\u00eb m\u00eb i shpejt\u00eb (&gt; 50000-x) se EAV, n\u00ebse nuk p\u00ebrdoren indekset, p\u00ebr shkak t\u00eb arsyes s\u00eb p\u00ebrmendur m\u00eb lart. Kur ne indeksojm\u00eb kolonat me \u00e7el\u00ebsa primar\u00eb, ndryshimi pothuajse zhduket, por JSONB \u00ebsht\u00eb ende 1.3 her\u00eb m\u00eb i shpejt\u00eb se EAV. Vini re se indeksi n\u00eb kolon\u00ebn JSONB k\u00ebtu nuk ka asnj\u00eb ndikim, pasi ne nuk e p\u00ebrdorim kolon\u00ebn e pronave n\u00eb kriteret e vler\u00ebsimit. <\/p>\n<p>P\u00ebr t\u00eb zgjedhur t\u00eb dh\u00ebnat n\u00eb baz\u00eb t\u00eb vler\u00ebs s\u00eb pron\u00ebs, ne marrim rezultatet e m\u00ebposhtme (shkalla normale):<\/p>\n<p><img decoding=\"async\" alt=\"Z\u00ebvend\u00ebsimi i EAV me JSONB n\u00eb PostgreSQL\" src=\"\/wp-content\/uploads\/2019\/11\/e9a1fd797ef60132e661da686f6214a3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMund t\u00eb v\u00ebrejm\u00eb se JSONB p\u00ebrs\u00ebri funksionon m\u00eb shpejt se EAV pa indekse, por kur EAV ka indekse \u2013 ai p\u00ebrs\u00ebri punon m\u00eb shpejt se JSONB. Por pastaj pash\u00eb se koha p\u00ebr k\u00ebrkesat JSONB ishte e nj\u00ebjt\u00eb, kjo m\u00eb shtyu t\u00eb mendoj se indekset GIN nuk po funksiononin. Rrjedhimisht, kur p\u00ebrdorni indekset GIN p\u00ebr nj\u00eb kolon\u00eb me pronat e mbushura, ato veprojn\u00eb vet\u00ebm kur p\u00ebrdoret operatori i p\u00ebrfshirjes @&gt;. Un\u00eb e p\u00ebrdora k\u00ebt\u00eb n\u00eb nj\u00eb test t\u00eb ri, i cili kishte nj\u00eb ndikim t\u00eb madh n\u00eb koh\u00eb: vet\u00ebm 0,153 ms! Kjo \u00ebsht\u00eb 15000 her\u00eb m\u00eb shpejt se EAV, dhe 25000 her\u00eb m\u00eb shpejt se operatori -&gt;&gt;. <\/p>\n<p>Mendoj se ishte mjaft shpejt!<\/p>\n<h3>Madh\u00ebsia e tabelave t\u00eb DB<\/h3>\n<p>\nLe t\u00eb krahasojm\u00eb madh\u00ebsit\u00eb e tabelave me t\u00eb dyja qasjet. N\u00eb psql ne mund t\u00eb tregojm\u00eb madh\u00ebsin\u00eb e t\u00eb gjitha tabelave dhe indekseve me komand\u00ebn <b>dti+<\/b><\/p>\n<p><img decoding=\"async\" alt=\"Z\u00ebvend\u00ebsimi i EAV me JSONB n\u00eb PostgreSQL\" src=\"\/wp-content\/uploads\/2019\/11\/c6c1fe7901fe9ae2bd446cf4ae99b923.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nP\u00ebr qasjen EAV, madh\u00ebsit\u00eb e tabelave jan\u00eb rreth 3068 MB, nd\u00ebrsa indekset jan\u00eb deri n\u00eb 3427 MB, duke dh\u00ebn\u00eb s\u00eb bashku 6.43 GB. P\u00ebr qasjen me JSONB p\u00ebrdoren 1817 MB p\u00ebr tabel\u00ebn dhe 318 MB p\u00ebr indekset, q\u00eb p\u00ebrb\u00ebn 2.08 GB. Pra, \u00ebsht\u00eb 3 her\u00eb m\u00eb pak! Ky fakt m\u00eb befasoi pak, sepse ne ruajm\u00eb emrat e pronave n\u00eb \u00e7do objekt JSONB. <\/p>\n<p>Megjithat\u00eb, numrat flasin vet\u00eb: n\u00eb EAV ruajm\u00eb 2 \u00e7el\u00ebsa t\u00eb jasht\u00ebm num\u00ebror\u00eb p\u00ebr vler\u00ebn e atributit, duke rezultuar n\u00eb 8 byte t\u00eb dh\u00ebnash shtes\u00eb. P\u00ebr m\u00eb tep\u00ebr, n\u00eb EAV t\u00eb gjitha vlerat e pronave ruajn\u00eb si tekst, nd\u00ebrsa JSONB do t\u00eb p\u00ebrdor\u00eb vlera numerike dhe logjike brenda, ku t\u00eb jet\u00eb e mundur, duke rezultuar k\u00ebshtu n\u00eb nj\u00eb v\u00ebllim m\u00eb t\u00eb vog\u00ebl.<\/p>\n<h3>P\u00ebrfundime<\/h3>\n<p>\nN\u00eb p\u00ebrgjith\u00ebsi, mendoj se ruajtja e pronave t\u00eb entiteteve n\u00eb formatin JSONB mund t\u00eb thjeshtoj\u00eb n\u00eb m\u00ebnyr\u00eb t\u00eb konsiderueshme projektimin dhe mir\u00ebmbajtjen e baz\u00ebs tuaj t\u00eb t\u00eb dh\u00ebnave. N\u00ebse realizoni shum\u00eb k\u00ebrkesa, at\u00ebher\u00eb gjith\u00e7ka q\u00eb ruhet n\u00eb nj\u00eb tavolin\u00eb me entitetin do t\u00eb funksionoj\u00eb me t\u00eb v\u00ebrtet\u00eb m\u00eb efikas. Dhe fakti se kjo e thjeshton nd\u00ebrveprimin midis t\u00eb dh\u00ebnave \u00ebsht\u00eb tashm\u00eb nj\u00eb plus, por edhe DB p\u00ebrfundimtare \u00ebsht\u00eb 3 her\u00eb m\u00eb e vog\u00ebl n\u00eb v\u00ebllim.<\/p>\n<p>Gjithashtu, nga testet e realizuara, mund t\u00eb p\u00ebrfundojm\u00eb se humbjet e performanc\u00ebs jan\u00eb shum\u00eb t\u00eb vogla. N\u00eb disa raste, JSONB madje funksionon m\u00eb shpejt se EAV, gj\u00eb q\u00eb e b\u00ebn at\u00eb edhe m\u00eb t\u00eb mir\u00eb. Sidoqoft\u00eb, ky test referenc\u00eb, natyrisht, nuk mbulon t\u00eb gjitha aspektet (p\u00ebr shembull, entitete me nj\u00eb num\u00ebr t\u00eb madh pronash, rritje t\u00eb konsiderueshme t\u00eb numrit t\u00eb pronave t\u00eb t\u00eb dh\u00ebnave ekzistuese,\u2026), prandaj, n\u00ebse keni ndonj\u00eb sugjerim se si t'i p\u00ebrmir\u00ebsoni ato, ju lutem mos ngurroni t\u00eb lini komentet tuaja!<br \/>\n<br \/>Burimi: <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.2 - 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\/sq\/blog\/administrirovanie\/zamena-eav-na-jsonb-v-postgresql\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"sq_AL\" \/>\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\/sq\/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\udd47Z\u00ebvend\u00ebsimi i EAV me JSONB n\u00eb PostgreSQL | ProHoster","description":"TL; DR: JSONB mund ta thjeshtoj\u00eb ndjesh\u00ebm zhvillimin e skem\u00ebs s\u00eb DB pa cenuar performanc\u00ebn n\u00eb k\u00ebrkesa. Hyrje Le t\u00eb japim nj\u00eb shembull klasik, ndoshta, nga m\u00eb t\u00eb vjetrit.","canonical_url":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/zamena-eav-na-jsonb-v-postgresql","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sq_AL","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\/sq\/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\/sq\/wp-json\/wp\/v2\/posts\/52584","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/comments?post=52584"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/52584\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media?parent=52584"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/categories?post=52584"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/tags?post=52584"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}