Здраво пријатели. Пред да тргнеме во вториот дел од мајските празници, го споделуваме со вас материјалот што го преведовме во пресрет на лансирањето на нов стрим на курсот
Програмерите на апликации трошат многу време споредувајќи повеќе оперативни бази на податоци за да ја изберат онаа што најдобро одговара на предвидениот обем на работа. Потребите може да вклучуваат поедноставено моделирање на податоци, трансакциски гаранции, перформанси за читање/запишување, хоризонтално скалирање и толеранција на грешки. Традиционално, изборот започнува со категоријата на базата на податоци, SQL или NoSQL, бидејќи секоја категорија претставува јасен сет на компромиси. Високите перформанси во смисла на ниска латентност и висока пропусност генерално се гледаат како услов што не се разменува и затоа е од суштинско значење за секоја база на податоци за примероци.
Целта на овој напис е да им помогне на развивачите на апликации да го направат вистинскиот избор помеѓу SQL и NoSQL во контекст на моделирање на податоци за апликации. Ќе погледнеме една SQL база на податоци, имено PostgreSQL, и две NoSQL бази на податоци, Cassandra и MongoDB, за да ги покриеме основите на дизајнот на базата на податоци, како што се создавање табели, нивно пополнување, читање податоци од табела и нивно бришење. Во следната статија, сигурно ќе ги разгледаме индексите, трансакциите, JOIN-овите, TTL директивите и дизајнот на базата на податоци базиран на JSON.
Која е разликата помеѓу SQL и NoSQL?
Базите на податоци на SQL ја зголемуваат флексибилноста на апликацијата преку ACID трансакциски гаранции, како и нивната способност да бараат податоци користејќи JOIN на неочекувани начини, покрај постоечките нормализирани модели на релациона база на податоци.
Со оглед на нивната монолитна/еден-јазол архитектура и употребата на модел за репликација на master-slave за вишок, на традиционалните SQL бази на податоци им недостасуваат две важни карактеристики - линеарна приспособливост за пишување (т.е. автоматско партиционирање низ повеќе јазли) и автоматско/нула загуба на податоци. Ова значи дека количината на добиени податоци не може да го надмине максималниот проток на запишување на еден јазол. Дополнително, некои привремени загуби на податоци мора да се земат предвид при толеранцијата на грешки (во архитектурата што нема ништо). Овде треба да имате на ум дека неодамнешните обврски сè уште не се рефлектирани во робната копија. Ажурирањата без прекини, исто така, тешко се постигнуваат во базите на податоци на SQL.
NoSQL базите на податоци обично се дистрибуираат по природа, т.е. во нив податоците се поделени на делови и дистрибуирани низ неколку јазли. Тие бараат денормализација. Ова значи дека внесените податоци исто така мора да се копираат неколку пати за да се одговори на конкретните барања што ги испраќате. Општата цел е да се добијат високи перформанси со намалување на бројот на достапни парчиња за време на читањето. Ова имплицира дека NoSQL бара од вас да ги моделирате вашите барања, додека SQL бара од вас да ги моделирате вашите податоци.
NoSQL се фокусира на постигнување високи перформанси во дистрибуиран кластер и ова е основната причина за многу компромиси во дизајнот на базата на податоци кои вклучуваат загуба на трансакции со ACID, JOIN и конзистентни глобални секундарни индекси.
Постои аргумент дека додека NoSQL базите на податоци обезбедуваат линеарна приспособливост за пишување и висока толеранција на грешки, губењето на трансакциските гаранции ги прави несоодветни за критичните податоци за мисијата.
Следната табела покажува како моделирањето на податоци во NoSQL се разликува од SQL.
SQL и NoSQL: Зошто се потребни и двете?
Апликациите од реалниот свет со голем број корисници, како што се Amazon.com, Netflix, Uber и Airbnb, имаат задача да извршуваат сложени, повеќеслојни задачи. На пример, апликација за е-трговија како Amazon.com треба да складира лесни, висококритични податоци како што се кориснички информации, производи, нарачки, фактури, заедно со тешки, помалку чувствителни податоци како што се прегледи на производи, пораки за поддршка, корисничка активност, прегледи и препораки од корисниците. Секако, овие апликации се потпираат на барем една база на податоци SQL заедно со најмалку една база на податоци NoSQL. Во меѓурегионалните и глобалните системи, базата на податоци NoSQL работи како гео-дистрибуирана кеш за податоци складирани во доверлив извор SQL база на податоци што работи во одреден регион.
Како YugaByte DB комбинира SQL и NoSQL?
Изграден на мешан мотор за складирање ориентиран кон дневник, автоматско споделување, разделена дистрибуирана репликација на консензус и ACID дистрибуирани трансакции (инспирирани од Google Spanner), YugaByte DB е првата база на податоци со отворен код во светот која е истовремено компатибилна со NoSQL (Cassandra & Redis ) и SQL (PostgreSQL). Како што е прикажано во табелата подолу, YCQL, YugaByte DB API компатибилен со Cassandra, ги додава концептите на ACID трансакции со еден и повеќекратен клуч и глобални секундарни индекси на NoSQL API, со што ја воведува ерата на трансакциските NoSQL бази на податоци. Дополнително, YCQL, YugaByte DB API компатибилен со PostgreSQL, ги додава концептите за линеарно скалирање на запишување и автоматска толеранција на грешки во SQL API, со што ќе се донесат дистрибуирани SQL бази на податоци во светот. Бидејќи YugaByte DB е трансакциска по природа, NoSQL API сега може да се користи во контекст на критични податоци за мисијата.
Како што беше претходно наведено во статијата
- Ако вашиот примарен обем на работа се операциите JOIN со повеќе клучеви, тогаш кога избирате YSQL, разберете дека вашите клучеви може да се дистрибуираат низ повеќе јазли, што резултира со поголема латентност и/или помала пропусност од NoSQL.
- Во спротивно, изберете кое било од двете NoSQL API, имајќи на ум дека ќе добиете подобри перформанси како резултат на прашања сервирани од еден јазол во исто време. YugaByte DB може да служи како единствена оперативна база на податоци за реални, сложени апликации кои треба да управуваат со повеќе оптоварувања истовремено.
Лабораторијата за моделирање податоци во следниот дел се заснова на базите на податоци на YugaByte DB компатибилни со PostgreSQL и Cassandra API, наспроти матичните бази на податоци. Овој пристап ја нагласува леснотијата на интеракција со две различни API (на две различни порти) од истиот кластер на бази на податоци, наспроти користењето на целосно независни кластери од две различни бази на податоци.
Во следните делови, ќе ја разгледаме лабораторијата за моделирање податоци за да ги илустрираме разликите и некои од заедничките карактеристики на опфатените бази на податоци.
Лабораторија за моделирање податоци
Инсталација на база на податоци
Со оглед на акцентот на дизајнот на моделот на податоци (наместо сложените архитектури за распоредување), ќе инсталираме бази на податоци во контејнерите на Docker на локалната машина и потоа ќе комуницираме со нив користејќи ги нивните соодветни школки на командната линија.
PostgreSQL и Cassandra компатибилна со YugaByte DB база на податоци
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
Пристап до командната линија
Ајде да се поврземе со базите на податоци користејќи ја обвивката на командната линија за соодветните API.
PostgreSQL
docker exec -it yb-postgres-n1 /home/yugabyte/postgres/bin/psql -p 5433 -U postgres
Касандра
cqlsh
во каталогот bin
.
Забележете дека CQL е инспириран од SQL и има слични концепти на табели, редови, колони и индекси. Сепак, како јазик NoSQL, додава одреден сет на ограничувања, од кои повеќето ќе ги опфатиме и во други статии.
docker exec -it yb-tserver-n1 /home/yugabyte/bin/cqlsh
MongoDB
docker exec -it my-mongo bash
cd bin
mongo
Направете табела
Сега можеме да комуницираме со базата на податоци за да извршиме различни операции користејќи ја командната линија. Да почнеме со креирање табела која чува информации за песни напишани од различни изведувачи. Овие песни може да бидат дел од албум. Исто така, изборните атрибути за песна се година на издавање, цена, жанр и оцена. Треба да земеме сметка за дополнителни атрибути кои можеби ќе бидат потребни во иднина преку полето „ознаки“. Може да складира полуструктурирани податоци во форма на парови клуч-вредност.
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)
);
Касандра
Креирањето табела во Касандра е многу слично на PostgreSQL. Една од главните разлики е недостатокот на ограничувања за интегритет (на пример, NOT NULL), но ова е одговорност на апликацијата, а не на базата на податоци NoSQL. Примарниот клуч се состои од клуч за партиција (колоната Artist во примерот подолу) и збир на колони за групирање (колоната SongTitle во примерот подолу). Копчето за партиција одредува во која партиција/парче треба да се смести редот, а колоните за групирање покажуваат како податоците треба да се организираат во тековниот фрагмент.
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 организира податоци во бази на податоци (База на податоци) (слично на Keyspace во Касандра), каде што има Колекции (слично на табелите) кои содржат Документи (слично на редовите во табелата). Во MongoDB, во основа нема потреба да се дефинира почетна шема. Тим "користи база на податоци", прикажано подолу, ја инстанцира базата на податоци при првиот повик и го менува контекстот за новосоздадената база на податоци. Дури и збирките не треба да се креираат експлицитно; тие се создаваат автоматски, едноставно кога ќе го додадете првиот документ во нова колекција. Забележете дека MongoDB стандардно ја користи тест базата, така што секоја операција на ниво на колекција без да наведе одредена база на податоци ќе се извршува на неа стандардно.
use myNewDatabase;
Добивање информации за табела
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)
Касандра
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;
Внесување податоци во табела
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}'
);
Касандра
Севкупен израз INSERT
во Касандра изгледа многу слично на она во PostgreSQL. Сепак, постои една голема разлика во семантиката. Во Касандра INSERT
всушност е операција UPSERT
, каде што последните вредности се додаваат на редот ако редот веќе постои.
Внесувањето податоци е слично на PostgreSQL
INSERT
над
.
MongoDB
Иако MongoDB е NoSQL база на податоци како Касандра, нејзината операција за вметнување нема ништо заедничко со семантичкото однесување на Касандра. Во MongoDB UPSERT
, што го прави сличен на PostgreSQL. Додавање стандардни податоци без _idspecified
ќе предизвика да се додаде нов документ во колекцијата.
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"
}
}
);
Барање за табела
Можеби најзначајната разлика помеѓу SQL и NoSQL во однос на конструкцијата на барањето е јазикот што се користи FROM
и WHERE
. SQL дозволува по изразување FROM
изберете повеќе табели и изразување со WHERE
може да биде од секаква сложеност (вклучувајќи операции JOIN
помеѓу табелите). Сепак, NoSQL има тенденција да наметне сериозно ограничување FROM
, и работи само со една одредена табела, и во WHERE
, примарниот клуч мора секогаш да биде наведен. Ова се поврзува со притисокот за изведба на NoSQL за кој зборувавме претходно. Оваа желба води до секое можно намалување на секоја вкрстена табеларна и вкрстена интеракција. Може да внесе големо доцнење во комуникацијата меѓу јазлите кога одговара на барање и затоа најдобро е да се избегнува воопшто. На пример, Касандра бара барањата да бидат ограничени на одредени оператори (само =, IN, <, >, =>, <=
) на копчињата за партиција, освен кога се бара секундарен индекс (тука е дозволен само операторот =).
PostgreSQL
Подолу се дадени три примери на прашања кои лесно може да се извршат од базата на податоци SQL.
- Прикажи ги сите песни од изведувач;
- Прикажи ги сите песни од изведувачот што одговараат на првиот дел од насловот;
- Прикажи ги сите песни од изведувач кои имаат одреден збор во насловот и имаат цена помала од 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;
Касандра
Од прашањата PostgreSQL наведени погоре, само првото ќе работи непроменето во Касандра, бидејќи операторот LIKE
не може да се примени на колони за групирање како на пр SongTitle
. Во овој случај, дозволени се само оператори =
и 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
Како што е прикажано во претходните примери, главниот метод за креирање прашања во MongoDB е music
во примерот подолу), така што е забрането барање повеќе збирки.
db.music.find( {
artist: "No One You Know"
}
);
db.music.find( {
artist: "No One You Know",
songTitle: /Call/
}
);
Читање на сите редови од табелата
Читањето на сите редови е едноставно посебен случај на шемата за барање што ја разгледавме претходно.
PostgreSQL
SELECT *
FROM Music;
Касандра
Слично на примерот PostgreSQL погоре.
MongoDB
db.music.find( {} );
Уредување податоци во табела
PostgreSQL
PostgreSQL дава инструкции UPDATE
за промена на податоци. Таа нема можности UPSERT
, па оваа изјава нема да успее ако редот повеќе не е во базата на податоци.
UPDATE Music
SET Genre = 'Disco'
WHERE Artist = 'The Acme Band' AND SongTitle = 'Still In Love';
Касандра
Касандра има UPDATE
слично на PostgreSQL. UPDATE
ја има истата семантика UPSERT
, слично INSERT
.
Слично на примерот PostgreSQL погоре.
MongoDB
Операција UPSERT
. Ажурирање на повеќе документи и слично однесување UPSERT
може да се примени со поставување дополнителни знаменца за операцијата. На пример, во примерот подолу, жанрот на одреден изведувач се ажурира врз основа на неговата песна.
db.music.update(
{"artist": "The Acme Band"},
{
$set: {
"genre": "Disco"
}
},
{"multi": true, "upsert": true}
);
Отстранување податоци од табела
PostgreSQL
DELETE FROM Music
WHERE Artist = 'The Acme Band' AND SongTitle = 'Look Out, World';
Касандра
Слично на примерот PostgreSQL погоре.
MongoDB
MongoDB има два типа на операции за бришење документи -
db.music.deleteMany( {
artist: "The Acme Band"
}
);
Избришете табела
PostgreSQL
DROP TABLE Music;
Касандра
Слично на примерот PostgreSQL погоре.
MongoDB
db.music.drop();
Заклучок
Дебатата за избор помеѓу SQL и NoSQL беснее повеќе од 10 години. Постојат два главни аспекти на оваа дебата: архитектура на мотори за бази на податоци (монолитна, трансакциска SQL наспроти дистрибуирана, нетрансакциска NoSQL) и пристап на дизајнирање на базата на податоци (моделирање на вашите податоци во SQL наспроти моделирање на вашите барања во NoSQL).
Со дистрибуирана трансакциска база на податоци како YugaByte DB, дебатата за архитектурата на базата на податоци може лесно да се стави крај. Како што обемот на податоци станува поголем од она што може да се запише на еден јазол, станува неопходна целосно дистрибуирана архитектура која поддржува линеарна приспособливост за запишување со автоматско сечење/ребалансирање.
Освен тоа, како што е наведено во еден од написите
Навраќајќи се на дискусијата за дизајн на базата на податоци, фер е да се каже дека и двата пристапи за дизајн (SQL и NoSQL) се неопходни за секоја сложена апликација од реалниот свет. Пристапот за „моделирање на податоци“ на SQL им овозможува на програмерите полесно да ги исполнат променливите деловни барања, додека пристапот на NoSQL „моделирање на податоци“ им овозможува на истите програмери да работат на големи количини на податоци со мала латентност и висока пропусност. Токму поради оваа причина YugaByte DB обезбедува SQL и NoSQL API во заедничко јадро, наместо да промовира еден од пристапите. Дополнително, со обезбедување на компатибилност со популарните јазици на бази на податоци, вклучувајќи ги PostgreSQL и Cassandra, YugaByte DB гарантира дека програмерите не мора да учат друг јазик за да работат со дистрибуиран, високо конзистентен мотор на бази на податоци.
Во оваа статија, разгледавме како основите на дизајнот на базата на податоци се разликуваат помеѓу PostgreSQL, Cassandra и MongoDB. Во идните статии, ќе се нурнеме во напредни концепти за дизајн како што се индекси, трансакции, ПРИКЛУЧУВАЊА, TTL директиви и документи JSON.
Ви посакуваме убав одмор од викендот и ве покануваме
Извор: www.habr.com