Základy modelování dat - PostgreSQL vs. Cassandra vs. MongoDB

Vývojáři aplikací obvykle tráví značným časem vyhodnocováním více operačních databází, aby našli jednu databázi, která nejlépe vyhovuje jejich potřebám pracovního vytížení. Mezi tyto potřeby patří zjednodušené modelování dat, transakční záruky, výkon čtení / zápisu, horizontální škálování a odolnost proti chybám. Tradičně tento výběr začíná databázovými kategoriemi SQL vs. NoSQL, protože každá kategorie představuje jasnou sadu kompromisů. Vysoký výkon z hlediska nízké latence a vysoké propustnosti je obvykle považován za nekompromisní požadavek, a proto se očekává u každé vybrané databáze.

Cílem tohoto příspěvku je pomoci vývojářům aplikací pochopit volbu SQL vs. NoSQL v kontextu potřeb datového modelování aplikace. Jako příklady vysvětlujeme základy modelování dat, jako je vytváření tabulek, vkládání dat, provádění skenování a mazání dat, jednu databázi SQL, jmenovitě PostgreSQL, a 2 databáze NoSQL, jmenovitě Cassandra a MongoDB. V následném příspěvku se budeme zabývat pokročilými tématy, jako jsou indexy, transakce, připojení, směrnice o životu (TTL) a modelování dat dokumentů založené na JSON.

Jak se NoSQL liší od SQL v modelování dat?

SQL databáze zvyšují agilitu aplikací prostřednictvím ACID transakčních záruk, jakož i jejich schopnosti dotazovat data pomocí JOINs nepředvídanými způsoby nad stávajícími normalizovanými relačními datovými modely.

Vzhledem k jejich monolitické architektuře / uzlu s jedním uzlem a použití replikačního modelu master-slave pro redundanci postrádají tradiční databáze SQL dvě důležité funkce - lineární škálovatelnost zápisu (tj. Automatické shardování napříč několika uzly) a automatické převzetí služeb při selhání / nulové ztrátě dat. To znamená, že přijaté objemy dat nemohou překročit maximální propustnost zápisu jednoho uzlu. Navíc by se mělo očekávat určitou dočasnou ztrátu dat při převzetí služeb při selhání (na architekturách sdílených úložišť nic), vzhledem k tomu, že nedávné závazky by se dosud neobjevily v replice slave. Ve světě databází SQL je také velmi obtížné dosáhnout nulových upgradů na prostoje.

NoSQL DB jsou obvykle distribuovány v přírodě, kde jsou data rozdělena do různých uzlů. Pověřují denormalizaci, což znamená, že vložená data je také třeba zkopírovat vícekrát, aby sloužily konkrétním dotazům, které máte na mysli. Hlavním cílem je extrahovat vysoký výkon explicitním snížením počtu střepů, ke kterým se během čtecího času dostanete. Proto prohlášení, že NoSQL vyžaduje modelování dotazů, zatímco SQL vyžaduje modelování dat.

Zaměření NoSQL na dosažení vysokého výkonu v distribuovaném klastru je uvedeno jako primární zdůvodnění kompromisů s více datovými modely, které zahrnují ztrátu transakcí ACID, JOIN a konzistentní globální sekundární indexy.

Obecně je vnímáno, ž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 popisuje, jak se NoSQL modelování dat liší od SQL.

SQL vs. NoSQL - klíčové rozdíly v modelování dat

SQL & NoSQL: Proč potřebujete oba?

Většina aplikací v reálném světě se zajímavými uživatelskými zkušenostmi, jako jsou Amazon.com, Netflix, Uber a Airbnb, je interně poháněna složitou směsí více pracovních zátěží. Např. e-commerce aplikace, jako je Amazon.com, musí ukládat nízkoobjemová, vysoce kritická data, jako jsou uživatelé, produkty, objednávky, faktury, vedle velkoobjemových, méně kritických dat, jako jsou recenze produktů, zprávy helpdesku, uživatelská aktivita, doporučení uživatelů. Tyto aplikace se přirozeně spoléhají na alespoň jednu databázi SQL spolu s alespoň jednou databází NoSQL. Ve více regionech a globálních implementacích funguje databáze NoSQL také jako geo-distribuovaná mezipaměť pro data uložená ve zdroji pravdy, databáze SQL běžící v jediné oblasti.

Jak YugaByte DB spojuje SQL a NoSQL do společného databázového jádra?

YugaByte DB, postavená na jedinečné kombinaci logového strukturovaného slučovacího úložiště, automatického shardingu, distribuované konsenzuální replikace na shard a distribuovaných transakcí ACID (inspirovaných Google Spanner), je první otevřenou zdrojovou databází na světě, která je NoSQL (Cassandra & Redis) kompatibilní) a SQL (kompatibilní s PostgreSQL). Jak je uvedeno v tabulce níže, YCQL, YugaByte DB Cassandra kompatibilní API, přidává pojem NoSQL API s jedním klíčem a více klíči ACID a globální sekundární indexy, čímž se stává érou transakčního NoSQL. Navíc rozhraní YSQL, rozhraní YugaByte DB kompatibilní s PostgreSQL, přidává do rozhraní API SQL pojmy lineárního měřítka zápisu a automatické odolnosti proti chybám, čímž se přináší svět distribuovaného SQL. Jelikož je YugaByte DB v jádru transakční, mohou být i API NoSQL nyní použita v kontextu kritických dat.

YugaByte DB - SQL a NoSQL na jediném databázovém jádru

Jak bylo dříve popsáno v Představení YSQL: PostgreSQL Compatible Distributed SQL API pro YugaByte DB, výběr SQL vs. NoSQL v YugaByte DB závisí zcela na charakteristikách většinové pracovní zátěže.

  • Pokud je většina pracovní zátěže operace s více klíči s JOINS, vyberte YSQL s vědomím, že vaše klíče mohou být distribuovány do více uzlů, což vede k vyšší latenci a / nebo nižší propustnosti než NoSQL.
  • V opačném případě vyberte jedno ze dvou rozhraní NoSQL API s vědomím, že získáte vyšší výkonnostní výhody vyplývající z dotazů, které jsou primárně obsluhovány z jednoho uzlu najednou. YugaByte DB může sloužit jako sjednocená operační databáze pro komplexní aplikace v reálném světě, které obvykle spravují více pracovních zátěží současně.

Laboratoř pro modelování dat v další části vychází z rozhraní API YugaByte DB kompatibilních s PostgreSQL a Cassandra, oproti původním databázím. Tento přístup zdůrazňuje jednoduchost interakce se dvěma různými API (na dvou různých portech) stejného databázového klastru, na rozdíl od použití zcela nezávislých klastrů dvou různých databází.

V následujících sekcích si projdeme datové modelování, které se věnuje laboratoři, abychom ilustrovali mnoho rozdílů a několik společných rysů mezi různými databázemi.

Laboratoř modelování dat

Nainstalujte databáze

Vzhledem k zaměření na modelování dat (a nikoli na složité architektury nasazení) nainstalujeme databáze do kontejnerů Docker na našich místních počítačích a pak s nimi interagujeme pomocí jejich příslušných prostředí příkazového řádku.

YugaByte DB, databáze kompatibilní s PostgreSQL a Cassandra

mkdir ~ / yugabyte && cd ~ / yugabyte
wget https://downloads.yugabyte.com/yb-docker-ctl && chmod + x yb-docker-ctl
ukotvit tahač yugabytedb / yugabyte
./yb-docker-ctl create --enable_postgres

MongoDB

docker run - jméno my-mongo -d mongo: nejnovější

Přístup pomocí prostředí příkazového řádku

Dále se připojíme k databázím pomocí prostředí příkazového řádku pro příslušná rozhraní API.

PostgreSQL

psql je prostředí příkazového řádku pro interakci s PostgreSQL. Pro snadné použití je YugaByte DB dodáván s verzí psql v adresáři bin.

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

Cassandra

cqlsh je prostředí 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 verzí cqlsh v adresáři bin.

Všimněte si, že CQL je silně inspirováno SQL s podobnou představou o tabulkách, řádcích, sloupcích a indexech. Jako jazyk NoSQL však přidává specifickou sadu omezení, z nichž většinu přezkoumáme během naší série blogů.

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

MongoDB

mongo je prostředí příkazového řádku pro interakci s MongoDB. Najdete ji v adresáři bin instalace MongoDB.

docker exec -it my-mongo bash
cd bin
mongo

Vytvořte tabulku

Nyní můžeme pracovat s databází pro různé operace pomocí prostředí příkazového řádku. Začněme vytvořením tabulky, ve které budou uloženy informace o skladbách publikovaných umělci. Tyto písně jsou někdy součástí alba. Další volitelné atributy písně jsou rok vydání, cena, žánr a kritika. Potřebujeme účet pro další atributy, které můžeme v budoucnu potřebovat, pomocí pole „značky“, které může ukládat polostrukturovaná data jako páry klíč-hodnota.

PostgreSQL

VYTVOŘIT TABULKU Hudba (
    Umělec VARCHAR (20) NOT NULL,
    SongTitle VARCHAR (30) NOT NULL,
    AlbumTitle VARCHAR (25),
    Year INT,
    Cena FLOAT,
    Žánr VARCHAR (10),
    CriticRating FLOAT,
    Štítky TEXT,
    PRIMARY KEY (Artist, SongTitle)
);

Cassandra

Vytvoření tabulky v Cassandře je velmi podobné tabulce PostgreSQL. Velkým rozdílem je nedostatek integritních omezení (například NOT NULL), což je zodpovědnost aplikace a ne databáze ve světě NoSQL. Primární klíč se skládá z klíče oddílu (sloupec Artist v příkladu níže) a sady klastrových sloupců (sloupec SongTitle v příkladu níže). Klíč oddílu určuje, do kterého oddílu / shardu se má řádek umístit, a sloupce shlukování určují, jak mají být data uvnitř daného střepu uspořádána.

VYTVOŘTE KEYSPACE myapp;
USE myapp;
VYTVOŘIT TABULKU Hudba (
    Umělec TEXT,
    SongTitle TEXT,
    AlbumTitle TEXT,
    Year INT,
    Cena FLOAT,
    Žánr TEXT,
    CriticRating FLOAT,
    Štítky TEXT,
    PRIMARY KEY (Artist, SongTitle)
);

MongoDB

MongoDB organizuje data v databázích (ekvivalent k Cassandra Keyspace), které mají sbírky (ekvivalent k tabulkám), které mají dokumenty (ekvivalent k řádku v tabulce). Jako databáze „schemaless“ není v MongoDB nutné definovat schéma předem. Příkaz „use database“ uvedený níže vytvoří instanci databáze hned při prvním vyvolání spolu se změnou kontextu na nově vytvořenou databázi. Dokonce ani kolekce nemusí být vytvořeny explicitně, ale jsou spíše vytvářeny automaticky jednoduchým vložením prvního dokumentu do nové kolekce. Všimněte si, že výchozí databáze MongoDB je testována, takže jakékoli operace na úrovni kolekce provedené bez zadání databáze budou provedeny v tomto výchozím kontextu.

použijte myNewDatabase;

Získejte informace o tabulce

PostgreSQL

\ d Hudba
Tabulka „public.music“
    Sloupec | Typ | Srovnání | Nullable | Výchozí
-------------- + ----------------------- + ----------- + ---------- + --------
 umělec měnící se charakter (20) | | není nulová |
 název skladby měnící se charakter (30) | | není nulová |
 název alba | měnící se charakter (25) | | |
 rok | celé číslo | | |
 cena | dvojitá přesnost | | |
 žánr | měnící se charakter (10) | | |
 kritizující | dvojitá přesnost | | |
 tagy | text | | |
Indexy:
    "music_pkey" PRIMARY KEY, btree (umělec, název skladby)

Cassandra

POPIS TABULKA HUDBA;
VYTVOŘIT TABULKU myapp.music (
    text umělce,
    text titulů,
    text názvu alba,
    rok int,
    cena float,
    žánrový text,
    tagy text,
    PRIMARY KEY (umělec, název skladby)
) S OBCHODNÍM OBJEDNÁVKEM PODLE (songtitle ASC)
    AND default_time_to_live = 0
    AND transakce = {'enabled': 'false'};

MongoDB

použijte myNewDatabase;
zobrazit sbírky;

Vložte data do tabulky

PostgreSQL

VLOŽTE DO Hudba
    (Umělec, SongTitle, AlbumTitle,
    Rok, Cena, Žánr, Kritické hodnocení,
    Značky)
HODNOTY (
    "Nikdo, koho znáš", "Zavolej mi dnes", "Trochu slavný",
    2015, 2,14, „Země“, 7,8,
    '{"Skladatelé": ["Smith", "Jones", "Davis"], "LengthInSeconds": 214}'
);
VLOŽTE DO Hudba
    (Umělec, SongTitle, AlbumTitle,
    Cena, žánr, kritika)
HODNOTY (
    "Nikdo, koho znáš", "My Dog Spot", "Hey Now",
    1,98, „Země“, 8.4
);
VLOŽTE DO Hudba
    (Umělec, SongTitle, AlbumTitle,
    Cena, žánr)
HODNOTY (
    „The Acme Band“, „Look Out, World“, „Buck začíná zde“,
    0,99, 'Rock'
);
VLOŽTE DO Hudba
    (Umělec, SongTitle, AlbumTitle,
    Cena, Žánr,
    Značky)
HODNOTY (
    „The Acme Band“, „Stále v lásce“, „Buck začíná zde“,
    2,47, 'Rock',
    '{"radioStationsPlaying": ["KHCR", "KBQX", "WTNR", "WJJH"], "tourDates": {"Seattle": "20150625", "Cleveland": "20150630"}, "rotace": Těžký}'
);

Cassandra

Příkazy Cassandra INSERT vypadají velmi podobně jako PostgreSQL obecně. Existuje však jeden velký rozdíl v sémantice. INSERT je vlastně operace upert v Cassandře, kde je řádek aktualizován o nejnovější hodnoty v případě, že již existuje.

Stejné jako výše uvedené příkazy PostgreSQL INSERT.

MongoDB

I když MongoDB je také databáze NoSQL podobná Cassandře, její operace vložení nemá stejné sémantické chování jako Cassandra. MongoDB insert () nemá žádnou upert možnost, díky které je podobná PostgreSQL. Výchozí chování vložení bez zadaného _idspecifikování povede k přidání nového dokumentu do kolekce.

db.music.insert ({
umělec: "Nikdo nevíš",
   songTitle: "Call Me Today",
    albumTitle: „Poněkud slavné“,
    rok: 2015,
    cena: 2,14,
    žánr: „Country“,
    tagy: {
Skladatelé: [„Smith“, „Jones“, „Davis“],
Délka v sekundách: 214
}
   }
);
db.music.insert ({
    umělec: "Nikdo nevíš",
    songTitle: "My Dog Spot",
    albumTitle: "Hey Now",
    cena: 1,98,
    žánr: „Country“,
    critRating: 8.4
   }
);
db.music.insert ({
    umělec: "The Acme Band",
    songTitle: "Look Out, World",
    albumTitle: "The Buck začíná zde",
    cena: 0,99,
    žánr: "Rock"
   }
);
db.music.insert ({
    umělec: "The Acme Band",
    songTitle: "Stále v lásce",
    albumTitle: "The Buck začíná zde",
    cena: 2,47,
    žánr: "Rock",
    tagy: {
        radioStationsPlaying: ["KHCR", "KBQX", "WTNR", "WJJH"],
        tourDates: {
            Seattle: "20150625",
            Cleveland: "20150630"
        },
        rotace: "Heavy"
}
    }
);

Dotaz na tabulku

Pravděpodobně nejvýznamnějším rozdílem mezi SQL a NoSQL, pokud jde o modelovací dotazy, je použití klauzulí FROM a WHERE. SQL umožňuje klauzuli FROM zahrnovat více tabulek a klauzule WHERE má libovolnou složitost (včetně spojení JOIN napříč tabulkami). NoSQL však má tendenci k přísnému omezení klauzule FROM mít zadanou pouze jednu tabulku a klauzuli WHERE vždy mít určený primární klíč. Důvodem je vysoké zaměření na výkon NoSQL, o kterém jsme diskutovali dříve, jehož cílem je omezit interakci napříč tabulkami a křížovými klávesami. Taková interakce může zavést komunikaci s vysokými latencemi mezi uzly do doby odezvy na dotaz, a proto je nejlepší se úplně vyhnout. Např. Cassandra vyžaduje, aby dotazy byly omezeny operátory (pouze =, IN, <,>, =>, <= jsou povoleny) na klíčích oddílů, s výjimkou dotazů na sekundární index (kde je povolen pouze = operátor).

PostgreSQL

Následuje 3 typy dotazů, které lze snadno obsluhovat pomocí databáze SQL.

  • Vraťte všechny skladby od interpreta
  • Vraťte všechny skladby od interpreta, který odpovídá první části názvu
  • Vraťte všechny skladby od interpreta s konkrétním slovem v názvu, ale pouze pokud je cena nižší než 1,00
VÝBĚR * Z Hudba
WHERE Artist = 'Nikdo, koho znáš';
VÝBĚR * Z Hudba
WHERE Artist = 'Nikdo nevíš' A SongTitle LIKE 'Call%';
VÝBĚR * Z Hudba
WHERE Artist = 'Nikdo nevíš' A SongTitle LIKE '% Today%'
A Cena> 1,00;

Cassandra

Z výše uvedených PostgreSQL dotazů bude pouze první pracovat s Cassandrou beze změny, protože operátor LIKE není povolen ve shlucích sloupců, jako je SongTitle. V tomto případě jsou povoleny pouze operátory = a IN.

VÝBĚR * Z Hudba
WHERE Artist = 'Nikdo, koho znáš';
VÝBĚR * Z Hudba
KDE Artist = 'Nikdo nevíš' A SongTitle IN ('Call Me Today', 'My Dog Spot')
A Cena> 1,00;

MongoDB

Jak je ukázáno v předchozích příkladech, primární metodou pro dotazování MongoDB je metoda db.collection.find (). Tato metoda je kvalifikována podle názvu kolekce (hudba v příkladu níže), aby byla dotazována velmi explicitně, takže dotazování napříč kolekcemi je výslovně zakázáno.

db.music.find ({
  umělec: "Nikdo nevíš"
 }
);
db.music.find ({
  umělec: "Nikdo nevíš",
  songTitle: / Call /
 }
);

Přečtěte si všechny řádky z tabulky

Čtení všech řádků je jednoduše zvláštním případem obecného vzorce dotazu, který jsme pozorovali dříve.

PostgreSQL

VYBRAT *
Z Hudba;

Cassandra

Stejné jako výše uvedený příkaz PostgreSQL SELECT.

MongoDB

db.music.find ({});

Upravit data v tabulce

PostgreSQL

PostgreSQL poskytuje příkaz UPDATE pro úpravu dat. Nepovoluje žádnou možnost upert, takže příkaz selže, pokud řádek v databázi již neexistuje.

AKTUALIZUJTE hudbu
SET Žánr = 'Disco'
WHERE Artist = 'The Acme Band' A SongTitle = 'Stále v lásce';

Cassandra

Cassandra má také příkaz UPDATE podobný PostgreSQL. UPDATE také má stejnou sémantiku jako u příkazu INSERT.

Stejné jako výše uvedený příkaz PostgreSQL UPDATE.

MongoDB

Operace MongoDB update () může aktualizovat existující dokument úplně nebo může aktualizovat pouze specifická pole. Ve výchozím nastavení aktualizuje pouze jeden dokument s vypnutou sémantikou. Aktualizace více dokumentů a chování upert lze zapnout nastavením dalších příznaků operace. Např. níže uvedený příklad aktualizuje žánr konkrétního umělce napříč jeho písněmi.

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

Odstranit data z tabulky

PostgreSQL

ODSTRANIT Z Hudba
KDE Artist = 'The Acme Band' A SongTitle = 'Look Out, World';

Cassandra

Stejné jako výše uvedený příkaz PostgreSQL DELETE.

MongoDB

MongoDB má dva typy operací pro odstranění dokumentů - deleteOne () / deleteMany () a remove (). Oba dokumenty odstraňují, ale mají odlišné výsledky návratu.

db.music.deleteMany ({
        umělec: "The Acme Band"
    }
);

Odebrat tabulku

PostgreSQL

DROP TABLE Hudba;

Cassandra

Stejné jako výše uvedený příkaz PostgreSQL DROP TABLE;

MongoDB

db.music.drop ();

souhrn

Debata SQL vs. NoSQL nyní zuří už deset let. Tato debata má 2 aspekty: architektura jádra databáze (monolitická, transakční SQL vs. distribuovaná, netransakční NoSQL) a přístup k modelování dat (modelování vašich dat v SQL vs. modelování vašich dotazů v NoSQL).

S distribuovanou transakční databází, jako je YugaByte DB, lze jádro debaty o architektuře jádra snadno položit. Protože objemy dat přesahují rámec toho, co lze zapsat do jednoho uzlu, nutnou je plně distribuovaná architektura, která umožňuje lineární škálovatelnost zápisu s automatickým sharding / rebalancing. Navíc, jak je popsáno v tomto příspěvku od Google Cloud, transakční, silně konzistentní architektury jsou nyní široce přijímány, aby poskytovaly vyšší vývojářskou a provozní flexibilitu než neobchodní, případně konzistentní architektury.

Pokud jde o debatu o modelování dat, je spravedlivé říci, že přístupy pro modelování dat SQL i NoSQL jsou nezbytné pro jakoukoli komplexní aplikaci v reálném světě. Přístup SQL model-vaše-data umožňuje vývojářům snáze reagovat na měnící se obchodní požadavky, zatímco přístup NoSQL model-vaše-dotazy umožňuje stejným vývojářům spravovat velké objemy dat s nízkou latencí a vysokou propustností. To je přesně důvod, proč YugaByte DB implementuje API SQL i NoSQL do společného jádra místo toho, aby propagoval, že jeden přístup je přísně lepší než druhý. Kromě toho zajišťuje YugaByte DB zajištěním kompatibility s populárními databázovými jazyky včetně PostgreSQL a Cassandra, že vývojáři se nenaučí jiný jazyk, aby mohli těžit z distribuovaného silně konzistentního jádra databáze.

Tento příspěvek nám pomohl pochopit, jak se základy modelování dat liší mezi PostgreSQL, Cassandra a MongoDB. V dalších příspěvcích v sérii se seznámíme s pokročilými koncepty modelování dat, jako jsou indexy, transakce, JOIN, směrnice TTL a dokumenty JSON.

Co bude dál?

  • Porovnejte YugaByte DB s databázemi jako Amazon DynamoDB, Cassandra, MongoDB a Azure Cosmos DB.
  • Začínáme s YugaByte DB na počítačích MacOS, Linux, Docker a Kubernetes.
  • Kontaktujte nás, chcete-li se dozvědět více o licencích, cenách nebo naplánovat technický přehled.

Původně publikováno na blogu databáze YugaByte.