Sveiki, draugai. Prieš išvykdami į antrąją gegužės atostogų dalį, dalinamės su jumis medžiaga, kurią išvertėme laukdami naujo kurso srauto pradžios.
Programų kūrėjai praleidžia daug laiko palygindami kelias veikiančias duomenų bazes, kad pasirinktų tą, kuri geriausiai atitinka numatytą darbo krūvį. Gali prireikti supaprastinto duomenų modeliavimo, operacijų garantijų, skaitymo / rašymo našumo, horizontalaus mastelio ir gedimų tolerancijos. Tradiciškai pasirinkimas prasideda nuo duomenų bazės kategorijos, SQL arba NoSQL, nes kiekviena kategorija pateikia aiškų kompromisų rinkinį. Didelis našumas mažo delsos ir didelio pralaidumo požiūriu paprastai laikomas ne kompromisiniu reikalavimu, todėl yra būtinas bet kuriai pavyzdinei duomenų bazei.
Šio straipsnio tikslas yra padėti programų kūrėjams teisingai pasirinkti SQL ir NoSQL taikomųjų programų duomenų modeliavimo kontekste. Apžvelgsime vieną SQL duomenų bazę, būtent PostgreSQL, ir dvi NoSQL duomenų bazes, Cassandra ir MongoDB, kad apimtume duomenų bazės projektavimo pagrindus, tokius kaip lentelių kūrimas, užpildymas, duomenų nuskaitymas iš lentelės ir jų trynimas. Kitame straipsnyje būtinai apžvelgsime indeksus, operacijas, JOIN, TTL direktyvas ir JSON pagrindu sukurtą duomenų bazės dizainą.
Kuo skiriasi SQL ir NoSQL?
SQL duomenų bazės padidina taikomųjų programų lankstumą suteikdamos ACID operacijų garantijas, taip pat jų galimybę netikėtais būdais užklausti duomenis naudojant JOIN, papildant esamus normalizuotus reliacinių duomenų bazių modelius.
Atsižvelgiant į jų monolitinę / vieno mazgo architektūrą ir pagrindinio-pavaldžiojo replikacijos modelio naudojimą atleidimui, tradicinėms SQL duomenų bazėms trūksta dviejų svarbių savybių - linijinio rašymo mastelio (t. y. automatinio skaidymo keliuose mazguose) ir automatinio / nulinio duomenų praradimo. Tai reiškia, kad gaunamų duomenų kiekis negali viršyti didžiausio vieno mazgo rašymo pralaidumo. Be to, reikia atsižvelgti į tam tikrą laikiną duomenų praradimą gedimų tolerancijos srityje (naudojant nieko bendrai naudojamą architektūrą). Čia reikia turėti omenyje, kad paskutiniai įsipareigojimai dar neatsispindėjo verginėje kopijoje. SQL duomenų bazėse taip pat sunku pasiekti atnaujinimus be prastovos.
NoSQL duomenų bazės dažniausiai yra platinamos iš prigimties, t.y. juose duomenys skirstomi į skyrius ir paskirstomi keliuose mazguose. Jie reikalauja denormalizavimo. Tai reiškia, kad įvesti duomenys taip pat turi būti kelis kartus nukopijuoti, kad būtų galima atsakyti į konkrečias jūsų siunčiamas užklausas. Bendras tikslas yra pasiekti aukštą našumą sumažinant skaitymo metu pasiekiamų skeveldrų skaičių. Tai reiškia, kad naudojant NoSQL reikia modeliuoti užklausas, o naudojant SQL – duomenis.
„NoSQL“ daugiausia dėmesio skiria aukštam našumui paskirstytoje klasteryje, ir tai yra daugelio duomenų bazės dizaino kompromisų, įskaitant ACID transakcijų praradimą, JOIN ir nuoseklius pasaulinius antrinius indeksus, pagrindas.
Yra argumentas, kad nors NoSQL duomenų bazės suteikia linijinį rašymo mastelį ir didelį atsparumą gedimams, dėl sandorių garantijų praradimo jos netinkamos svarbiems duomenims.
Šioje lentelėje parodyta, kuo duomenų modeliavimas NoSQL skiriasi nuo SQL.
SQL ir NoSQL: kodėl abu reikalingi?
Realaus pasaulio programoms, turinčioms daug vartotojų, pvz., Amazon.com, Netflix, Uber ir Airbnb, pavesta atlikti sudėtingas, įvairiapuses užduotis. Pavyzdžiui, elektroninės prekybos programoje, pvz., Amazon.com, reikia saugoti lengvus, labai svarbius duomenis, pvz., informaciją apie naudotoją, produktus, užsakymus, sąskaitas faktūras, taip pat sunkius, ne tokius jautrius duomenis, kaip produktų apžvalgos, palaikymo pranešimai, naudotojo veikla, vartotojų atsiliepimai ir rekomendacijos. Žinoma, šios programos remiasi bent viena SQL duomenų baze ir bent viena NoSQL duomenų baze. Tarpregioninėse ir pasaulinėse sistemose NoSQL duomenų bazė veikia kaip geografiškai paskirstyta talpykla duomenims, saugomiems patikimo šaltinio SQL duomenų bazėje, veikiančioje tam tikrame regione.
Kaip YugaByte DB sujungia SQL ir NoSQL?
„YugaByte DB“, sukurta pagal į žurnalą orientuotą mišrios saugyklos variklį, automatinį dalijimąsi, suskaidytą paskirstytą konsensuso replikaciją ir ACID paskirstytas operacijas (įkvėpta „Google Spanner“). SQL (PostgreSQL). Kaip parodyta toliau pateiktoje lentelėje, YCQL, YugaByte DB API, suderinama su Cassandra, prideda vieno ir kelių klavišų ACID operacijų ir visuotinių antrinių indeksų sąvokas prie NoSQL API, taip pradėdamas operacijų NoSQL duomenų bazių erą. Be to, YCQL, YugaByte DB API, suderinama su PostgreSQL, prideda linijinio rašymo mastelio keitimo ir automatinio klaidų tolerancijos sąvokas prie SQL API, todėl pasauliui pristatomos paskirstytos SQL duomenų bazės. Kadangi „YugaByte DB“ yra transakcinio pobūdžio, „NoSQL“ API dabar gali būti naudojama atliekant svarbius duomenis.
Kaip jau minėta straipsnyje
- Jei jūsų pagrindinis darbo krūvis yra kelių klavišų JOIN operacijos, tada rinkdamiesi YSQL supraskite, kad jūsų raktai gali būti paskirstyti keliuose mazguose, todėl delsa ir (arba) pralaidumas yra didesnis nei NoSQL.
- Kitu atveju pasirinkite vieną iš dviejų NoSQL API, turėdami omenyje, kad užklausos bus teikiamos vienu metu iš vieno mazgo. YugaByte DB gali būti viena veikianti duomenų bazė realioms sudėtingoms programoms, kurioms vienu metu reikia valdyti kelis darbo krūvius.
Duomenų modeliavimo laboratorija kitame skyriuje yra pagrįsta PostgreSQL ir Cassandra API suderinamomis YugaByte DB duomenų bazėmis, o ne vietinėmis duomenų bazėmis. Šis metodas pabrėžia sąveikos su dviem skirtingomis API (dviejuose skirtinguose prievaduose) to paties duomenų bazių klasterio paprastumą, o ne naudojant visiškai nepriklausomas dviejų skirtingų duomenų bazių grupes.
Tolesniuose skyriuose apžvelgsime duomenų modeliavimo laboratoriją, kad parodytume nagrinėjamų duomenų bazių skirtumus ir kai kuriuos bendrumus.
Duomenų modeliavimo laboratorija
Duomenų bazės diegimas
Atsižvelgiant į tai, kad akcentuojamas duomenų modelio dizainas (o ne sudėtingos diegimo architektūros), mes įdiegsime duomenų bazes „Docker“ konteineriuose vietiniame kompiuteryje ir sąveikausime su jomis naudodami atitinkamus komandų eilutės apvalkalus.
Su PostgreSQL ir Cassandra suderinama YugaByte DB duomenų bazė
mkdir ~/yugabyte && cd ~/yugabyte
wget https://downloads.yugabyte.com/yb-docker-ctl && chmod +x yb-docker-ctl
docker pull yugabytedb/yugabyte
./yb-docker-ctl create --enable_postgres
MongoDB
docker run --name my-mongo -d mongo:latest
Prieiga prie komandų eilutės
Prisijunkite prie duomenų bazių naudodami atitinkamų API komandinės eilutės apvalkalą.
PostgreSQL
docker exec -it yb-postgres-n1 /home/yugabyte/postgres/bin/psql -p 5433 -U postgres
Kasandra
cqlsh
kataloge bin
.
Atminkite, kad CQL įkvėpė SQL ir turi panašias lentelių, eilučių, stulpelių ir indeksų koncepcijas. Tačiau, kaip NoSQL kalba, ji prideda tam tikrų apribojimų, kurių daugumą apžvelgsime ir kituose straipsniuose.
docker exec -it yb-tserver-n1 /home/yugabyte/bin/cqlsh
MongoDB
docker exec -it my-mongo bash
cd bin
mongo
Sukurkite lentelę
Dabar galime sąveikauti su duomenų baze ir atlikti įvairias operacijas naudodami komandinę eilutę. Pradėkime nuo lentelės, kurioje saugoma informacija apie skirtingų atlikėjų parašytas dainas. Šios dainos gali būti albumo dalis. Taip pat pasirenkami dainos atributai yra išleidimo metai, kaina, žanras ir įvertinimas. Turime atsižvelgti į papildomus atributus, kurių gali prireikti ateityje, naudodami lauką „žymos“. Jis gali saugoti pusiau struktūrinius duomenis raktų ir reikšmių porų pavidalu.
PostgreSQL
CREATE TABLE Music (
Artist VARCHAR(20) NOT NULL,
SongTitle VARCHAR(30) NOT NULL,
AlbumTitle VARCHAR(25),
Year INT,
Price FLOAT,
Genre VARCHAR(10),
CriticRating FLOAT,
Tags TEXT,
PRIMARY KEY(Artist, SongTitle)
);
Kasandra
Lentelės kūrimas Cassandra yra labai panašus į PostgreSQL. Vienas iš pagrindinių skirtumų yra vientisumo apribojimų nebuvimas (pvz., NOT NULL), tačiau tai yra programos, o ne NoSQL duomenų bazės atsakomybė.. Pirminį raktą sudaro skaidinio raktas (toliau pateiktame pavyzdyje stulpelis Atlikėjas) ir grupavimo stulpelių rinkinys (toliau pateiktame pavyzdyje stulpelis Dainos pavadinimas). Padalinio raktas nustato, į kurį skaidinį / skiltį reikia įdėti į eilutę, o grupavimo stulpeliai nurodo, kaip duomenys turi būti tvarkomi dabartinėje skiltyje.
CREATE KEYSPACE myapp;
USE myapp;
CREATE TABLE Music (
Artist TEXT,
SongTitle TEXT,
AlbumTitle TEXT,
Year INT,
Price FLOAT,
Genre TEXT,
CriticRating FLOAT,
Tags TEXT,
PRIMARY KEY(Artist, SongTitle)
);
MongoDB
„MongoDB“ tvarko duomenis į duomenų bazes (duomenų bazę) (panašiai kaip „Keyspace“ Cassandroje), kur yra rinkiniai (panašūs į lenteles), kuriuose yra dokumentai (panašūs į lentelės eilutes). MongoDB iš esmės nereikia apibrėžti pradinės schemos. Komanda "naudoti duomenų bazę", parodyta toliau, sukuria duomenų bazę pirmojo skambučio metu ir pakeičia naujai sukurtos duomenų bazės kontekstą. Net kolekcijų nereikia kurti aiškiai, jos sukuriamos automatiškai, tiesiog pridedate pirmąjį dokumentą prie naujos kolekcijos. Atminkite, kad „MongoDB“ pagal numatytuosius nustatymus naudoja bandomąją duomenų bazę, todėl bet kokia rinkinio lygio operacija, nenurodant konkrečios duomenų bazės, bus vykdoma pagal numatytuosius nustatymus.
use myNewDatabase;
Informacijos apie lentelę gavimas
PostgreSQL
d Music
Table "public.music"
Column | Type | Collation | Nullable | Default
--------------+-----------------------+-----------+----------+--------
artist | character varying(20) | | not null |
songtitle | character varying(30) | | not null |
albumtitle | character varying(25) | | |
year | integer | | |
price | double precision | | |
genre | character varying(10) | | |
criticrating | double precision | | |
tags | text | | |
Indexes:
"music_pkey" PRIMARY KEY, btree (artist, songtitle)
Kasandra
DESCRIBE TABLE MUSIC;
CREATE TABLE myapp.music (
artist text,
songtitle text,
albumtitle text,
year int,
price float,
genre text,
tags text,
PRIMARY KEY (artist, songtitle)
) WITH CLUSTERING ORDER BY (songtitle ASC)
AND default_time_to_live = 0
AND transactions = {'enabled': 'false'};
MongoDB
use myNewDatabase;
show collections;
Duomenų įvedimas į lentelę
PostgreSQL
INSERT INTO Music
(Artist, SongTitle, AlbumTitle,
Year, Price, Genre, CriticRating,
Tags)
VALUES(
'No One You Know', 'Call Me Today', 'Somewhat Famous',
2015, 2.14, 'Country', 7.8,
'{"Composers": ["Smith", "Jones", "Davis"],"LengthInSeconds": 214}'
);
INSERT INTO Music
(Artist, SongTitle, AlbumTitle,
Price, Genre, CriticRating)
VALUES(
'No One You Know', 'My Dog Spot', 'Hey Now',
1.98, 'Country', 8.4
);
INSERT INTO Music
(Artist, SongTitle, AlbumTitle,
Price, Genre)
VALUES(
'The Acme Band', 'Look Out, World', 'The Buck Starts Here',
0.99, 'Rock'
);
INSERT INTO Music
(Artist, SongTitle, AlbumTitle,
Price, Genre,
Tags)
VALUES(
'The Acme Band', 'Still In Love', 'The Buck Starts Here',
2.47, 'Rock',
'{"radioStationsPlaying": ["KHCR", "KBQX", "WTNR", "WJJH"], "tourDates": { "Seattle": "20150625", "Cleveland": "20150630"}, "rotation": Heavy}'
);
Kasandra
Bendra išraiška INSERT
Cassandra atrodo labai panašiai kaip PostgreSQL. Tačiau yra vienas didelis semantikos skirtumas. Kasandroje INSERT
iš tikrųjų yra operacija UPSERT
, kur paskutinės reikšmės pridedamos prie eilutės, jei eilutė jau yra.
Duomenų įvedimas panašus į PostgreSQL
INSERT
virš
.
MongoDB
Nors „MongoDB“ yra „NoSQL“ duomenų bazė, tokia kaip „Cassandra“, jos įterpimo operacija neturi nieko bendra su „Cassandra“ semantine elgsena. MongoDB UPSERT
, todėl jis panašus į PostgreSQL. Pridedami numatytieji duomenys be _idspecified
Prie kolekcijos bus pridėtas naujas dokumentas.
db.music.insert( {
artist: "No One You Know",
songTitle: "Call Me Today",
albumTitle: "Somewhat Famous",
year: 2015,
price: 2.14,
genre: "Country",
tags: {
Composers: ["Smith", "Jones", "Davis"],
LengthInSeconds: 214
}
}
);
db.music.insert( {
artist: "No One You Know",
songTitle: "My Dog Spot",
albumTitle: "Hey Now",
price: 1.98,
genre: "Country",
criticRating: 8.4
}
);
db.music.insert( {
artist: "The Acme Band",
songTitle: "Look Out, World",
albumTitle:"The Buck Starts Here",
price: 0.99,
genre: "Rock"
}
);
db.music.insert( {
artist: "The Acme Band",
songTitle: "Still In Love",
albumTitle:"The Buck Starts Here",
price: 2.47,
genre: "Rock",
tags: {
radioStationsPlaying:["KHCR", "KBQX", "WTNR", "WJJH"],
tourDates: {
Seattle: "20150625",
Cleveland: "20150630"
},
rotation: "Heavy"
}
}
);
Lentelės užklausa
Bene reikšmingiausias skirtumas tarp SQL ir NoSQL užklausų kūrimo požiūriu yra vartojama kalba FROM
и WHERE
. SQL leidžia po išraiškos FROM
pasirinkite kelias lenteles ir išraišką su WHERE
gali būti bet kokio sudėtingumo (įskaitant operacijas JOIN
tarp lentelių). Tačiau NoSQL linkęs nustatyti griežtus apribojimus FROM
, ir dirbti tik su viena nurodyta lentele, ir in WHERE
, visada turi būti nurodytas pirminis raktas. Tai susiję su NoSQL našumo postūmiu, apie kurį kalbėjome anksčiau. Dėl šio troškimo kiek įmanoma sumažinama bet kokia sąveika tarp lentelių ir raktų. Atsakant į užklausą tai gali sukelti didelį mazgų komunikacijos vėlavimą, todėl apskritai geriausia to vengti. Pavyzdžiui, Cassandra reikalauja, kad užklausos būtų apribotos tam tikrais operatoriais (tik =, IN, <, >, =>, <=
) skirsnių raktuose, išskyrus atvejus, kai prašoma antrinio indekso (čia leidžiamas tik operatorius =).
PostgreSQL
Žemiau pateikiami trys užklausų, kurias gali lengvai vykdyti SQL duomenų bazė, pavyzdžiai.
- Rodyti visas atlikėjo dainas;
- Rodyti visas atlikėjo dainas, atitinkančias pirmąją pavadinimo dalį;
- Rodyti visas atlikėjo dainas, kurių pavadinime yra tam tikras žodis ir kurių kaina mažesnė nei 1.00.
SELECT * FROM Music
WHERE Artist='No One You Know';
SELECT * FROM Music
WHERE Artist='No One You Know' AND SongTitle LIKE 'Call%';
SELECT * FROM Music
WHERE Artist='No One You Know' AND SongTitle LIKE '%Today%'
AND Price > 1.00;
Kasandra
Iš aukščiau išvardytų PostgreSQL užklausų tik pirmoji veiks nepakitusi Cassandra, nes operatorius LIKE
negali būti taikomas grupavimo stulpeliams, pvz., SongTitle
. Šiuo atveju leidžiami tik operatoriai =
и IN
.
SELECT * FROM Music
WHERE Artist='No One You Know';
SELECT * FROM Music
WHERE Artist='No One You Know' AND SongTitle IN ('Call Me Today', 'My Dog Spot')
AND Price > 1.00;
MongoDB
Kaip parodyta ankstesniuose pavyzdžiuose, pagrindinis užklausų kūrimo metodas MongoDB yra music
toliau pateiktame pavyzdyje), todėl užklausos keliuose rinkiniuose draudžiama.
db.music.find( {
artist: "No One You Know"
}
);
db.music.find( {
artist: "No One You Know",
songTitle: /Call/
}
);
Visų lentelės eilučių skaitymas
Visų eilučių skaitymas yra tiesiog ypatingas užklausos modelio, kurį žiūrėjome anksčiau, atvejis.
PostgreSQL
SELECT *
FROM Music;
Kasandra
Panašus į aukščiau pateiktą PostgreSQL pavyzdį.
MongoDB
db.music.find( {} );
Duomenų redagavimas lentelėje
PostgreSQL
PostgreSQL pateikia instrukcijas UPDATE
keisti duomenis. Ji neturi galimybių UPSERT
, todėl šis teiginys nepavyks, jei eilutės nebebus duomenų bazėje.
UPDATE Music
SET Genre = 'Disco'
WHERE Artist = 'The Acme Band' AND SongTitle = 'Still In Love';
Kasandra
Kasandra turi UPDATE
panašus į PostgreSQL. UPDATE
turi tą pačią semantiką UPSERT
, panašus INSERT
.
Panašus į aukščiau pateiktą PostgreSQL pavyzdį.
MongoDB
Operacija UPSERT
. Kelių dokumentų atnaujinimas ir panašus elgesys UPSERT
galima pritaikyti nustatant papildomas operacijos vėliavėles. Pavyzdžiui, toliau pateiktame pavyzdyje konkretaus atlikėjo žanras atnaujinamas pagal jo dainą.
db.music.update(
{"artist": "The Acme Band"},
{
$set: {
"genre": "Disco"
}
},
{"multi": true, "upsert": true}
);
Duomenų pašalinimas iš lentelės
PostgreSQL
DELETE FROM Music
WHERE Artist = 'The Acme Band' AND SongTitle = 'Look Out, World';
Kasandra
Panašus į aukščiau pateiktą PostgreSQL pavyzdį.
MongoDB
„MongoDB“ turi dviejų tipų operacijas, skirtas ištrinti dokumentus
db.music.deleteMany( {
artist: "The Acme Band"
}
);
Lentelės ištrynimas
PostgreSQL
DROP TABLE Music;
Kasandra
Panašus į aukščiau pateiktą PostgreSQL pavyzdį.
MongoDB
db.music.drop();
išvada
Diskusijos apie pasirinkimą tarp SQL ir NoSQL tęsiasi daugiau nei 10 metų. Yra du pagrindiniai šios diskusijos aspektai: duomenų bazės variklio architektūra (monolitinė, transakcinė SQL ir paskirstyta, neoperacinė NoSQL) ir duomenų bazės projektavimo metodas (duomenų modeliavimas SQL ir užklausų modeliavimas NoSQL).
Naudojant paskirstytą operacijų duomenų bazę, pvz., YugaByte DB, diskusijas apie duomenų bazės architektūrą galima lengvai sustabdyti. Kadangi duomenų apimtys tampa didesnės nei galima įrašyti į vieną mazgą, tampa būtina visiškai paskirstyta architektūra, palaikanti linijinį rašymo mastelį ir automatinį skaidymą / perbalansavimą.
Be to, kaip teigiama viename iš straipsnių
Grįžtant prie diskusijos apie duomenų bazės dizainą, teisinga pasakyti, kad bet kuriai sudėtingai realaus pasaulio programai būtini abu projektavimo metodai (SQL ir NoSQL). SQL „duomenų modeliavimo“ metodas leidžia kūrėjams lengviau patenkinti kintančius verslo reikalavimus, o NoSQL „užklausų modeliavimo“ metodas leidžia tiems patiems kūrėjams valdyti didelius duomenų kiekius su maža delsa ir dideliu pralaidumu. Būtent dėl šios priežasties YugaByte DB teikia SQL ir NoSQL API bendrame branduolyje, o ne reklamuoja vieną iš būdų. Be to, suteikdama suderinamumą su populiariomis duomenų bazių kalbomis, įskaitant PostgreSQL ir Cassandra, YugaByte DB užtikrina, kad kūrėjams nereikėtų mokytis kitos kalbos, kad galėtų dirbti su paskirstytu, labai nuosekliu duomenų bazės varikliu.
Šiame straipsnyje apžvelgėme, kaip duomenų bazių projektavimo pagrindai skiriasi tarp PostgreSQL, Cassandra ir MongoDB. Būsimuose straipsniuose pasinersime į išplėstines dizaino koncepcijas, tokias kaip indeksai, operacijos, JOIN, TTL direktyvos ir JSON dokumentai.
Linkime puikaus poilsio savaitgalio ir kviečiame
Šaltinis: www.habr.com