I-TL; DR: I-JSONB ingenza kube lula kakhulu ukuthuthukiswa kwe-schema sesizindalwazi ngaphandle kokudela ukusebenza kombuzo.
Isingeniso
Ake sinikeze isibonelo sakudala cishe esinye sezigameko zokusetshenziswa ezindala kakhulu emhlabeni zesizindalwazi esihlobene (isizindalwazi): sinebhizinisi, futhi sidinga ukulondoloza izici ezithile (izibaluli) zaleli bhizinisi. Kodwa akuzona zonke izimo ezingaba nesethi efanayo yezakhiwo, futhi izakhiwo ezengeziwe zingase zengezwe ngokuzayo.
Indlela elula yokuxazulula le nkinga iwukuba udale ikholomu kuthebula lesizindalwazi yenani ngalinye lesakhiwo, futhi umane ugcwalise lezo ezidingekayo esimweni esithile sebhizinisi. Kuhle! Inkinga ixazululiwe... kuze kube yilapho ithebula lakho liqukethe izigidi zamarekhodi futhi udinga ukungeza irekhodi elisha.
Cabanga ngephethini ye-EAV (
Kodwa-ke, bengingeke ngibhale lokhu okuthunyelwe ukube bezingekho izinto ezingezinhle endleleni ye-Eva. Ngakho-ke, ngokwesibonelo, ukuthola ibhizinisi elilodwa noma ngaphezulu elinesibaluli esingu-1 lilinye, kudingeka ukujoyina okungu-2 embuzweni: eyokuqala iwukuhlanganisa nethebula lesichasiso, okwesibili ukuhlanganisa nethebula lamanani. Uma ibhizinisi linezibaluli ezi-2, kudingeka ukujoyina okungu-4! Ukwengeza, zonke izibaluli zivame ukugcinwa njengezintambo, okuholela ekulingiseni kohlobo kokubili komphumela kanye nesigatshana esithi WHERE. Uma ubhala imibuzo eminingi, khona-ke lokhu kuwukumosha impela mayelana nokusetshenziswa kwezinsiza.
Naphezu kwalokhu kushiyeka okusobala, i-EAV sekuyisikhathi eside isetshenziselwa ukuxazulula lezi zinhlobo zezinkinga. Lawa kwakungamaphutha angenakugwenywa, futhi yayingekho enye indlela engcono kakhulu.
Kepha kwabe sekuvela βubuchwephesheβ obusha ku-PostgreSQL...
Kusukela nge-PostgreSQL 9.4, uhlobo lwedatha ye-JSONB lwengezwe ukuze kugcinwe idatha kanambambili ye-JSON. Nakuba ukugcina i-JSON ngale fomethi ngokuvamile kuthatha isikhala esiningi nesikhathi kunombhalo ongenalutho othi JSON, ukwenza imisebenzi kuyo kuyashesha kakhulu. I-JSONB iphinde isekele ukukhonjwa, okwenza imibuzo isheshe nakakhulu.
Uhlobo lwedatha ye-JSONB lusivumela ukuthi simiselele iphethini ye-EAV enzima ngokwengeza ikholomu eyodwa nje ye-JSONB kuthebula lethu lebhizinisi, okwenza kube lula kakhulu ukwakheka kwesizindalwazi. Kodwa abaningi bathi lokhu kufanele kuhambisane nokuncipha kokukhiqiza... Yingakho ngibhale lesi sihloko.
Ukusetha isizindalwazi sokuhlola
Kulesi siqhathaniso, ngidale i-database ekufakweni okusha kwe-PostgreSQL 9.5 ku-$80 build.
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
);
Ngezansi kunethebula lapho idatha efanayo izogcinwa khona, kodwa ngezibaluli kukholomu yohlobo lwe-JSONB - izakhiwo.
CREATE TABLE entity_jsonb (
id SERIAL PRIMARY KEY,
name TEXT,
description TEXT,
properties JSONB
);
Kubukeka kulula kakhulu, akunjalo? Bese yengezwa kumathebula ebhizinisi (inhlangano & entity_jsonb) Amarekhodi ayizigidi ezingu-10, futhi ngenxa yalokho, ithebula lagcwaliswa ngedatha efanayo kusetshenziswa iphethini ye-EAV nendlela enekholomu ye-JSONB - entity_jsonb.properties. Ngakho-ke, sithole izinhlobo eziningana zedatha ezihlukene phakathi kwayo yonke isethi yezakhiwo. Idatha yesampula:
{
id: 1
name: "Entity1"
description: "Test entity no. 1"
properties: {
color: "red"
lenght: 120
width: 3.1882420
hassomething: true
country: "Belgium"
}
}
Ngakho manje sinedatha efanayo yazo zombili izinketho. Ake siqale ukuqhathanisa ukuqaliswa emsebenzini!
Yenza umklamo wakho ube lula
Phambilini kwashiwo ukuthi ukwakheka kwesizindalwazi kwenziwe kwaba lula kakhulu: ithebula elilodwa, ngokusebenzisa ikholomu ye-JSONB yezakhiwo, esikhundleni sokusebenzisa amathebula amathathu e-EAV. Kodwa lokhu kubonakala kanjani ezicelweni? Ukubuyekeza impahla yebhizinisi eyodwa kubukeka kanje:
-- 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;
Njengoba ubona, isicelo sokugcina asibukeki silula. Ukuze sibuyekeze inani lesakhiwo entweni ye-JSONB kufanele sisebenzise umsebenzi
Manje ake sikhethe ibhizinisi esisanda kulibuyekeza ngokusekelwe kumbala walo omusha:
-- 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';
Ngicabanga ukuthi singavuma ukuthi eyesibili yifushane (akukho ukujoyina!), ngakho-ke ifundeka kakhudlwana. I-JSONB iyawina lapha! Sisebenzisa i-opharetha ye-JSON ->> ukuze sithole umbala njengenani lombhalo entweni ye-JSONB. Kukhona nendlela yesibili yokuzuza umphumela ofanayo kumodeli ye-JSONB usebenzisa @> opharetha:
-- JSONB
SELECT name
FROM entity_jsonb
WHERE properties @> '{"color": "blue"}';
Lokhu kuyinkimbinkimbi kakhulu: sihlola ukuze sibone ukuthi ingabe into ye-JSON kukholomu yezindawo zayo iqukethe into engakwesokudla ku-opharetha @>. Ayifundeki kangako, ikhiqiza kakhulu (bheka ngezansi).
Masenze ukusebenzisa i-JSONB kube lula nakakhulu uma udinga ukukhetha izakhiwo eziningi ngesikhathi esisodwa. Kulapho indlela ye-JSONB ingena khona ngempela: simane sikhethe izakhiwo njengamakholomu engeziwe kusethi yethu yemiphumela ngaphandle kwesidingo sokujoyina:
-- JSONB
SELECT name
, properties ->> 'color'
, properties ->> 'country'
FROM entity_jsonb
WHERE id = 120;
Nge-EAV uzodinga ukujoyina okungu-2 endaweni ngayinye ofuna ukuyibuza. Ngokubona kwami, le mibuzo engenhla ikhombisa ukwenziwa lula okukhulu ekwakhiweni kwesizindalwazi. Bona izibonelo eziningi zendlela yokubhala imibuzo ye-JSONB, naku
Manje sekuyisikhathi sokukhuluma ngokusebenza.
Ukukhiqiza
Ukuqhathanisa ukusebenza engikusebenzisile
Ukubuyekezwa kwedatha kubonise imiphumela elandelayo ngokwesikhathi (nge-ms). Qaphela ukuthi isikali siyi-logarithmic:
Siyabona ukuthi i-JSONB ishesha kakhulu (> 50000-x) kune-EAV uma ungasebenzisi izinkomba, ngenxa yesizathu esishiwo ngenhla. Uma sikhomba amakholomu anokhiye abayinhloko, umehluko ucishe unyamalale, kodwa i-JSONB isashesha izikhathi ezingu-1,3 kune-EAV. Qaphela ukuthi inkomba kukholomu ye-JSONB ayinamthelela lapha njengoba singasebenzisi ikholomu yendawo kumibandela yokuhlola.
Ngokukhetha idatha ngokusekelwe kunani lesakhiwo, sithola imiphumela elandelayo (isikali esivamile):
Ungaqaphela ukuthi i-JSONB futhi isebenza ngokushesha kune-EAV ngaphandle kwezinkomba, kodwa uma i-EAV inezinkomba, isasebenza ngokushesha kune-JSONB. Kodwa-ke ngabona ukuthi izikhathi zemibuzo ye-JSONB zazifana, lokhu kungenze ngathola ukuthi izinkomba ze-GIN azisebenzi. Ngokusobala uma usebenzisa inkomba ye-GIN kukholomu enezici ezigcwele, iqala ukusebenza kuphela uma usebenzisa ukufaka phakathi u-opharetha @>. Ngisebenzise lokhu esivivinyweni esisha futhi kwaba nomthelela omkhulu ngesikhathi: kuphela 0,153ms! Lokhu kushesha izikhathi ezingu-15000 kune-EAV futhi izikhathi ezingu-25000 ngokushesha kuno-opharetha ->>.
Ngicabanga ukuthi bekushesha ngokwanele!
Usayizi wethebula lesizindalwazi
Ake siqhathanise osayizi betafula kuzo zombili izindlela. Ku-psql singabonisa usayizi wawo wonke amatafula nezinkomba sisebenzisa umyalo dti+
Ngendlela ye-EAV, osayizi bethebula balinganiselwa ku-3068 MB kanye nezinkomba ezifika ku-3427 MB ngesamba esingu-6,43 GB. Indlela ye-JSONB isebenzisa u-1817 MB kuthebula no-318 MB kuma-index, okungu-2,08 GB. Kuvela izikhathi ezi-3 ngaphansi! Leli qiniso lingimangaze kancane ngoba sigcina amagama ezakhiwo kuzo zonke izinto ze-JSONB.
Kodwa noma kunjalo, izinombolo ziyazikhulumela: ku-EAV sigcina izinombolo ezi-2 zokhiye bangaphandle ngenani lemfanelo ngayinye, okuholela kumabhayithi angu-8 edatha eyengeziwe. Ukwengeza, i-EAV igcina wonke amanani ezakhiwo njengombhalo, kuyilapho i-JSONB izosebenzisa amanani ezinombolo ne-boolean ngaphakathi lapho kungenzeka khona, okuholela ekugxilweni okuncane.
Imiphumela
Sekukonke, ngicabanga ukuthi ukulondoloza izakhiwo zebhizinisi ngefomethi ye-JSONB kungenza ukuklama nokugcina isizindalwazi sakho kube lula kakhulu. Uma usebenzisa imibuzo eminingi, ukugcina yonke into etafuleni elifanayo nebhizinisi kuzosebenza ngokuphumelelayo. Futhi iqiniso lokuthi lokhu kwenza kube lula ukusebenzisana phakathi kwedatha sekuvele kuhlanganisiwe, kodwa i-database ewumphumela incane izikhathi ezi-3 ngevolumu.
Futhi, ngokusekelwe ekuhloleni okwenziwe, singaphetha ngokuthi ukulahlekelwa kokusebenza akubalulekile kakhulu. Kwezinye izimo, i-JSONB ishesha kakhulu kune-EAV, iyenza ibe ngcono nakakhulu. Nokho, le bhentshimakhi ayifaki zonke izici (isb., amabhizinisi anenani elikhulu kakhulu lezakhiwo, ukwanda okuphawulekayo kwenani lezakhiwo zedatha ekhona,...), ngakho-ke uma uneziphakamiso zokuthi ungazithuthukisa kanjani. , sicela ukhululeke ukushiya kumazwana!
Source: www.habr.com