Základy návrhu databáze - Porovnání PostgreSQL, Cassandra a MongoDB

Dobrý den, přátelé. Před odjezdem na druhou část květnových prázdnin s vámi sdílíme materiál, který jsme přeložili v očekávání spuštění nového streamu v kurzu "Relační DBMS".

Základy návrhu databáze - Porovnání PostgreSQL, Cassandra a MongoDB

Vývojáři aplikací tráví spoustu času porovnáváním více operačních databází, aby si vybrali tu, která nejlépe vyhovuje jejich zamýšlené zátěži. Potřeby mohou zahrnovat zjednodušené datové modelování, transakční záruky, výkon čtení/zápisu, horizontální škálování a odolnost proti chybám. Tradičně výběr začíná kategorií databáze, SQL nebo NoSQL, protože každá kategorie poskytuje jasný soubor kompromisů. Vysoký výkon z hlediska nízké latence a vysoké propustnosti je obecně považován za požadavek, který nelze ohrozit, a je proto nezbytný pro jakoukoli databázi ve vzorku.

Účelem tohoto článku je pomoci vývojářům aplikací správně se rozhodnout mezi SQL a NoSQL v kontextu datového modelování aplikací. Podíváme se na jednu SQL databázi, konkrétně PostgreSQL, a dvě NoSQL databáze, Cassandra a MongoDB, abychom pokryli základy návrhu databáze, jako je vytváření tabulek, jejich naplňování, čtení dat z tabulky a jejich mazání. V příštím článku se určitě podíváme na indexy, transakce, JOINy, TTL direktivy a návrh databáze na bázi JSON.

Jaký je rozdíl mezi SQL a NoSQL?

SQL databáze zvyšují flexibilitu aplikací prostřednictvím ACID transakčních záruk, stejně jako jejich schopnost dotazovat se na data pomocí JOINs neočekávaným způsobem nad existujícími normalizovanými modely relačních databází.

Vzhledem k jejich monolitické/jednouzlové architektuře a použití modelu replikace master-slave pro redundanci postrádají tradiční databáze SQL dvě důležité funkce – lineární škálovatelnost zápisu (tj. automatické rozdělování mezi více uzly) a automatickou/nulovou ztrátu dat. To znamená, že množství přijatých dat nemůže překročit maximální propustnost zápisu jednoho uzlu. Navíc je třeba vzít v úvahu určitou dočasnou ztrátu dat pro odolnost proti chybám (v nesdílené architektuře). Zde musíte mít na paměti, že nedávné odevzdání se ještě neprojevilo v podřízené kopii. V databázích SQL je také obtížné dosáhnout žádných aktualizací prostojů.

NoSQL databáze jsou typicky distribuované v přírodě, tzn. v nich jsou data rozdělena do sekcí a distribuována do několika uzlů. Vyžadují denormalizaci. To znamená, že zadaná data musí být také několikrát zkopírována, aby bylo možné reagovat na konkrétní požadavky, které zasíláte. Celkovým cílem je dosáhnout vysokého výkonu snížením počtu datových fragmentů dostupných v době čtení. To znamená, že NoSQL vyžaduje, abyste modelovali své dotazy, zatímco SQL vyžaduje, abyste modelovali svá data.

NoSQL klade důraz na dosažení vysokého výkonu v distribuovaném clusteru a to je hlavní důvod mnoha kompromisů při návrhu databází, které zahrnují ztrátu ACID transakcí, JOINů a konzistentních globálních sekundárních indexů.

Existuje názor, že ačkoli databáze NoSQL poskytují lineární škálovatelnost zápisu a vysokou odolnost proti chybám, ztráta transakčních záruk je činí nevhodnými pro kritická data.

Následující tabulka ukazuje, jak se datové modelování v NoSQL liší od SQL.

Základy návrhu databáze - Porovnání PostgreSQL, Cassandra a MongoDB

SQL a NoSQL: Proč jsou oba potřebné?

Reálné aplikace s velkým počtem uživatelů, jako jsou Amazon.com, Netflix, Uber a Airbnb, jsou zodpovědné za provádění složitých úkolů různého druhu. Například aplikace pro elektronický obchod, jako je Amazon.com, potřebuje ukládat nenáročná, vysoce citlivá data, jako jsou informace o uživatelích, produktech, objednávkách, fakturách, spolu s těžkými, ale méně citlivými daty, jako jsou recenze produktů, zprávy podpory. , aktivita uživatelů , uživatelské recenze a doporučení. Tyto aplikace přirozeně spoléhají na alespoň jednu SQL databázi spolu s alespoň jednou NoSQL databází. V meziregionálních a globálních systémech funguje databáze NoSQL jako geograficky distribuovaná mezipaměť pro data uložená v důvěryhodném zdroji, databázi SQL, fungující v libovolné oblasti.

Jak YugaByte DB kombinuje SQL a NoSQL?

YugaByte DB, postavená na logově orientovaném smíšeném úložišti, automatickém shardingu, sdílené distribuované replikaci konsensu a ACID distribuovaných transakcích (inspirováno Google Spannerem), je YugaByte DB první open source databáze na světě, která je současně kompatibilní s NoSQL (Cassandra & Redis). ) a SQL (PostgreSQL). Jak je uvedeno v tabulce níže, YCQL, YugaByte DB API kompatibilní s Cassandrou, přidává do NoSQL API koncepty jednoklíčových a víceklíčových ACID transakcí a globálních sekundárních indexů, čímž zahajuje éru transakčních NoSQL databází. YCQL, YugaByte DB API kompatibilní s PostgreSQL, navíc přidává koncepty lineárního škálování zápisu a automatického převzetí služeb při selhání do SQL API, čímž přináší distribuované SQL databáze na svět. Vzhledem k tomu, že databáze YugaByte DB je ze své podstaty transakční, lze nyní rozhraní NoSQL API používat v kontextu důležitých dat.

Základy návrhu databáze - Porovnání PostgreSQL, Cassandra a MongoDB

Jak již bylo uvedeno v článku „Představujeme YSQL: PostgreSQL kompatibilní distribuované SQL API pro YugaByte DB“, výběr mezi SQL nebo NoSQL v YugaByte DB zcela závisí na vlastnostech základního pracovního zatížení:

  • Pokud jsou vaší primární zátěží operace JOIN s více klíči, pak si při výběru YSQL uvědomte, že vaše klíče mohou být rozmístěny mezi více uzly, což má za následek vyšší latenci a/nebo nižší propustnost než NoSQL.
  • V opačném případě vyberte jedno ze dvou rozhraní NoSQL API a mějte na paměti, že získáte lepší výkon v důsledku dotazů obsluhovaných z jednoho uzlu najednou. YugaByte DB může sloužit jako jediná operační databáze pro skutečné komplexní aplikace, které potřebují spravovat více pracovních zátěží současně.

Laboratoř datového modelování v další části je založena na databázových API YugaByte DB kompatibilních s PostgreSQL a Cassandra, na rozdíl od původních databází. Tento přístup zdůrazňuje snadnost interakce se dvěma různými API (na dvou různých portech) stejného databázového clusteru, na rozdíl od použití zcela nezávislých clusterů dvou různých databází.
V následujících částech se podíváme na Data Modeling Lab, abychom ilustrovali rozdíl a některé společné rysy příslušných databází.

Laboratoř datového modelování

Instalace databází

Vzhledem k zaměření na návrh datového modelu (spíše než na složité architektury nasazení), nainstalujeme databáze do kontejnerů Docker na místním počítači a poté s nimi budeme komunikovat pomocí jejich příslušných shellů příkazového řádku.

Databáze YugaByte DB kompatibilní s PostgreSQL a 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_postgres

MongoDB

docker run --name my-mongo -d mongo:latest

Přístup z příkazového řádku

Pojďme se připojit k databázím pomocí shellu příkazového řádku pro příslušná API.

PostgreSQL

psql je shell příkazového řádku pro interakci s PostgreSQL. Pro snadné použití je YugaByte DB dodáván s psql přímo ve složce bin.

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

Cassandra

sqlsh je shell příkazového řádku pro interakci s Cassandrou a jejími kompatibilními databázemi prostřednictvím CQL (Cassandra Query Language). Pro snadné použití je YugaByte DB dodáván s cqlsh v katalogu bin.
Všimněte si, že CQL byl inspirován SQL a má podobné koncepty tabulek, řádků, sloupců a indexů. Jako jazyk NoSQL však přidává určitou sadu omezení, z nichž většině se také budeme věnovat v dalších článcích.

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

MongoDB

Mongo je shell příkazového řádku pro interakci s MongoDB. Lze jej nalézt v adresáři bin instalace MongoDB.

docker exec -it my-mongo bash 
cd bin
mongo

Vytvořte tabulku

Nyní můžeme interagovat s databází a provádět různé operace pomocí příkazového řádku. Začněme vytvořením tabulky, která ukládá informace o skladbách napsaných různými interprety. Tyto písně mohou být součástí alba. Volitelnými atributy skladby jsou také rok vydání, cena, žánr a hodnocení. Musíme vzít v úvahu další atributy, které mohou být v budoucnu potřeba prostřednictvím pole „tagy“. Může ukládat polostrukturovaná data jako páry klíč-hodnota.

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

Vytvoření tabulky v Cassandře je velmi podobné PostgreSQL. Jedním z hlavních rozdílů je absence omezení integrity (jako NOT NULL), ale to je odpovědností aplikace, nikoli databáze NoSQL.. Primární klíč se skládá z klíče oddílu (sloupec Artist v příkladu níže) a sady sloupců shlukování (sloupec SongTitle v příkladu níže). Klíč oddílu určuje, do kterého oddílu/úlomku se má řádek vložit, a sloupce shlukování udávají, jak by měla být data v aktuálním fragmentu organizována.

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 organizuje data do databází (Database) (podobně jako Keyspace v Cassandře), kde jsou kolekce (Collections) (podobné tabulkám), které obsahují dokumenty (Documents) (podobně jako řádky v tabulce). V MongoDB v zásadě není vyžadována žádná počáteční definice schématu. tým "použít databázi", zobrazený níže, vytvoří instanci databáze při prvním volání a změní kontext pro nově vytvořenou databázi. Ani kolekce nemusí být vytvářeny explicitně, jsou vytvářeny automaticky, právě když je první dokument přidán do nové kolekce. Všimněte si, že MongoDB standardně používá testovací databázi, takže jakákoli operace na úrovni kolekce bez zadání konkrétní databáze bude ve výchozím nastavení provedena v ní.

use myNewDatabase;

Získání informací o stole
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;

Zadávání dat do tabulky
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

Obecně výraz INSERT v Cassandře vypadá velmi podobně jako v PostgreSQL. V sémantice je však jeden velký rozdíl. V Cassandře INSERT je vlastně operace UPSERT, kde jsou k řetězci přidány nejnovější hodnoty v případě, že řetězec již existuje.

Zadávání dat je podobné PostgreSQL INSERT nad

.

MongoDB

Přestože MongoDB je databáze NoSQL jako Cassandra, její operace zadávání dat nemá nic společného se sémantickým chováním Cassandry. V MongoDB vložit() nemá příležitost UPSERT, díky čemuž je podobný PostgreSQL. Přidávání výchozích dat bez _idspecified bude mít za následek přidání nového dokumentu do sbírky.

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

Dotaz na tabulku

Snad nejvýznamnější rozdíl mezi SQL a NoSQL z hlediska dotazování je použití FROM и WHERE. SQL umožňuje po výrazu FROM vyberte více tabulek a výraz s WHERE může mít libovolnou složitost (včetně operací JOIN mezi tabulkami). NoSQL má však tendenci ukládat pevný limit FROMa pracovat pouze s jednou zadanou tabulkou a v WHERE, musí být vždy uveden primární klíč. To je způsobeno touhou zlepšit výkon NoSQL, o kterém jsme hovořili dříve. Tato touha vede ke všemu možnému omezení jakékoli interakce mezi kartami a křížovými klíči. Může způsobit velké zpoždění v meziuzlové komunikaci při odpovědi na požadavek, a proto je lepší se mu v zásadě vyhnout. Cassandra například vyžaduje, aby požadavky byly omezeny na určité operátory (povoleno pouze =, IN, <, >, =>, <=) na klíčích oddílů, s výjimkou dotazování na sekundární index (zde je povolen pouze operátor =).

PostgreSQL

Následují tři příklady dotazů, které lze snadno provést pomocí databáze SQL.

  • Zobrazit všechny skladby interpreta;
  • Zobrazit všechny skladby interpreta, které odpovídají první části názvu;
  • Zobrazit všechny skladby od interpreta, které mají v názvu určité slovo a mají cenu nižší než 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

Z výše uvedených PostgreSQL dotazů bude v Cassandře fungovat beze změny pouze první, protože příkaz LIKE nelze použít na shlukování sloupců, jako je např SongTitle. V tomto případě jsou povoleni pouze operátoři = и 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

Jak je ukázáno v předchozích příkladech, hlavní metodou pro vytváření dotazů v MongoDB je db.collection.find(). Tato metoda explicitně obsahuje název kolekce (music v příkladu níže), takže dotazování na více kolekcí není povoleno.

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

Čtení všech řádků tabulky

Čtení všech řádků je jen speciální případ vzoru dotazu, o kterém jsme hovořili dříve.

PostgreSQL

SELECT * 
FROM Music;

Cassandra

Podobně jako v příkladu PostgreSQL výše.

MongoDB

db.music.find( {} );

Editace dat v tabulce

PostgreSQL

PostgreSQL poskytuje prohlášení UPDATE pro změnu údajů. Nemá žádnou příležitost UPSERT, takže tento příkaz selže, pokud řádek již není v databázi.

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

Cassandra

Cassandra má UPDATE podobně jako PostgreSQL. UPDATE má stejnou sémantiku UPSERT, jako INSERT.

Podobně jako v příkladu PostgreSQL výše.

MongoDB
Operace aktualizace () v MongoDB dokáže kompletně aktualizovat existující dokument nebo aktualizovat jen určitá pole. Ve výchozím nastavení aktualizuje pouze jeden dokument se zakázanou sémantikou UPSERT. Aktualizace více dokumentů a podobné chování UPSERT lze použít nastavením dalších příznaků pro operaci. Jako například v příkladu níže je žánr konkrétního umělce aktualizován jeho skladbou.

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

Odstranění dat z tabulky

PostgreSQL

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

Cassandra

Podobně jako v příkladu PostgreSQL výše.

MongoDB

MongoDB má dva typy operací pro mazání dokumentů − deleteOne() /deleteMany() и odstranit(). Oba typy odstraní dokumenty, ale vrátí jiné výsledky.

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

Smazání tabulky

PostgreSQL

DROP TABLE Music;

Cassandra

Podobně jako v příkladu PostgreSQL výše.

MongoDB

db.music.drop();

Závěr

Debata o výběru mezi SQL a NoSQL zuří již více než 10 let. Tato debata má dva hlavní aspekty: architektura databázového stroje (monolitický, transakční SQL vs. distribuovaný, netransakční NoSQL) a přístup k návrhu databáze (datové modelování v SQL vs. modelování vašich dotazů v NoSQL).

S distribuovanou transakční databází, jako je YugaByte DB, lze debatu o architektuře databáze snadno rozptýlit. Vzhledem k tomu, že objemy dat jsou větší než objemy, které lze zapsat do jednoho uzlu, je nezbytná plně distribuovaná architektura, která podporuje lineární škálovatelnost zápisu s automatickým sdílením/rebalancováním.

Kromě toho, co bylo řečeno v jednom z článků Google CloudTransakční, silně konzistentní architektury jsou nyní více přijímány, aby poskytovaly lepší flexibilitu vývoje než netransakční, v konečném důsledku konzistentní architektury.

Vrátíme-li se k diskusi o návrhu databáze, je spravedlivé říci, že oba přístupy k návrhu (SQL a NoSQL) jsou nezbytné pro jakoukoli komplexní aplikaci v reálném světě. Přístup SQL „modelování dat“ umožňuje vývojářům snadněji plnit měnící se obchodní požadavky, zatímco přístup „modelování dotazů“ NoSQL umožňuje stejným vývojářům zpracovávat velké množství dat s nízkou latencí a vysokou propustností. Z tohoto důvodu YugaByte DB poskytuje SQL a NoSQL API ve společném jádru a neobhajuje žádný z přístupů. Kromě toho, poskytnutím kompatibility s populárními databázovými jazyky, včetně PostgreSQL a Cassandra, YugaByte DB zajišťuje, že se vývojáři nemusí učit další jazyk, aby mohli pracovat s distribuovaným silně konzistentním databázovým strojem.

V tomto článku jsme se podívali na to, jak se liší základy návrhu databáze mezi PostgreSQL, Cassandrou a MongoDB. V následujících článcích se ponoříme do pokročilých konceptů návrhu, jako jsou indexy, transakce, JOINy, direktivy TTL a dokumenty JSON.

Přejeme vám krásný víkend a zveme vás webinář zdarmakterý se bude konat 14. května.

Zdroj: www.habr.com

Přidat komentář