TL; DR: JSONB tuaj yeem ua kom yooj yim rau kev tsim cov ntaub ntawv schema yam tsis muaj kev txi kev ua haujlwm ntawm cov lus nug.
Taw qhia
Cia peb siv ib qho piv txwv classic, tej zaum yog ib qho ntawm cov ntaub ntawv siv qub tshaj plaws hauv ntiaj teb ntawm cov ntaub ntawv sib raug zoo: peb muaj ib lub koom haum, thiab peb yuav tsum khaws qee yam khoom (cov cwj pwm) ntawm lub koom haum no. Tab sis tsis yog txhua qhov piv txwv yuav muaj tib pawg khoom, thiab ntau yam khoom yuav raug ntxiv rau yav tom ntej.
Qhov kev daws teeb meem yooj yim tshaj plaws rau qhov teeb meem no yog tsim ib kab hauv lub rooj ntaub ntawv rau txhua tus nqi khoom thiab tsuas yog sau cov uas xav tau rau ib qho piv txwv tshwj xeeb. Zoo heev! Teeb meem daws tau lawm... kom txog thaum koj lub rooj muaj ntau lab cov ntaub ntawv thiab koj xav tau ntxiv cov ntaub ntawv tshiab.
Cia peb xav txog tus qauv EAV (), nws yog ib qho uas ntau heev. Ib lub rooj muaj cov chaw (cov ntaub ntawv), lwm lub rooj muaj cov npe khoom (cov yam ntxwv), thiab lub rooj thib peb txuas cov chaw rau lawv cov yam ntxwv thiab muaj cov nqi ntawm cov yam ntxwv no rau qhov chaw tam sim no. Qhov no tso cai rau koj kom muaj cov khoom sib txawv rau cov khoom sib txawv, nrog rau ntxiv cov khoom ntawm tus yoov, yam tsis hloov cov qauv ntaub ntawv.
Txawm li cas los xij, kuv yuav tsis sau tsab ntawv no yog tias tsis muaj qee qhov tsis zoo rau txoj hauv kev EVA. Piv txwv li, kev rov qab tau ib lossis ntau lub koom haum nrog ib qho attribute txhua tus xav tau ob qhov kev sib koom ua ke hauv cov lus nug: thawj qhov kev sib koom ua ke nrog lub rooj attribute, qhov thib ob kev sib koom ua ke nrog lub rooj nqi. Yog tias ib lub koom haum muaj ob qho attributes, ces plaub qhov kev sib koom ua ke yuav tsum tau ua! Ntxiv mus, txhua qhov attributes feem ntau khaws cia ua cov hlua, uas ua rau muaj kev yuam hom rau ob qho tib si qhov tshwm sim thiab WHERE clause. Yog tias koj sau ntau cov lus nug, qhov no yog qhov pov tseg heev hauv cov nqe lus ntawm kev siv cov peev txheej.
Txawm hais tias muaj cov teeb meem no los xij, EAV tau siv ntev los daws cov teeb meem no. Cov no yog cov teeb meem uas tsis zam tau, thiab tsis muaj lwm txoj hauv kev zoo dua.
Tab sis tom qab ntawd ib qho "technology" tshiab tau tshwm sim hauv PostgreSQL ...
Pib nrog PostgreSQL 9.4, hom ntaub ntawv JSONB tau ntxiv rau kev khaws cov ntaub ntawv binary JSON. Txawm hais tias kev khaws cia JSON hauv hom ntawv no feem ntau siv qhov chaw thiab sijhawm ntau dua li cov ntawv JSON yooj yim, kev ua haujlwm nrog nws sai dua. JSONB kuj txhawb nqa kev ntsuas, ua rau cov lus nug sai dua.
Cov hom ntaub ntawv JSONB tso cai rau peb hloov cov qauv EAV uas nyuaj los ntawm kev ntxiv ib kab JSONB rau peb lub rooj teeb tsa, ua rau kev tsim qauv ntaub ntawv yooj yim dua. Txawm li cas los xij, ntau tus neeg sib cav tias qhov no muaj tus nqi hauv kev ua tau zoo ... Yog vim li cas kuv thiaj sau tsab xov xwm no.
Teeb tsa lub ntaub ntawv sim
Rau qhov kev sib piv no, kuv tau tsim lub database ntawm kev teeb tsa tshiab ntawm PostgreSQL 9.5 ntawm $ 80 tsim. Ubuntu 14.04 Tom qab teeb tsa qee cov kev teeb tsa hauv postgresql.conf kuv tau khiav tsab ntawv siv psql. Txhawm rau nthuav qhia cov ntaub ntawv ua EAV, cov lus hauv qab no tau tsim:
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
);
Hauv qab no yog ib lub rooj uas cov ntaub ntawv tib yam yuav raug khaws cia, tab sis nrog cov cwj pwm hauv ib kab JSONB - zog.
CREATE TABLE entity_jsonb (
id SERIAL PRIMARY KEY,
name TEXT,
description TEXT,
properties JSONB
);
Zoo li yooj yim dua, puas yog? Tom qab ntawd nws tau ntxiv rau cov lus qhia ntawm cov khoom (qhov chaw & entity_jsonb) 10 lab cov ntaub ntawv, thiab raws li, lub rooj tau sau nrog cov ntaub ntawv zoo sib xws uas tus qauv EAV thiab txoj hauv kev nrog JSONB kem tau siv - entity_jsonb.propertiesYog li, peb tau txais ntau hom ntaub ntawv sib txawv thoob plaws tag nrho cov khoom. Piv txwv li cov ntaub ntawv:
{
id: 1
name: "Entity1"
description: "Test entity no. 1"
properties: {
color: "red"
lenght: 120
width: 3.1882420
hassomething: true
country: "Belgium"
}
}Yog li, tam sim no peb muaj cov ntaub ntawv zoo ib yam rau ob qho kev xaiv. Cia peb pib sib piv cov kev siv hauv lub neej tiag tiag!
Ua kom yooj yim rau kev tsim qauv
Tau hais ua ntej lawm tias kev tsim qauv ntaub ntawv tau yooj yim heev: ib lub rooj, siv ib kab JSONB rau cov khoom, es tsis yog peb lub rooj rau EAV. Tab sis qhov no txhais li cas rau hauv cov lus nug? Kev hloov kho ib qho khoom ntawm ib qho chaw zoo li no:
-- 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;
Raws li koj tuaj yeem pom, cov lus nug kawg tsis zoo li yooj yim dua. Txhawm rau hloov kho tus nqi ntawm cov cuab yeej hauv JSONB khoom, peb yuav tsum siv cov haujlwm , thiab yuav tsum dhau peb tus nqi tshiab ua ib yam khoom JSONB. Txawm li cas los xij, peb tsis tas yuav paub ib qho cim qhia ua ntej. Saib ntawm EAV piv txwv, peb yuav tsum paub ob qho tib si entity_id thiab entity_attribute_id los ua qhov hloov tshiab. Yog tias koj xav hloov kho ib yam khoom hauv JSONB kem raws li lub npe khoom, nws ua tiav tag nrho hauv ib kab yooj yim.
Tam sim no cia peb xaiv qhov chaw uas peb nyuam qhuav hloov kho raws li nws cov xim tshiab:
-- 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';
Kuv xav tias peb tuaj yeem pom zoo tias qhov thib ob luv dua (tsis muaj kev koom ua ke!) thiab yog li ntawd nyeem tau yooj yim dua. JSONB yeej ntawm no! Peb siv JSON ->> tus neeg teb xov tooj kom rov qab tau cov xim ua tus nqi ntawv los ntawm JSONB khoom. Kuj tseem muaj txoj hauv kev thib ob los ua tiav tib yam hauv JSONB qauv siv tus neeg teb xov tooj @>:
-- JSONB
SELECT name
FROM entity_jsonb
WHERE properties @> '{"color": "blue"}';
Qhov no nyuaj me ntsis: peb xyuas seb JSON khoom hauv kab properties puas muaj cov khoom nyob rau sab xis ntawm tus neeg ua haujlwm @>. Nyeem tsawg dua, ua tau zoo dua (saib hauv qab no).
Cia peb ua kom yooj yim dua thaum koj xav tau xaiv ntau yam khoom tib lub sijhawm. Qhov no yog qhov uas txoj hauv kev JSONB ci ntsa iab tiag tiag: peb tsuas yog xaiv cov khoom ua cov kab ntxiv hauv peb cov txiaj ntsig teeb tsa, tsis tas yuav koom ua ke:
-- JSONB
SELECT name
, properties ->> 'color'
, properties ->> 'country'
FROM entity_jsonb
WHERE id = 120;
Nrog EAV, koj yuav xav tau ob qhov kev sib koom ua ke rau txhua yam khoom uas koj xav nug. Hauv kuv lub tswv yim, cov lus nug saum toj no qhia txog kev yooj yim hauv kev tsim cov ntaub ntawv. Koj tuaj yeem pom ntau cov piv txwv ntawm yuav ua li cas sau cov lus nug JSONB hauv tsab ntawv.
Tam sim no yog lub sijhawm los tham txog kev ua tau zoo.
Tsim tau
Los piv rau qhov kev ua tau zoo uas kuv siv hauv cov lus nug los xam lub sijhawm ua tiav. Txhua qhov lus nug tau ua tiav tsawg kawg peb zaug, vim tias tus neeg npaj lus nug siv sijhawm ntev dua thawj zaug. Ua ntej, kuv tau khiav cov lus nug yam tsis muaj cov ntsuas. Qhov no pom tseeb tias yog qhov zoo ntawm JSONB, txij li thaum cov kev sib koom ua ke uas xav tau rau EAV tsis tuaj yeem siv cov ntsuas (cov teb tseem ceeb txawv teb chaws tsis tau ntsuas). Tom qab ntawd, kuv tau tsim ib qho ntsuas ntawm ob kab tseem ceeb txawv teb chaws ntawm lub rooj nqi EAV, nrog rau ib qho ntsuas rau kab JSONB.
Cov ntaub ntawv hloov tshiab tau qhia cov txiaj ntsig ntawm lub sijhawm hauv qab no (hauv ms). Nco ntsoov tias qhov ntsuas yog logarithmic:

Peb pom tias JSONB yog qhov tseem ceeb (> 50000x) sai dua li EAV yam tsis muaj cov ntsuas, rau qhov laj thawj uas tau hais los saum toj no. Thaum peb ntsuas cov kab tseem ceeb tseem ceeb, qhov sib txawv yuav luag ploj mus, tab sis JSONB tseem yog 1,3x sai dua li EAV. Nco ntsoov tias cov ntsuas ntawm kab JSONB tsis muaj txiaj ntsig ntawm no, vim peb tsis siv kab khoom hauv cov qauv ntsuas.
Rau kev xaiv cov ntaub ntawv raws li tus nqi ntawm cov cuab yeej, peb tau txais cov txiaj ntsig hauv qab no (qhov ntsuas ib txwm muaj):

Koj tuaj yeem pom tias JSONB dua sai dua li EAV yam tsis muaj cov ntsuas, tab sis thaum EAV raug ntsuas, nws tseem sai dua li JSONB. Tab sis tom qab ntawd kuv pom tias lub sijhawm rau cov lus nug JSONB zoo ib yam, uas ua rau kuv paub tseeb tias GIN ntsuas tsis raug cuam tshuam. Zoo li, thaum koj siv GIN ntsuas ntawm ib kab nrog cov khoom muaj neeg coob, nws tsuas yog siv tau thaum siv tus neeg teb xov tooj @>. Kuv siv qhov no hauv kev sim tshiab, thiab nws muaj kev cuam tshuam loj heev rau lub sijhawm: tsuas yog 0,153 ms! Qhov ntawd yog 15000 npaug sai dua li EAV thiab 25000 npaug sai dua li ->> tus neeg teb xov tooj.
Kuv xav tias nws ceev heev!
Qhov loj ntawm cov rooj ntaub ntawv
Cia peb piv qhov loj ntawm cov rooj rau ob txoj hauv kev. Hauv psql, peb tuaj yeem tso saib qhov loj ntawm txhua lub rooj thiab cov ntsuas siv cov lus txib dti+

Nrog rau txoj kev EAV, qhov loj ntawm lub rooj yog kwv yees li 3068 MB, thiab cov indexes yog txog li 3427 MB, rau tag nrho ntawm 6,43 GB. Siv txoj kev JSONB, lub rooj siv 1817 MB thiab indexes 318 MB, rau tag nrho ntawm 2,08 GB. Qhov ntawd yog ib feem peb ntawm qhov loj! Qhov tseeb no ua rau kuv xav tsis thoob me ntsis, vim peb khaws cov npe khoom hauv txhua yam khoom JSONB.
Tab sis cov lej hais lus rau lawv tus kheej: hauv EAV, peb khaws ob tus lej txawv teb chaws rau ib tus nqi ntawm tus cwj pwm, ua rau muaj 8 bytes ntawm cov ntaub ntawv ntxiv. Ntxiv mus, hauv EAV, txhua tus nqi ntawm cov cuab yeej raug khaws cia ua ntawv, thaum JSONB yuav siv cov lej thiab cov lej sib piv sab hauv qhov twg ua tau, ua rau muaj qhov chaw me dua.
Cov txiaj ntsim tau los
Zuag qhia tag nrho, kuv xav tias kev khaws cov khoom ntawm cov chaw ua haujlwm hauv JSONB hom ntawv tuaj yeem ua rau kev tsim thiab kev saib xyuas ntawm koj lub database yooj yim dua. Yog tias koj ua ntau cov lus nug, kev khaws txhua yam hauv tib lub rooj raws li lub chaw ua haujlwm yuav ua haujlwm tau zoo dua. Qhov tseeb tias nws ua kom yooj yim rau kev sib cuam tshuam ntawm cov ntaub ntawv twb yog qhov zoo lawm, tab sis cov ntaub ntawv tshwm sim kuj tseem me dua peb zaug.
Tsis tas li ntawd xwb, raws li cov txiaj ntsig ntawm qhov kev ntsuas, peb tuaj yeem xaus lus tias qhov kev nplua rau kev ua tau zoo yog me me heev. Qee zaum, JSONB txawm ua tau sai dua EAV, ua rau nws zoo dua. Txawm li cas los xij, qhov kev ntsuas no yeej tsis suav nrog txhua yam (piv txwv li, cov chaw uas muaj ntau yam khoom, qhov nce ntxiv ntawm cov khoom hauv cov ntaub ntawv uas twb muaj lawm, thiab lwm yam), yog li ntawd yog tias koj muaj lus qhia rau kev txhim kho, thov koj tso lawv rau hauv cov lus!
Tau qhov twg los: www.hab.com
