Database Design Fundamentals - Vergelyk PostgreSQL, Cassandra en MongoDB

Hallo vriende. Voordat ons na die tweede deel van die Mei-vakansie vertrek, deel ons die materiaal wat ons vertaal het in afwagting van die bekendstelling van 'n nuwe stroom teen die koers, met u "Relasionele DBBS".

Database Design Fundamentals - Vergelyk PostgreSQL, Cassandra en MongoDB

Toepassingsontwikkelaars spandeer baie tyd om verskeie operasionele databasisse te vergelyk om die een te kies wat die beste werk vir hul beoogde werklading. Behoeftes kan vereenvoudigde datamodellering, transaksionele waarborge, lees-/skryfprestasie, horisontale skaal en fouttoleransie insluit. Tradisioneel begin die keuse met die kategorie databasis, SQL of NoSQL, aangesien elke kategorie 'n duidelike stel afwegings bied. Hoë werkverrigting in terme van lae latensie en hoë deurset word oor die algemeen gesien as 'n vereiste wat nie gekompromitteer kan word nie en is dus noodsaaklik vir enige databasis in die monster.

Die doel van hierdie artikel is om toepassingsontwikkelaars te help om die regte keuse tussen SQL en NoSQL te maak in die konteks van toepassingsdatamodellering. Ons sal kyk na een SQL-databasis, naamlik PostgreSQL, en twee NoSQL-databasisse, Cassandra en MongoDB, om die basiese beginsels van databasisontwerp te dek, soos om tabelle te skep, hulle te vul, data uit 'n tabel te lees en dit uit te vee. In die volgende artikel sal ons beslis kyk na indekse, transaksies, JOINs, TTL-aanwysings en databasisontwerp gebaseer op JSON.

Wat is die verskil tussen SQL en NoSQL?

SQL-databasisse verhoog toepassingsbuigsaamheid deur ACID-transaksiewaarborge, sowel as hul vermoë om data met behulp van JOINs op onverwagte maniere navraag te doen bo en behalwe bestaande genormaliseerde relasionele databasismodelle.

Gegewe hul monolitiese/enkelnodusargitektuur en gebruik van 'n meester-slaaf-replikasiemodel vir oortolligheid, het tradisionele SQL-databasisse nie twee belangrike kenmerke nie - lineêre skryfskaalbaarheid (d.w.s. outomatiese verdeling oor veelvuldige nodusse) en outomatiese/nul dataverlies. Dit beteken dat die hoeveelheid data wat ontvang word nie die maksimum skryfdeurset van 'n enkele nodus kan oorskry nie. Daarbenewens moet 'n mate van tydelike verlies van data in ag geneem word vir fouttoleransie (in 'n nie-gedeelde argitektuur). Hier moet jy in gedagte hou dat onlangse commits nog nie in die slawe-kopie weerspieël is nie. Geen stilstand-opdaterings is ook moeilik om in SQL-databasisse te bereik nie.

NoSQL-databasisse word tipies in die natuur versprei, d.w.s. daarin word die data in afdelings verdeel en oor verskeie nodusse versprei. Hulle benodig denormalisering. Dit beteken dat die ingevoerde data ook verskeie kere gekopieer moet word om te reageer op die spesifieke versoeke wat jy stuur. Die algehele doelwit is om hoë werkverrigting te kry deur die aantal stukke wat beskikbaar is tydens leestyd te verminder. Dit impliseer dat NoSQL vereis dat jy jou navrae modelleer, terwyl SQL vereis dat jy jou data modelleer.

NoSQL beklemtoon die bereiking van hoë werkverrigting in 'n verspreide groepering en dit is die hoofrede vir baie databasisontwerp-afruilings, wat verlies van ACID-transaksies, JOIN's en konsekwente globale sekondêre indekse insluit.

Daar is 'n mening dat alhoewel NoSQL-databasisse lineêre skryfskaalbaarheid en hoë fouttoleransie bied, die verlies van transaksionele waarborge dit ongeskik maak vir kritieke data.

Die volgende tabel wys hoe datamodellering in NoSQL van SQL verskil.

Database Design Fundamentals - Vergelyk PostgreSQL, Cassandra en MongoDB

SQL en NoSQL: Hoekom is albei nodig?

Werklike toepassings met 'n groot aantal gebruikers, soos Amazon.com, Netflix, Uber en Airbnb, is verantwoordelik vir die uitvoering van komplekse take van verskillende soorte. Byvoorbeeld, 'n e-handeltoepassing soos Amazon.com moet liggewig, hoogs sensitiewe data stoor soos inligting oor gebruikers, produkte, bestellings, fakture, tesame met swaar maar minder sensitiewe data soos produkresensies, ondersteuningsboodskappe. , gebruikeraktiwiteit , gebruikersresensies en aanbevelings. Natuurlik maak hierdie toepassings staat op ten minste een SQL-databasis saam met ten minste een NoSQL-databasis. In interstreek- en globale stelsels werk NoSQL-databasis as 'n geo-verspreide kas vir data wat gestoor word in 'n betroubare bron, SQL-databasis, wat in enige streek werk.

Hoe kombineer YugaByte DB SQL en NoSQL?

YugaByte DB is gebou op 'n log-georiënteerde gemengde bergingsenjin, outo-sharding, verdeelde verspreide konsensusreplikasie en ACID-verspreide transaksies (geïnspireer deur Google Spanner), en is die wêreld se eerste oopbrondatabasis wat gelyktydig NoSQL (Cassandra & Redis) versoenbaar is. ) en SQL (PostgreSQL). Soos in die tabel hieronder getoon, voeg YCQL, 'n YugaByte DB API versoenbaar met Cassandra, die konsepte van enkel- en multi-sleutel ACID-transaksies en globale sekondêre indekse by die NoSQL API, en lei sodoende die era van transaksionele NoSQL-databasisse in. Daarbenewens voeg YCQL, 'n YugaByte DB API versoenbaar met PostgreSQL, die konsepte van lineêre skryfskaal en outomatiese failover by die SQL API, wat verspreide SQL-databasisse na die wêreld bring. Aangesien die YugaByte DB-databasis inherent transaksioneel is, kan die NoSQL API nou in die konteks van kritieke data gebruik word.

Database Design Fundamentals - Vergelyk PostgreSQL, Cassandra en MongoDB

Soos voorheen in die artikel gesê "Bekendstelling van YSQL: 'n PostgreSQL-versoenbare verspreide SQL API vir YugaByte DB", hang die keuse tussen SQL of NoSQL in YugaByte DB geheel en al af van die eienskappe van die onderliggende werklading:

  • As jou primêre werklading multi-sleutel JOIN bedrywighede is, dan wanneer jy YSQL kies, wees bewus daarvan dat jou sleutels oor verskeie nodusse versprei kan wees, wat lei tot hoër latensie en/of laer deurset as NoSQL.
  • Andersins, kies een van die twee NoSQL API's, hou in gedagte dat u beter werkverrigting sal kry as gevolg van navrae wat vanaf een nodus op 'n slag bedien word. YugaByte DB kan dien as 'n enkele operasionele databasis vir werklike komplekse toepassings wat verskeie werkladings op dieselfde tyd moet bestuur.

Die datamodelleringslaboratorium in die volgende afdeling is gebaseer op die PostgreSQL- en Cassandra-versoenbare YugaByte DB-databasis-API's, in teenstelling met die oorspronklike databasisse. Hierdie benadering beklemtoon die gemak van interaksie met twee verskillende API's (op twee verskillende poorte) van dieselfde databasiskluster, in teenstelling met die gebruik van heeltemal onafhanklike groepe van twee verskillende databasisse.
In die volgende afdelings gaan ons na die Data Modellering Lab kyk om die verskil en sommige van die gemeenskaplikhede van die betrokke databasisse te illustreer.

Data Modeling Lab

Die installering van databasisse

Gegewe die fokus op datamodelontwerp (eerder as komplekse ontplooiingsargitekture), sal ons die databasisse in Docker-houers op die plaaslike masjien installeer en dan met hulle in wisselwerking tree deur hul onderskeie opdragreëldoppies te gebruik.

PostgreSQL & Cassandra versoenbaar, YugaByte DB databasis

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

Bevellyn toegang

Kom ons koppel aan die databasisse deur die opdragreëldop vir die onderskeie API's te gebruik.

PostgreSQL

psql is 'n opdragreëldop vir interaksie met PostgreSQL. Vir gebruiksgemak kom YugaByte DB met psql reg in die bin-lêergids.

docker exec -it yb-postgres-n1 /home/yugabyte/postgres/bin/psql -p 5433 -U postgres

Cassandra

sqlsh is 'n opdragreëldop vir interaksie met Cassandra en sy versoenbare databasisse via CQL (Cassandra Query Language). Vir gemak van gebruik, kom YugaByte DB saam cqlsh in die katalogus bin.
Let daarop dat CQL deur SQL geïnspireer is en soortgelyke konsepte van tabelle, rye, kolomme en indekse het. As 'n NoSQL-taal voeg dit egter 'n sekere stel beperkings by, waarvan ons die meeste ook in ander artikels sal dek.

docker exec -it yb-tserver-n1 /home/yugabyte/bin/cqlsh

MongoDB

Mongo is 'n opdragreëldop vir interaksie met MongoDB. Dit kan gevind word in die bin-gids van die MongoDB-installasie.

docker exec -it my-mongo bash 
cd bin
mongo

Skep 'n tafel

Nou kan ons met die databasis interaksie hê om verskeie bewerkings uit te voer deur die opdragreël te gebruik. Kom ons begin deur 'n tabel te skep wat inligting stoor oor liedjies wat deur verskillende kunstenaars geskryf is. Hierdie liedjies kan deel van 'n album wees. Opsionele eienskappe vir die liedjie is ook jaar van vrystelling, prys, genre en gradering. Ons moet addisionele eienskappe in ag neem wat in die toekoms nodig mag wees deur die "tags"-veld. Dit kan semi-gestruktureerde data as sleutel-waarde-pare stoor.

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

Die skep van 'n tabel in Cassandra is baie soortgelyk aan PostgreSQL. Een van die belangrikste verskille is die afwesigheid van integriteitsbeperkings (soos NIE NULL), maar dit is die verantwoordelikheid van die toepassing, nie die NoSQL-databasis nie.. Die primêre sleutel bestaan ​​uit 'n partisiesleutel (Kunstenaarkolom in die voorbeeld hieronder) en 'n stel groeperingskolomme (SongTitle-kolom in die voorbeeld hieronder). Die partisiesleutel bepaal in watter partisie/skerf die ry moet geplaas word, en die groeperingskolomme dui aan hoe die data binne die huidige skerf georganiseer moet word.

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 organiseer data in databasisse (Databasis) (soortgelyk aan Keyspace in Cassandra), waar daar versamelings (Versamelings) (soortgelyk aan tabelle) is wat dokumente (Dokumente) bevat (soortgelyk aan rye in 'n tabel). In MongoDB word in beginsel geen aanvanklike skemadefinisie vereis nie. Span "gebruik databasis", hieronder getoon, instansieer die databasis op die eerste oproep en verander die konteks vir die nuutgeskepte databasis. Selfs versamelings hoef nie eksplisiet geskep te word nie, hulle word outomaties geskep, net wanneer die eerste dokument by 'n nuwe versameling gevoeg word. Let daarop dat MongoDB by verstek 'n toetsdatabasis gebruik, so enige versamelingsvlakbewerking sonder om 'n spesifieke databasis te spesifiseer, sal by verstek daarin uitgevoer word.

use myNewDatabase;

Kry inligting oor 'n tabel
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)

Cassandra

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;

Die invoer van data in 'n tabel
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}'
);

Cassandra

In die algemeen, die uitdrukking INSERT in Cassandra lyk baie soos die een in PostgreSQL. Daar is egter een groot verskil in semantiek. In Cassandra INSERT is eintlik 'n operasie UPSERT, waar die nuutste waardes by die string gevoeg word, ingeval die string reeds bestaan.

Data-invoer is soortgelyk aan PostgreSQL INSERT bo

.

MongoDB

Alhoewel MongoDB 'n NoSQL-databasis soos Cassandra is, het die data-invoerbewerking niks met Cassandra se semantiese gedrag te doen nie. In MongoDB voeg in () het geen geleentheid nie UPSERT, wat dit soortgelyk maak aan PostgreSQL. Voeg verstekdata by sonder _idspecified sal daartoe lei dat 'n nuwe dokument by die versameling gevoeg word.

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"
}
}
);

Tabelnavraag

Miskien is die belangrikste verskil tussen SQL en NoSQL in terme van navrae die gebruik van FROM и WHERE. SQL laat na uitdrukking toe FROM kies verskeie tabelle, en 'n uitdrukking met WHERE kan van enige kompleksiteit wees (insluitend bewerkings JOIN tussen tafels). NoSQL is egter geneig om 'n harde limiet op te lê FROM, en werk met slegs een gespesifiseerde tabel, en in WHERE, moet die primêre sleutel altyd gespesifiseer word. Dit is te danke aan die begeerte om die prestasie van NoSQL te verbeter, waaroor ons vroeër gepraat het. Hierdie begeerte lei tot elke moontlike vermindering van enige kruisoortjie- en kruissleutelinteraksie. Dit kan 'n groot vertraging in inter-node-kommunikasie veroorsaak wanneer op 'n versoek gereageer word en word dus in beginsel die beste vermy. Byvoorbeeld, Cassandra vereis dat versoeke beperk moet word tot sekere operateurs (slegs toegelaat =, IN, <, >, =>, <=) op partisiesleutels, behalwe wanneer 'n sekondêre indeks navraag gedoen word (slegs die = operateur word hier toegelaat).

PostgreSQL

Die volgende is drie voorbeelde van navrae wat maklik deur 'n SQL-databasis uitgevoer kan word.

  • Vertoon alle liedjies van die kunstenaar;
  • Vertoon alle liedjies van die kunstenaar wat by die eerste deel van die titel pas;
  • Vertoon alle liedjies deur die kunstenaar wat 'n sekere woord in die titel het en 'n prys van minder as 1.00 het.
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

Van die PostgreSQL-navrae wat hierbo gelys is, sal slegs die eerste een onveranderd in Cassandra werk, omdat die stelling LIKE kan nie toegepas word op groeperingkolomme soos SongTitle. In hierdie geval word slegs operateurs toegelaat = и 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

Soos in die vorige voorbeelde getoon, is die hoofmetode vir die skep van navrae in MongoDB db.collection.find(). Hierdie metode bevat uitdruklik die naam van die versameling (music in die voorbeeld hieronder), dus word navraag oor verskeie versamelings nie toegelaat nie.

db.music.find( {
  artist: "No One You Know"
 } 
);
db.music.find( {
  artist: "No One You Know",
  songTitle: /Call/
 } 
);

Lees alle rye van 'n tabel

Om alle rye te lees is net 'n spesiale geval van die navraagpatroon wat ons vroeër bespreek het.

PostgreSQL

SELECT * 
FROM Music;

Cassandra

Soortgelyk aan die PostgreSQL-voorbeeld hierbo.

MongoDB

db.music.find( {} );

Redigeer data in 'n tabel

PostgreSQL

PostgreSQL verskaf 'n verklaring UPDATE data te verander. Sy het geen geleentheid nie UPSERT, so hierdie stelling sal misluk as die ry nie meer in die databasis is nie.

UPDATE Music
SET Genre = 'Disco'
WHERE Artist = 'The Acme Band' AND SongTitle = 'Still In Love';

Cassandra

Cassandra het UPDATE soortgelyk aan PostgreSQL. UPDATE het dieselfde semantiek UPSERT, soos INSERT.

Soortgelyk aan die PostgreSQL-voorbeeld hierbo.

MongoDB
operasie Opdateer() in MongoDB kan dit 'n bestaande dokument heeltemal opdateer of slegs sekere velde opdateer. By verstek werk dit net een dokument op met semantiek gedeaktiveer UPSERT. Verfris veelvuldige dokumente en soortgelyke gedrag UPSERT kan toegepas word deur bykomende vlae vir die operasie te stel. Soos byvoorbeeld in die voorbeeld hieronder, word die genre van 'n spesifieke kunstenaar deur sy liedjie opgedateer.

db.music.update(
  {"artist": "The Acme Band"},
  { 
    $set: {
      "genre": "Disco"
    }
  },
  {"multi": true, "upsert": true}
);

Verwyder data uit 'n tabel

PostgreSQL

DELETE FROM Music
WHERE Artist = 'The Acme Band' AND SongTitle = 'Look Out, World';

Cassandra

Soortgelyk aan die PostgreSQL-voorbeeld hierbo.

MongoDB

MongoDB het twee tipes bewerkings om dokumente uit te vee − deleteOne() /deleteMany() и verwyder (). Albei tipes vee dokumente uit, maar gee verskillende resultate.

db.music.deleteMany( {
        artist: "The Acme Band"
    }
);

Vee tans 'n tabel uit

PostgreSQL

DROP TABLE Music;

Cassandra

Soortgelyk aan die PostgreSQL-voorbeeld hierbo.

MongoDB

db.music.drop();

Gevolgtrekking

Die debat oor die keuse tussen SQL en NoSQL woed al meer as 10 jaar. Daar is twee hoofaspekte aan hierdie debat: die argitektuur van die databasis-enjin (monolitiese, transaksionele SQL vs. verspreide, nie-transaksionele NoSQL) en die benadering tot databasisontwerp (datamodellering in SQL vs. modellering van jou navrae in NoSQL).

Met 'n verspreide transaksionele databasis soos YugaByte DB, kan die databasisargitektuurdebat maklik uit die weg geruim word. Namate datavolumes groter word as wat na 'n enkele nodus geskryf kan word, word 'n volledig verspreide argitektuur wat lineêre skryfskaalbaarheid ondersteun met outomatiese versplintering/herbalansering nodig.

Benewens wat in een van die artikels gesê is Google Wolk, transaksionele, sterk konsekwente argitekture word nou meer algemeen aangeneem om beter ontwikkelingsbuigsaamheid te bied as nie-transaksionele, uiteindelik konsekwente argitekture.

Om terug te keer na die bespreking van databasisontwerp, is dit regverdig om te sê dat beide ontwerpbenaderings (SQL en NoSQL) nodig is vir enige komplekse werklike toepassings. SQL se "datamodellering"-benadering stel ontwikkelaars in staat om makliker aan veranderende besigheidsvereistes te voldoen, terwyl NoSQL se "navraagmodellering"-benadering daardie selfde ontwikkelaars toelaat om groot hoeveelhede data met lae latensie en hoë deurset te hanteer. Dit is om hierdie rede dat YugaByte DB SQL- en NoSQL-API's in 'n gemeenskaplike kern verskaf en nie een van die benaderings voorstaan ​​nie. Boonop, deur versoenbaarheid met gewilde databasistale, insluitend PostgreSQL en Cassandra, te verskaf, verseker YugaByte DB dat ontwikkelaars nie 'n ander taal hoef te leer om met 'n verspreide sterk konsekwente databasisenjin te werk nie.

In hierdie artikel het ons gekyk hoe die basiese beginsels van databasisontwerp verskil tussen PostgreSQL, Cassandra en MongoDB. In die volgende artikels sal ons duik in gevorderde ontwerpkonsepte soos indekse, transaksies, JOINs, TTL-aanwysings en JSON-dokumente.

Ons wens jou 'n wonderlike naweek toe en nooi jou uit gratis webinarwat op 14 Mei sal plaasvind.

Bron: will.com

Voeg 'n opmerking