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
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.
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.
Jak již bylo uvedeno v článku
- 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
docker exec -it yb-postgres-n1 /home/yugabyte/postgres/bin/psql -p 5433 -U postgres
Cassandra
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
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 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 FROM
a 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 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 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ů −
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ů
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
Zdroj: www.habr.com