Hej vÀnner. Innan vi gÄr in i den andra delen av majhelgerna delar vi med oss av material som vi har översatt inför lanseringen av den nya kursen. .

Apputvecklare lÀgger ner mycket tid pÄ att jÀmföra flera olika operativa databaser för att vÀlja den som passar bÀst för den planerade arbetsbelastningen. Behoven kan inkludera förenklad datamodellering, transaktionsgarantier, lÀs-/skrivprestanda, horisontell skalbarhet och fel tolerans. Traditionellt börjar valet med kategorin databas, SQL eller NoSQL, eftersom varje kategori erbjuder en tydlig uppsÀttning kompromisser. Hög prestanda nÀr det gÀller lÄg latens och hög genomströmning betraktas vanligtvis som ett krav utan kompromisser och Àr dÀrför nödvÀndigt för varje databas i urvalet.
Syftet med denna artikel Ă€r att hjĂ€lpa apputvecklare att göra rĂ€tt val mellan SQL och NoSQL i kontexten av applikationsdatamodellering. Vi kommer att titta pĂ„ en SQL databas, nĂ€mligen PostgreSQL, och tvĂ„ NoSQL databaser â Cassandra och MongoDB, för att berĂ€tta om grunderna i databasdesign, sĂ„som att skapa tabeller, fylla dem, lĂ€sa data frĂ„n tabeller och ta bort data. I nĂ€sta artikel kommer vi att titta pĂ„ index, transaktioner, JOINs, TTL-direktiv och databasdesign baserat pĂ„ JSON.
Vad Àr skillnaden mellan SQL och NoSQL?
SQL-databaser ökar applikationens flexibilitet genom ACID-transaktionsgarantier och deras förmÄga att hÀmta data med JOIN pÄ ovÀntade sÀtt ovanpÄ befintliga normaliserade modeller av relationsdatabaser.
Med tanke pÄ deras monolitiska/en-nodstruktur och anvÀndning av master-slave-replikationsmodellen för redundans har traditionella SQL-databaser inte tvÄ viktiga egenskaper - linjÀr skrivskalerbarhet (d.v.s. automatisk splittring pÄ flera noder) och automatisk/ingen datarförlust. Det betyder att mÀngden mottagna data inte kan överskrida den maximala skrivgenomströmningen för en nod. Dessutom mÄste viss tillfÀllig datarförlust beaktas vid felhantering (i arkitekturer utan resursdelning). HÀr mÄste vi komma ihÄg att nyliga commits Ànnu inte har Äterspeglats i den underordnade (slave) kopian. Uppdateringar utan driftstopp Àr ocksÄ svÄra att uppnÄ i SQL-databaser.
NoSQL-databaser Àr i sin natur vanligtvis distribuerade, vilket innebÀr att data delas upp i sektioner och sprids över flera noder. De krÀver denormalisering. Det innebÀr att inskickade data ocksÄ mÄste kopieras flera gÄnger för att svara pÄ specifika förfrÄgningar som du skickar. Det övergripande mÄlet Àr att uppnÄ hög prestanda genom att minska antalet shards som Àr tillgÀngliga under lÀsning. DÀrför Àr det viktigt att pÄpeka att NoSQL krÀver att du modellerar dina förfrÄgningar, medan SQL krÀver att du modellerar dina data.
NoSQL fokuserar pÄ att uppnÄ hög prestanda i en distribuerad kluster och det Àr den grundlÀggande motiveringen för mÄnga designkompromisser i databaser, som inkluderar förlust av ACID-transaktionsgarantier, JOIN:ar och konsekventa globala sekundÀra index.
Det finns en uppfattning att Àven om NoSQL-databaser erbjuder linjÀr skrivskalerbarhet och hög felhantering, gör förlusten av transaktionsgarantier dem olÀmpliga för kritiska data.
Följande tabell visar hur datamodellering i NoSQL skiljer sig frÄn SQL.

SQL och NoSQL: Varför behöver vi bÄda?
I verkliga applikationer med ett stort antal anvÀndare, som Amazon.com, Netflix, Uber och Airbnb, faller genomförandet av komplexa och olika uppgifter. Till exempel behöver en e-handelsapplikation liknande Amazon.com lagra lÀtta, högkÀnsliga uppgifter, sÄsom anvÀndarinformation, produktinformation, bestÀllningar, fakturor, tillsammans med tyngre, men mindre kÀnsliga uppgifter, som produktrecensioner, kundsupportmeddelanden, anvÀndaraktivitet, feedback och rekommendationer. Naturligtvis litar dessa applikationer pÄ Ätminstone en SQL-databas tillsammans med minst en NoSQL-databas. I interregionala och globala system fungerar NoSQL-databasen som en geografiskt distribuerad cache för data som lagras i en betrodd kÀlla, SQL-databasen som körs i en viss region.
Hur förenar YugaByte DB SQL och NoSQL?
Byggd pÄ en loggorienterad blandmotor för lagring, automatisk sharding, sharddistribution och ACID-distribuerad Consensus-replikerings- och distribuerade transaktioner (inspirerade av Google Spanner), Àr YugaByte DB den första open-source databasen i vÀrlden som Àr samtidigt kompatibel med NoSQL (Cassandra & Redis) och SQL (PostgreSQL). Som det visas i tabellen nedan, lÀgger YCQL, YugaByte DB:s Cassandra-kompatibla API, till begrepp av en- och flernyckel ACID-transaktioner och globala sekundÀra index i NoSQL API:t, vilket öppnar en era av transaktionella NoSQL-databaser. Dessutom lÀgger YCQL, YugaByte DB:s PostgreSQL-kompatibla API, till begrepp för linjÀr skrivskaling och automatisk felsÀkerhet till SQL API:t, och presenterar för vÀrlden distribuerade SQL-databaser. Eftersom YugaByte DB i grunden Àr transaktionell, kan NoSQL-API:t nu anvÀndas i kontexten av kritiskt viktiga data.

Som nÀmnts tidigare i artikeln , valet mellan SQL eller NoSQL i YugaByte DB beror helt pÄ egenskaperna hos den underliggande arbetsbelastningen:
- Om den underliggande arbetsbelastningen bestÄr av flernyckeloperationer med JOIN:ar, vÀlj YSQL och förstÄ att dina nycklar kan vara spridda över flera noder, vilket kommer att resultera i högre latens och/eller minskad genomströmning Àn i NoSQL.
- Annars kan du vÀlja nÄgot av de tvÄ NoSQL-API:erna, med vetskap om att du kommer att fÄ högre prestanda som ett resultat av förfrÄgningar som hanteras av en nod Ät gÄngen. YugaByte DB kan fungera som en enda operativ databas för verkligt komplexa applikationer dÀr det behövs hantering av flera arbetsbelastningar samtidigt.
I den kommande sektionen av datamodelleringslaboratoriet baseras pÄ YugaByte DB:s API:er som Àr kompatibla med PostgreSQL och Cassandra, till skillnad frÄn de ursprungliga databaserna. Denna metod betonar enkelheten i att interagera med tvÄ olika API:er (pÄ tvÄ olika portar) av samma databas som motsats till att anvÀnda helt oberoende kluster av tvÄ olika databaser.
I de kommande sektionerna kommer vi att utforska datamodelleringslaboratoriet för att illustrera skillnaderna och vissa likheter mellan de granskade databaserna.
Datamodelleringslaboratorium
Installation av databaser
Med fokus pÄ datamodellens design (och inte komplexa distributionsarkitekturer) kommer vi att installera databaserna i Docker-containrar pÄ den lokala datorn och sedan interagera med dem via deras respektive kommandoradsgrÀnssnitt.
YugaByte DB, kompatibel med PostgreSQL & Cassandra
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_postgresMongoDB
docker run --name my-mongo -d mongo:latestĂ tkomst via kommandoraden
LÄt oss ansluta till databaserna med hjÀlp av kommandoradsgrÀnssnittet för de respektive API:erna.
PostgreSQL
â detta Ă€r kommandoradsgrĂ€nssnittet för att interagera med PostgreSQL. För enkelhetens skull levereras YugaByte DB med psql direkt i bin-mappen.
docker exec -it yb-postgres-n1 /home/yugabyte/postgres/bin/psql -p 5433 -U postgresCassandra
â detta Ă€r kommandoradsgrĂ€nssnittet för att interagera med Cassandra och dess kompatibla databaser via CQL (Cassandra Query Language). För anvĂ€ndarvĂ€nlighet gör YugaByte DB det klart att cqlsh i katalogen bin.
Observera att CQL Àr inspirerat av SQL och har liknande begrepp som tabeller, rader, kolumner och index. Men som ett NoSQL-sprÄk lÀgger det till en viss uppsÀttning begrÀnsningar, de flesta av vilka vi ocksÄ kommer att granska i andra artiklar.
docker exec -it yb-tserver-n1 /home/yugabyte/bin/cqlshMongoDB
â Ă€r ett kommandoradsgrĂ€nssnitt för att interagera med MongoDB. Det kan hittas i bin-katalogen för MongoDB-installationen.
docker exec -it my-mongo bash
cd bin
mongoSkapa en tabell
Nu kan vi interagera med databasen för att utföra olika operationer via kommandoraden. LĂ„t oss börja med att skapa en tabell som lagrar information om lĂ„tar skrivna av olika artister. Dessa lĂ„tar kan vara en del av ett album. Ăven valfria attribut för lĂ„ten â utgivningsĂ„r, pris, genre och betyg. Vi behöver ta hĂ€nsyn till ytterligare attribut som kan behövas i framtiden genom fĂ€ltet "taggar". Det kan lagra semi-strukturerade data i form av nyckel-vĂ€rde-par.
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)
); Cassandra
Att skapa en tabell i Cassandra Àr mycket likt PostgreSQL. En av de stora skillnaderna Àr avsaknaden av integritetsbegrÀnsningar (t.ex. NOT NULL), men detta faller inom applikationens ansvar, inte NoSQL-databasen.. Den primÀra nyckeln bestÄr av en partition key (kolumnen Artist i exemplet nedan) och ett set av clustering columns (kolumnen SongTitle i det nedan givna exemplet). Partition key anger vilken partition/shard som en rad ska placeras i, medan clustering columns anger hur datan ska organiseras inom den aktuella sharden.
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 organiserar data i databaser (Database) (motsvarande Keyspace i Cassandra), dĂ€r det finns samlingar (Collections) (motsvarande tabeller), i vilka dokument (Documents) (motsvarande rader i en tabell) finns. I MongoDB krĂ€vs principiellt ingen initial definitionsschema. Kommandot "use database", som visas nedan, skapar en instans av databasen vid första anropet och Ă€ndrar kontexten till den nyss skapade databasen. Ăven samlingar behöver inte skapas explicit, de skapas automatiskt nĂ€r den första dokumentet lĂ€ggs till i en ny samling. Observera att MongoDB som standard anvĂ€nder en testdatabas, sĂ„ alla operationer pĂ„ samlingsnivĂ„ utan att ange en specifik databas kommer att utföras dĂ€r som standard.
use myNewDatabase;HĂ€mta information om tabellen
PostgreSQL
d Musik
Tabell "public.music"
Kolumn | Typ | Sortering | Nullable | Standard
--------------+-----------------------+-----------+----------+--------
artist | tecken varierande(20) | | ej null |
songtitle | tecken varierande(30) | | ej null |
albumtitle | tecken varierande(25) | | |
Är | heltal | | |
pris | dubbel precision | | |
genre | tecken varierande(10) | | |
kritikerbetyg | dubbel precision | | |
tags | text | | |
Index:
"music_pkey" PRIMĂR NYCKEL, btree (artist, songtitle)Cassandra
BESKRIV TABELL MUSIC;
SKAPA TABELL myapp.music (
artist text,
songtitle text,
albumtitle text,
Är int,
pris float,
genre text,
tags text,
PRIMĂR NYCKEL (artist, songtitle)
) MED KLUSTERINGSORDNING EFTER (songtitle ASC)
OCH default_time_to_live = 0
OCH transaktioner = {'enabled': 'false'};MongoDB
anvÀnd myNewDatabase;
visa kollektioner;Införande av data i tabellen
PostgreSQL
INFĂR i Musik
(Artist, LÄt, Album,
Ă
r, Pris, Genre, Kritikerbetyg,
Taggar)
VALUES(
'No One You Know', 'Call Me Today', 'Somewhat Famous',
2015, 2.14, 'Country', 7.8,
'{"Composers": ["Smith", "Jones", "Davis"],"LengthInSeconds": 214}'
);
INFĂR i Musik
(Artist, LÄt, Album,
Pris, Genre, Kritikerbetyg)
VALUES(
'No One You Know', 'My Dog Spot', 'Hey Now',
1.98, 'Country', 8.4
);
INFĂR i Musik
(Artist, LÄt, Album,
Pris, Genre)
VALUES(
'The Acme Band', 'Look Out, World', 'The Buck Starts Here',
0.99, 'Rock'
);
INFĂR i Musik
(Artist, LÄt, Album,
Pris, Genre,
Taggar)
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}'
);Cassandra
Generellt uttryck INSĂTT i Cassandra ser vĂ€ldigt liknande ut som det motsvarande i PostgreSQL. Men det finns en stor skillnad i semantiken. I Cassandra INSĂTT Ă€r det faktiskt en operation UPSERT, dĂ€r de senaste vĂ€rdena lĂ€ggs till i raden, om raden redan finns.
Datainmatning sker pÄ ett sÀtt som liknar PostgreSQL.
INSĂTTmetoden.
.
MongoDB
Trots att MongoDB Àr en NoSQL-databas, liknande Cassandra, har dess datainmatningsoperationer inget gemensamt med semantiken i Cassandra. I MongoDB har ingen kapacitet UPSERT, vilket gör att den liknar PostgreSQL. Att lÀgga till data som standard utan _idspecified kommer resultera i att ett nytt dokument lÀggs till i kollektionen.
db.music.insert( {
artist: "Ingen som du kÀnner",
songTitle: "Ring mig idag",
albumTitle: "NÄgot berömt",
year: 2015,
price: 2.14,
genre: "Country",
tags: {
Composers: ["Smith", "Jones", "Davis"],
LengthInSeconds: 214
}
}
);
db.music.insert( {
artist: "Ingen som du kÀnner",
songTitle: "Min hund Spot",
albumTitle: "Hej nu",
price: 1.98,
genre: "Country",
criticRating: 8.4
}
);
db.music.insert( {
artist: "The Acme Band",
songTitle: "Se upp, vÀrlden",
albumTitle:"Dollar börjar hÀr",
price: 0.99,
genre: "Rock"
}
);
db.music.insert( {
artist: "The Acme Band",
songTitle: "Fortfarande förÀlskad",
albumTitle:"Dollar börjar hÀr",
price: 2.47,
genre: "Rock",
tags: {
radioStationsPlaying:["KHCR", "KBQX", "WTNR", "WJJH"],
tourDates: {
Seattle: "20150625",
Cleveland: "20150630"
},
rotation: "Heavy"
}
}
);
FörfrÄgan i tabellen
Kanske den mest betydande skillnaden mellan SQL och NoSQL i termer av att göra förfrĂ„gningar ligger i anvĂ€ndningen av formuleringar FRĂ
N och DĂR. SQL tillĂ„ter flera tabeller efter uttrycket FRĂ
N att vĂ€lja, och uttrycket med DĂR kan ha vilken komplexitet som helst (inklusive operationer JOIN mellan tabeller). Men NoSQL tenderar att införa strikta begrĂ€nsningar pĂ„ FRĂ
N, och fungerar endast med en angiven tabell, medan i DĂR, mĂ„ste en primĂ€rnyckel alltid anges. Detta beror pĂ„ strĂ€van att öka prestandan pĂ„ NoSQL, som vi tidigare har diskuterat. Denna strĂ€van leder till en minskning av all kors-tabell och kors-nyckel interaktion. Det kan orsaka stor fördröjning i nod-nod kommunikation vid svar pĂ„ förfrĂ„gningar och bör dĂ€rför undvikas helt. Till exempel krĂ€ver Cassandra att förfrĂ„gningar begrĂ€nsas till specifika operationer (endast tillĂ„tna =, IN, , =>, <=) pĂ„ partitionsnycklar, förutom i fall av sekundĂ€rindexförfrĂ„gningar (hĂ€r tillĂ„ts endast operatorn =).
PostgreSQL
HÀr Àr tre exempel pÄ förfrÄgningar som lÀtt kan utföras av en SQL-databas.
- HÀmta alla lÄtar av artisten;
- HÀmta alla lÄtar av artisten som matchar den första delen av titeln;
- HÀmta alla lÄtar av artisten som har ett visst ord i titeln och kostar mindre Àn 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;Cassandra
Av de ovan nÀmnda frÄgorna kommer endast den första att fungera i Cassandra utan Àndringar, eftersom operatorn LIKE inte kan tillÀmpas pÄ klusterkolumner, sÄsom SongTitle. I detta fall tillÄts endast operatorer = och 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
Som visat i de tidigare exemplen, Àr den frÀmsta metoden för att skapa förfrÄgningar i MongoDB . Denna metod innehÄller tydligt namnet pÄ samlingen (music i exemplet nedan), sÄ förfrÄgningar över flera samlingar Àr inte tillÄtna.
db.music.find( {
artist: "No One You Know"
}
);
db.music.find( {
artist: "No One You Know",
songTitle: /Call/
}
);LĂ€sa alla rader i tabellen
Att lÀsa alla rader Àr helt enkelt ett specialfall av den frÄgemall som vi diskuterat tidigare.
PostgreSQL
SELECT *
FROM Music;Cassandra
PÄ samma sÀtt som exemplet i PostgreSQL ovan.
MongoDB
db.music.find( {} );Redigera data i tabellen
PostgreSQL
PostgreSQL tillhandahÄller instruktionen UPPDATERA för att Àndra data. Den har ingen funktionalitet UPSERT, sÄ att köra denna instruktion kommer att resultera i ett felmeddelande om raderna inte lÀngre finns i databasen.
UPDATE Music
SET Genre = 'Disco'
WHERE Artist = 'The Acme Band' AND SongTitle = 'Still In Love';Cassandra
I Cassandra finns det UPPDATERA en motsvarande PostgreSQL. UPPDATERA har samma semantik UPSERT, liknande INSĂTT.
PÄ samma sÀtt som exemplet i PostgreSQL ovan.
MongoDB
Operation I MongoDB kan man helt uppdatera ett befintligt dokument eller endast uppdatera specifika fÀlt. Som standard uppdaterar den endast ett dokument med semantiken inaktiverad. UPSERT. Att uppdatera flera dokument och beteende Àr liknande. UPSERT det kan tillÀmpas genom att stÀlla in ytterligare flaggor för operationen. Precis som i det följande exemplet, uppdateras genren för en specifik artist baserat pÄ deras lÄt.
db.music.update(
{"artist": "The Acme Band"},
{
$set: {
"genre": "Disco"
}
},
{"multi": true, "upsert": true}
);Ta bort data frÄn tabellen
PostgreSQL
DELETE FROM Music
WHERE Artist = 'The Acme Band' AND SongTitle = 'Look Out, World';Cassandra
PÄ samma sÀtt som exemplet i PostgreSQL ovan.
MongoDB
I MongoDB finns det tvĂ„ typer av operationer för att ta bort dokument â och . BĂ„da typerna tar bort dokument, men returnerar olika resultat.
db.music.deleteMany( {
artist: "The Acme Band"
}
);
Ta bort tabellen
PostgreSQL
DROP TABLE Music;Cassandra
PÄ samma sÀtt som exemplet i PostgreSQL ovan.
MongoDB
db.music.drop();Slutsats
Debatten om valet mellan SQL och NoSQL har pÄgÄtt i över 10 Är. Det finns tvÄ huvudaspekter av denna debatt: kÀrnarkitekturen i databasen (monolitisk, transaktionell SQL mot distribuerad, icke-transaktionell NoSQL) och designmetoden för databasen (datamodellering i SQL mot att modellera dina förfrÄgningar i NoSQL).
Med en distribuerad transaktionell databas som YugaByte DB kan debatten om databasarkitektur enkelt skingras. Allt eftersom datamÀngderna blir större Àn vad som kan skrivs pÄ en nod, blir en helt distribuerad arkitektur som stödjer linjÀr skrivskalerbarhet med automatisk sharding/omfördelning nödvÀndig.
Förutom det som nÀmns i en av artiklarna , anvÀnds transaktionella, strikt överenskomna arkitekturer nu i större utstrÀckning för att sÀkerstÀlla bÀttre flexibilitet i utvecklingen Àn icke-transaktionella, slutligen överenskomna arkitekturer.
à terkommer till diskussionen om databasdesign, Àr det rimligt att sÀga att bÄda designmetoderna (SQL och NoSQL) Àr nödvÀndiga för alla komplexa verkliga applikationer. SQL-ansatsen "datamodellering" gör det lÀttare för utvecklare att möta förÀnderliga affÀrskrav, medan NoSQL-ansatsen "frÄgemodellering" tillÄter samma utvecklare att hantera stora datamÀngder med lÄg latens och hög genomströmning. Just av denna anledning erbjuder YugaByte DB bÄde SQL- och NoSQL-API:er i en gemensam kÀrna, snarare Àn att föresprÄka nÄgon av metoderna. Dessutom, genom att sÀkerstÀlla kompatibilitet med populÀra databassprÄk, inklusive PostgreSQL och Cassandra, garanterar YugaByte DB att utvecklare inte behöver lÀra sig ett annat sprÄk för att arbeta med den distribuerade, strikt konsistenta databasisskern.
I den hÀr artikeln har vi undersökt hur grunderna för databasdesign skiljer sig mellan PostgreSQL, Cassandra och MongoDB. I kommande artiklar kommer vi att dyka in i avancerade designkoncept som index, transaktioner, JOIN:ar, TTL-direktiv och JSON-dokument.
Vi önskar er en trevlig kvarvarande helg och inbjuder till , som redan Àger rum den 14 maj.
KĂ€lla: habr.com
