Ryšiai tarp modelių#

Pateikiant metaduomenis apie ryšius tarp modelių, duomenų brandos lygis pakeliamas iki ketvirto lygio.

Ryšiai tarp modelių aprašomi tais atvejais, kai vienoje duomenų lentelėje naudojami identifikatoriai iš kitos lentelės.

Jungimas per pirminį raktą#

Pavyzdžiui, jei turime tokias dvi duomenų lenteles:

Country

id

name

code

1

Lietuva

lt

2

Latvija

lv

City

id

name

country

1

Vilnius

lt

2

Kaunas

lt

3

Ryga

lv

Šiuo atveju, jei norime parengti aukščiau pateiktų duomenų struktūros aprašą, jis atrodytų taip:

id

d

r

b

m

property

type

ref

level

1

datasets/gov/example/countries

2

Country

code

4

3

id

integer

4

4

name

string

4

5

code

string

4

6

City

id

4

7

id

integer

4

8

name

string

4

9

country

ref

Country

4

Šiame duomenų struktūros apraše, 9-oje eilutėje country stulpelio tipas yra ref, tai reiškia, kad šis stulpelis yra kito modelio išorinis raktas. property.ref stulpelyje nurodyta kurio modelio išorinis raktas šis stulpelis yra. Šiuo atveju, tai yra Country modelis, kuris apibrėžtas 2-oje eilutėje.

Pagal nutylėjimą, ryšys su kitu modeliu nustatomas naudojant kitos lentelės pirminį raktą nurodytą model.ref stulpelyje. Šiuo atveju, City .country yra jungiamas per Country.code. Tai reiškia, kad City.country duomenų tipas turi sutapti su Country.code duomenų tipu, kuris yra string.

property.ref reikšmė gali būti pateikiama vienu iš šių variantų:

property.ref
model

model nurodo kito model pavadinimą kurio model.ref siejamas su property.

Jei model.ref pirminiam raktui naudoja daugiau nei vieną lauką, tada property.source laukas turi būti tuščias, o property.prepare turi būti pateikiamos kableliu atskirtos property reikšmės, kurios bus naudojamos susiejimui.

model[property]

Tais atvejais, kai property duomenys nesutampa su siejamo model.ref, galima nurodyti propertymodel.

model[*property]

Jei susiejimui reikia daugiau nei vieno duomenų lauko ir jie nesutampa su model.ref, tada galima nurodyti kelias property reikšmes atskirtas kableliu. Tačiau šiuo atveju taip pat būtina nurodyti ir property.prepare kelias reikšmes atskirtas kableliu, o property.source reikšmė turi būti tuščia. property.prepare stulpelyje nurodomi kiti modelio property pavadinimai iš kurių duomenų reikšmių turi būti formuojamas sudėtinis raktas.

Jungimas per nepirminį raktą#

Jei modelius reikia jungti ne per pirminį raktą, o per kitus laukus, tada naudojama model[property] forma.

Pavyzdžiui, jei turime tokius duomenis:

Country

id

name

code

1

Lietuva

lt

2

Latvija

lv

City

id

name

country

1

Vilnius

lt

2

Kaunas

lt

3

Ryga

lv

Kur Country pirminis raktas yra id ir norime jungti City.country per Country.code, tuomet duomenų struktūros aprašas atrodys taip:

d

d

r

b

m

property

type

ref

level

1

datasets/gov/example/countries

2

Country

id

4

3

id

integer

4

4

name

string

4

5

code

string

4

6

City

id

4

7

id

integer

4

8

name

string

4

9

country

ref

Country[code]

4

9-oje eilutėje property.ref stulpelyje pateikta Country[code] reikšmė, kuri Country nurodo su kokiu modeliu jungiame, o code nurodo su kokiu Country stulpeliu jungiame. Jei pateiktas tik modelis, tada jungiama per to modelio pirminį raktą, jei pateiktas stulpelis laužtiniuose skliausteliuose, tada jungiama per nurodytą stulpelį.

Jungimas per kompozicinį raktą#

Jei modelius reikia jungti per kelis laukus, tada naudojama model[*property] forma, kur laužtiniuose skliaustuose pateikiami keli stulpeliai atskirti kableliais.

Pavyzdžiui, jei turime tokius duomenis:

Country

id

name

code

1

Lietuva

lt

2

Latvija

lv

City

id

name

country

country_id

1

Vilnius

lt

1

2

Kaunas

lt

1

3

Ryga

lv

2

Kur City su Country yra jungiamas per du country ir country_id stulpelius, tuomet reikia įtraukti išvestinį duomenų lauką, kuriame formulės įrašomos į property.prepare pagalba apjungiami keli laukai į vieną kompozicinį raktą. Šiuo atveju duomenų struktūros aprašas atrodys taip:

d

d

r

b

m

property

type

ref

prepare

level

1

datasets/gov/example/countries

2

Country

id

4

3

id

integer

4

4

name

string

4

5

code

string

4

6

City

id

4

7

id

integer

4

8

name

string

4

9

country_code

string

4

10

country_id

integer

4

11

country

ref

Country[id,code]

country_id, country_code

4

Čia matome, kad 11-oje eilutėje buvo įtrauktas išvestinis laukas country, kuris išskaičiuojamas apjungiant country_id ir country_code. O ryšiui su Country, laužtiniuose skliausteliuose nurodyti du laukai iš jungiamo Country modelio. Abiejų jungiamų pusių pateiktas laukų sąrašas turi būti vienodo eiliškumo, o jungiami laukai turi turėti vienodus tipus.

Jei Country pirminis raktas būtų kompozicinis, pavyzdžiui id, code, tuomet, 11-oje eilutėje property.ref užtektu nurodyti tik Country.

Jungimas atgaliniu ryšiu#

Jungiant modelius atgaliniu ryšiu kuriamas išvestinis arba virtualus laukas, kuriame analogiškai kaip ir paprasto ryšio atveju, apjungiami du modeliai, tik šiuo atveju kuriamas daug su vienas tipo ryšys.

Pavyzdžiui, jei turime tokius duomenis:

Country

id

name

1

Lietuva

2

Latvija

City

id

name

country

1

Vilnius

1

2

Kaunas

1

3

Ryga

2

Ir šiuos duomenis atitinkantį duomenų modelį:

classDiagram direction LR class Country { + id: integer [1..1] + name@lt: string [1..1] } class City { + id: integer [1..1] + name@lt: string [1..1] } City --> "[1..1]" Country : country City "[1..*]" <-- Country : cities

Tai norint sukurti atgalinį ryšį iš City modelio į Country modelį, duomenų struktūros aprašas atrodys taip:

model

property

type

ref

level

Country

id

4

id

integer

4

name@lt

string

4

cities[]

backref

City

4

City

id

4

id

integer

4

name@lt

string

4

country

ref

Country

4

Čia atgalinis ryšys nurodytas 5-oje eilutėje, pateikiant virtualų Country.cities lauką, kuris jungiamas per City.country lauką, kadangi City.country turi ryšį su Country.

Jei City modelyje būtų pateikti keli stulpeliai susieti su Country, tada 5-oje eilutėje property.ref reikšmė turėtų nurodyti konkretų lauką, per kurį jungiama, pavyzdžiui City[country].

Polimorfinis jungimas#

Pastaba

Tokio tipo jungimas kol kas dar nėra įgyvendintas.

Polimorfinis jungimas yra toks ryšys tarp modelių, kai vieno modelio laukas yra siejamas su daugiau nei vienu kitu modeliu. Tokiam ryšiui nurodyti polimorfinis laukas turi dvi reikšmes, išorinio modelio pavadinimą ir to modelio stulpelio per kurį jungiama reikšmę.

Country

id

name

1

Lietuva

2

Latvija

City

id

name

country

1

Vilnius

1

2

Ryga

2

Event

id

name

object_id

object_model

1

Įkūrimas

1

datasets/gov/example/countries/Country

2

Įkūrimas

2

datasets/gov/example/countries/Country

3

Įkūrimas

1

datasets/gov/example/countries/City

4

Įkūrimas

2

datasets/gov/example/countries/City

Pavyzdyje aukščiau matome, kad yra du modeliai Country ir City, kuriuos jungia Event modelis per object_id ir object_model laukus. Pavyzdžiui Event kurio id yra 1, siejamas su Country modeliu, kurio id yra 1.

Tokių duomenų struktūros aprašas atrodys taip:

d

d

r

b

m

property

type

ref

prepare

level

1

datasets/gov/example/countries

2

Country

id

4

3

id

integer

4

4

name

string

4

5

cities[]

backref

City

4

6

City

id

4

7

id

integer

4

8

name

string

4

9

country

ref

Country

4

10

Event

id

4

11

id

integer

4

12

name

string

4

13

object_id

integer

4

14

object_model

string

4

15

object

generic

Country

object_model, object_id

4

16

City

15-oje eilutėje įtrauktas virtualus Event.object laukas, kuris 15-oje ir 16-oje eilutėse, property.ref stulpelyje išvardina du modelius Country ir City, su kuriais jungiamas šis laukas, per object_model ir object_id laukus, kurie aprašyti atskirai.

object_id ir object_model aprašomi atskirai tik todėl, kad duomenys ateina iš išorinio šaltinio. Jei duomenys rašomi tiesiogiai į Saugyklą, tada atskirai generic laukų apsirašyti nereikia.

Denormalizuoti duomenys#

Denormalizuoti duomenų laukai yra tokie laukai, kurie pateikti viename modelyje, tačiau pagal semantinę prasmę priklauso skirtingiems modeliams.

Dažniausiai duomenų normalizavimas atveriant duomenis yra nepageidaujamas ir duomenų struktūra turėtu būti transformuojama į skirtingus modelius, pagal semantinę prasmę. Plačiau apie duomenų normalizavimą galite skaityti skyriuje norm.

Tačiau tais atvejais, kai vis dėlto norima pateikti duomenis denormalizuotoje formoje, duomenų struktūros apraše galima nurodyti, kurie duomenų laukai yra denormalizuoti.

Pavyzdys, kaip atrodo denormalizuotų duomenų laukų žymėjimas:

d

r

b

m

property

type

ref

level

example

Country

code

4

code

string

4

name@en

text

4

City

3

name@en

text

4

country

ref

Country

4

country.code

2

country.name@en

2

country.name@lt

text

2

Šiame pavyzdyje turime tokius laukus:

country

Šis laukas yra ref tipo, tai reiškia, kad šiame lauke saugomas Country modelio identifikatorius, kurio pagalba City galima susieti su Country.

ref tipo duomenys yra sudėtiniai, tai reiškia, kad per ref tipo lauką galima pasiekti siejamo modelio laukus, nurodant kito modelio laukus po taško.

Todėl pagal nutylėjimą country ref Country yra tas pats, kas country._id ref Country, tik ._id dalis nenurodoma.

country.code ir country.name@en

Šie laukai yra denormalizuoti, tai reiškia, kad jie priklauso Country modeliui, tačiau duomenys yra dubliuojami ir pateikiami dviejose vietose, prie Country ir prie City.country.

Kadangi City.country yra ref tipo, tai po taško, galima nurodyti kitus šiam siejamam modeliui priklausančius laukus iš kito modelio.

Atkreipkite dėmesį, kad denormalizuotiems laukams nepildomas type stulpelis, kadangi šių laukų tipas turi sutapti su siejamo modelio laukų tipais, taip pat turi sutapti ir laukų pavadinimai.

country.name@lt

Tais atvejais, kai siejamame modelyje (šiuo atveju Country modelyje) nėra tam tikrų laukų, tuomet galima juose pateikti ir prie City.country, tačiau tokiu atveju, būtina nurodyti type.

Brandos lygis#

Apibrėžiant ryšius tarp modelių, brandos lygis įrašomas level stulpelyje atlieka svarbų vaidmenį. Nuo brandos lygio, priklauso, kaip turi būti interpretuojamas išorinis raktas, siejamas su kitu modeliu.

1 brandos lygis: Susiejimas neįmanomas

Duomenys pateikti tokia forma, kurios pagalba dviejų modelių jungimas nėra įmanomas.

Pavyzdžiui, pateikta adreso tekstinė forma, kuri nesutampa su tekstine forma pateikiama oficialiame adresų registre arba naudojamas toks tam tikras identifikatorius, kuris nėra surištas su siejamo modelio pirminiu raktu.

2 brandos lygis: Susiejimas nepatikimas

Duomenys pateikiami tam tikra forma, kuri neužtikrina patikimo duomenų susiejimo, tačiau siejimas atliekamas pagal siejamo modelio atributą, kuris negarantuoja unikalaus objekto identifikavimo.

Pavyzdžiui siejimas atliekamas pagal pavadinimą, kuris gali keistis arba ne visais atvejais sutampa.

3 brandos lygis: Susiejimas ne per pirminį raktą

Duomenims susieti naudojamas patikimas identifikatorius, kuris yra surištas su siejamo modelio pirminiu raktu, tačiau naudojamas ne pirminis raktas, o kitas identifikatorius.

4 brandos lygis: Susiejimas per pirminį raktą

Susiejimas daromas per pirminį raktą.

Susiejimas neįmanomas#

Jei ref tipui nurodytas 1 arba žemesnis brandos lygis, tai reiškia, duomenų jungimas nėra įmanomas. Tokiu atveju, atveriant duomenis, property įgaus tokį tipą, koks yra lauko su kuriuo siejamas ryšys tipas.

Pavyzdžiui:

d

r

b

m

property

type

ref

level

example

Country

name@lt

4

name@lt

text

4

City

name

4

name@lt

text

4

country

ref

Country

1

Šiuo atveju, City.country yra siejamas su Country.name. Kadangi City.country brandos lygis yra 2, tai reiškia, kad City.country ir Country.name pavadinimai nesutampa ir jungimo atlikti neįmanoma. Tokiu atveju, City.country tipas bus ne ref, o toks pat, kaip Country.name, t.y. text.

Tačiau, metaduomenyse išliks informacija, apie tai, kad šios lentelės yra susijusios. Dėl prasto duomenų brandos lygios, realus susiejimas nėra įmanomas.

Jei modeliai yra susiję, tačiau, tokio duomenų lauko, per kurį galima būtų atlikti susiejimą iš vis nėra, tuomet, tokį lauką galima sukurti, nurodant brandos lygį 0. Pavyzdžiui:

d

r

b

m

property

type

ref

level

example

Country

name@lt

4

name@lt

text

4

name@en

text

0

City

name

4

name@en

text

4

country

ref

Country[name@en]

1

Šioje vietoje City.country tampa country@en, kurio tipas yra text. O į Country yra įtrauktas papildomas laukas name@en, per kurį ir atliekamas susiejimas, t.y. per kurį galėtų būti atliktas susiejimas, jei toks laukas egzistuotų ne tik City.country, bet ir Country.name@en.

Susiejimas nepatikimas#

Jei ref tipui suteiktas 2 brandos lygis, tai reiškia, kad susiejimas yra įmanomas, tačiau nėra garantijos, kad jis veiks visais atvejais.

Susiejimas laikomas nepatikimu, tada, kai siejimas atliekamas ne patikimo unikalaus identifikatoriaus pagalba, o per pavadinimą ar panašiais būdais.

Pavadinimai gali keistis, gali dubliuotis, gali skirtis jų užrašymo forma, todėl toks jungimas laikomas nepatikimu.

Toks jungimas ir 2 brandos lygio žymėjimas taikomas tik tais atvejais, kai jungimas daromas, per jungiamo modelio atributą. Pavyzdžiui:

d

r

b

m

property

type

ref

level

example

Country

name@lt

4

name@lt

text

4

City

name

4

name@lt

text

4

country

ref

Country

2

Šiuo atveju, kadangi City.country brandos lygis yra 2, tai reiškia, kad City.country duomenys yra realiai paimti iš Country.name@lt. Jei City.country būtų paimti ne iš Country.name@lt, o iš kokio nors kito šaltinio ir gali nesutapti, tada brandos lygis turėtu būti 1.

Tai reiškia, kad 2 brandos lygis žymimas tik tais atvejais, kai išorinis raktas yra paimtas iš siejamo modelio atributo.

Susiejimas ne per pirminį raktą#

Jei ref tipui suteiktas 3 ar didesnis brandos lygis, vadinasi susiejimas yra patikimas. Duomenys siejami naudojant patikimus unikalius identifikatorius, kurie nesidubliuoja, nesikeičia ir užrašomi visada vienodai.

Dažniausiai patikimais identifikatoriais laikomi sveiki skaičiai, tam tikri sutartiniai kodai ir kiti specializuoti identifikatoriai, tokie kaip UUID.

Tačiau, naudojamas ne pirminis raktas, o kitas duomenų laukas. Pavyzdžiui:

d

r

b

m

property

type

ref

level

example

Country

id

4

id

integer

4

code

string

4

name@lt

text

4

City

name

4

name@lt

text

4

country

ref

Country[code]

3

Skirtumas tarp 3 ir 4 brandos lygio iš esmės susijęs su duomenų saugojimu Saugykloje ar kitoje vietoje, kur pirminiai raktai yra generuojami ir jų negalima keisti. Jei naudojamas 3 brandos lygis, tuomet saugykloje saugomas, ne išorinis saugyklos identifikatorius UUID, o vidinis duomenų rinkinio identifikatorius.

Publikuojant duomenis iš tam tikro šaltinio, išorinis raktas visada turėtu būti konvertuojamas į išorinį pirminį raktą, tačiau tais atvejais, jei dėl tam tikrų priežasčių tas nėra daroma, tuomet žymimas 3 brandos lygis ir publikuojami ne išoriniai pirminiai raktai, o šaltinio vidiniai.

Pavyzdžiui, jei turime tokius duomenis:

example/Country

_id

id

code

name@lt

4dbb1b77-a930-4f2a-8ef4-f05b89f0fcfe

1

lt

Lietuva

Ir jei City.country turi brandos lygį 3, tada City duomenys atrodys taip:

example/City

_id

name@lt

country._id

096e054e-7a4c-44cc-8f27-98af815080d5

Vilnius

lt

Susiejimas per pirminį raktą#

Šiuo atveju, brandos lygis žymimas 4 ir skirtumas nuo 3 brandos lygio yra toks, kad duomenyse naudojamas išorinis pirminis raktas. Pavyzdžiui:

d

r

b

m

property

type

ref

level

example

Country

id

4

id

integer

4

code

string

4

name@lt

text

4

City

name

4

name@lt

text

4

country

ref

Country

4

Turint tokį struktūros aprašą, kur City.country brandos lygis yra 4, duomenys atrodys taip:

example/Country

_id

id

code

name@lt

4dbb1b77-a930-4f2a-8ef4-f05b89f0fcfe

1

lt

Lietuva

example/City

_id

name@lt

country._id

096e054e-7a4c-44cc-8f27-98af815080d5

Vilnius

4dbb1b77-a930-4f2a-8ef4-f05b89f0fcfe

Matome, kad City.country._id yra Country pirminis raktas. Tai reiškia, kad vidiniai duomenų rinkinio raktai konvertuojami į išorinius.