binární formáty

19. 9. 2025 8:24 Živoslav Petr Bolf
Porovnání binárních formátů pro přenos dat, novější json-like vs. starší interní používané relačními databázemi. 

porovnej bson msgpack a formáty, které pro přenos dat pouziva MySQL a PostgreSQL

Skvěle zacílená otázka. Porovnání těchto formátů je vlastně srovnání dvou velmi rozdílných světů:

  1. Obecné binární sérializační formáty (BSON, MessagePack): Jejich hlavním účelem je efektivně zabalit (sérializovat) data do binární podoby pro přenos nebo uložení. Jsou agnostické vůči aplikaci, která je používá.
  2. Specializované komunikační protokoly (MySQL, PostgreSQL): Jejich hlavním účelem je přenos příkazů a výsledků mezi klientem a serverem relační databáze. Data jsou jejich náplní, ale formát musí zahrnovat i metadata, stavové kódy a další informace nutné pro komunikaci.

1. BSON (Binary JSON)

  • Původ a účel: Vytvořeno společností MongoDB pro efektivnější ukládání a dotazování dokumentů ve srovnání s plain-text JSON. Zachovává si JSON-like strukturu (klíč-hodnota, pole, vnořené dokumenty).
  • Klíčové vlastnosti:
    • Přidává binární datové typy, které JSON nemá (např. BinData, Date, UUID, Timestamp).
    • Obsahuje délky řetězců a objektů, což umožňuje rychlejší procházení dokumentem bez parsování celého obsahu (skákání na konkrétní pozice).
    • Obvykle větší velikost než MessagePack nebo JSON, kvůli metadatům (těmto délkám) pro rychlý přístup.

2. MessagePack (MsgPack)

  • Původ a účel: Obecný binární formát pro sérializaci, který se snaží být co nejmenší a nejefektivnější. Často popisován jako „binární JSON“.
  • Klíčové vlastnosti:
    • Extrémně kompaktní. Používá minimální metadata a efektivní kódování malých integerů a řetězců.
    • Jednodušší než BSON, nemá speciální datové typy jako BSON (ty se emulují pomocí základních typů).
    • Jeho hlavní a téměř jedinou výhodou je velikost a rychlost serializace/deserializace.

3. MySQL Client/Server Protocol

  • Původ a účel: Binární protokol pro komunikaci mezi klientem (např. vaše aplikace) a serverem MySQL.
  • Klíčové vlastnosti:
    • Není to jen formát dat. Je to protokol, který definuje rámce (packets), které nesou příkazy ( COM_QUERY, COM_STMT_EXECUTE), odpovědi, data, chyby a stavové informace.
    • Data (řádky výsledku) jsou přenášena v binárním formátu specifickém pro MySQL, často používajícím vlastní reprezentaci datových typů (např. MYSQL_TYPE_LONGMYSQL_TYPE_VARCHAR).
    • Pro připravené příkazy (prepared statements) se používají speciální pakety pro odeslání parametrů a výsledků, což je velmi efektivní.
    • Hlavním cílem je efektivní provedení dotazů a přenos výsledných sad, ne jen samotná serializace struktury dat.

4. PostgreSQL Frontend/Backend Protocol

  • Původ a účel: Binární protokol pro komunikaci mezi klientem a serverem PostgreSQL. Je velmi robustní a dobře zdokumentovaný.
  • Klíčové vlastnosti:
    • Podobně jako u MySQL, jde o komplexní protokol, ne jen formát dat.
    • Data mohou být přenášena v textové nebo binární reprezentaci. Binární formát je velmi efektivní.
    • Při volbě binárního formátu jsou datové typy přenášeny pomocí svých OID (Object Identifiers) a hodnoty jsou serializovány ve specifickém, optimalizovaném binárním layoutu pro daný typ (např. integer je 4 bajty, double je 8 bajtů ve strojovém pořadí bajtů).
    • Protokol definuje zprávy pro zahájení spojení, předávání parametrů, příkazy ( Parse, Bind, Execute) a podrobný přenos výsledků včetně metadat o sloupcích.

Srovnávací tabulka

Vlastnost BSON / MessagePack MySQL / PostgreSQL Protokol
Primární účel Sérializace struktur dat pro přenos/uložení Komunikace mezi klientem a databázovým serverem
Obsah Pouze data a jejich struktura Data + metadata (typ sloupce, chyby, stav, počet řádků) + příkazy ( SELECTINSERT)
Datové typy Obecné (string, number, bool, binární…) Specifické pro DB ( VARCHAR(255), INTEGER, TIMESTAMP WITH TIME ZONEJSONB)
Vztah k DB Datový formát, který může být uložen v DB Nosič, který přenáší vše, co DB potřebuje k práci
Optimalizace Rychlost (de)serializace, velikost Rychlost provedení dotazu, nízká režie spojení
Příklad {"name": "Alice", "age": 30} → binární blob COM_QUERYSELECT * FROM usersResultset (hlavička s typy sloupců → řádky v binárním formátu)

Praktické shrnutí a analogie

  • BSON a MessagePack jsou jako „krabice“.

    • Jsou skvělé na zabalení předmětu (dat) do standardizované krabice, kterou můžete poslat poštou (přes síť) nebo uložit do skladu (do DB/souboru). PostgreSQL může uložit MessagePack/BSONe do sloupce typu JSONB nebo  BYTEA.
  • MySQL a PostgreSQL protokoly jsou jako „logistický a komunikační proces“.

    • Představte si celý proces objednávky: vy (klient) řeknete „chci tohle“ (dotaz SELECT), skladník (server) potvrdí objednávku, najde zboží, zabalí ho na paletu (výsledek ve svém interním binárním formátu), přidá dodací list (metadata o sloupcích) a pošle vám ho. Samotná krabice (data) je jen součástí zásilky.

Závěr: Nejsou to přímo srovnatelné věci. BSON a MessagePack jsou formáty dat. MySQL a PostgreSQL protokoly jsou dopravní prostředky, které tyto formáty (a mnoho dalších věcí) přepravují. Databáze často používají své vlastní, highly optimized binární formáty pro přenos dat uvnitř svého protokolu, protože jsou přímo svázané s jejich interními datovými typy a strojovým kódem.

přenos záznamu z tabulky co zaznamu PostgreSQL a bson, srovnej velikost

Skvěle zacílený dotaz. Srovnání velikosti přenosu konkrétního záznamu odhaluje klíčový rozdíl mezi čistě datovým formátem (BSON) a komunikačním protokolem (PostgreSQL).

Provedeme srovnání na konkrétním příkladu.

Příklad: Záznam v tabulce users

Předpokládejme jednoduchou tabulku:

CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    age INTEGER,
    is_active BOOLEAN DEFAULT true,
    last_login TIMESTAMP
);

A jeden vzorový záznam:

INSERT INTO users (name, age, is_active, last_login)
VALUES ('Jan Novák', 30, true, '2024-05-15 14:32:10');

1. Velikost v BSON

BSON je formát pouze pro data. Sérializuje se do podoby, kterou lze uložit nebo přenést.

BSON reprezentace datového záznamu:

{
  "id": 1,
  "name": "Jan Novák",
  "age": 30,
  "is_active": true,
  "last_login": 1715783530000 // Unix timestamp v milisekundách
}

Odhadovaná velikost BSON:

  • Záhlaví dokumentu: ~4 bajty
  • id: 1 (typ int32): 1 bajt (typ) + 3 bajty (klíč „id“) + 4 bajty (hodnota) = ~8 bajtů
  • name: "Jan Novák" (typ string): 1 bajt (typ) + 5 bajtů (klíč „name“) + 4 bajty (délka řetězce) + 10 bajtů (utf-8 obsah) = ~20 bajtů
  • age: 30 (typ int32): 1 + 4 + 4 = ~9 bajtů
  • is_active: true (typ boolean): 1 + 9 + 1 = ~11 bajtů
  • last_login: 1715783530000 (typ datetime): 1 + 10 + 8 = ~19 bajtů
  • Ukončovací bajt dokumentu: 1 bajt

Přibližná celková velikost BSON dokumentu: ~72 bajtů.

Toto je čistá, zašifrovaná data bez jakékoli režie protokolu.


2. Velikost přenosu v PostgreSQL Protokolu

PostgreSQL protokol přenáší nejen data, ale i veškerou nutnou metainformaci. Při přenosu výsledku dotazu SELECT * FROM users server pošle:

  1. Row Description Message: Hlavička popisující každý sloupec ve výsledku.

    • Obsahuje: název sloupce, OID (ID datového typu), číslo datového typu, modifikátor typu, velikost sloupce atd.
    • Odhadovaná režie pro jeden sloupec: ~20–30 bajtů. Pro 5 sloupců tedy ~100–150 bajtů.
  2. Data Row Message: Samotná data záznamu.

    • Záhlaví zprávy: ~4 bajty (celková délka zprávy)
    • Počet sloupců: 2 bajty
    • Pro každý sloupec:
      • Délka hodnoty: 4 bajty ( pokud je hodnota NULL, je zde –1)
      • Samotná data.
    • Odhad velikosti datového řádku:
      • id (integer): 4 bajty (délka) + 4 bajty (data) = 8 bajtů
      • name (varchar): 4 bajty (délka) + 10 bajtů (data „Jan Novák“) = 14 bajtů
      • age (integer): 4 + 4 = 8 bajtů
      • is_active (boolean): 4 + 1 = 5 bajtů
      • last_login (timestamp): 4 + 8 = 12 bajtů
    • Celkem Data Row: ~4 (záhlaví) + 2 (počet sloupců) + (8+14+8+5+12) = ~53 bajtů.
  3. Command Completion Message: Zpráva o úspěšném provedení příkazu. (~10–15 bajtů).

Přibližná celková velikost přenosu pro jeden záznam: ~163 – 218 bajtů. (Row Description + Data Row + Completion)


Srovnávací tabulka

Vlastnost BSON (pouze data) PostgreSQL Protocol (přenos dotazu)
Obsah přenosu Pouze sérializovaná data záznamu. Data + Metadata (popis sloupců, stavové zprávy) + Režie protokolu.
Velikost pro příklad ~72 bajtů ~160–220 bajtů
Proč je rozdíl? BSON je úsporný kontejner na data. PG protokol je robustní nástroj, který musí přenést vše potřebné pro libovolný dotaz a jeho výsledek. Přenáší „manuál“ k datům (Row Description) spolu s daty samotnými.
Podpora datových typů Obecné (string, int, bool…). Může ztratit specifika (např. VARCHAR(100) vs  TEXT). Přesné a bohaté. Zachovává všechny specifika databázových typů (OID, modifikátory).
Čitelnost Binární (nečitelné bez deserializace). Binární (nečitelné bez znalosti protokolu).

Závěr a důsledky pro praxi

  • BSON je mnohem kompaktnější pro samotný záznam dat. Pokud potřebujete pouze přenést nebo uložit data, je BSON (nebo MessagePack) výrazně úspornější volba.
  • PostgreSQL protokol přenáší mnohem více informací. Jeho „nadbytečnost“ není chyba, ale vlastnost. Klient obdrží nejen data, ale i jejich detailní popis, což je nezbytné pro správné zpracování výsledku (např. pro knihovny jako psycopg2 nebo pq v Go). Tato režie je fixní a její relativní význam pro celkový přenos klesá s počtem vrácených řádků.
  • Scénáře použití:
    • BSON: Ideální pro ukládání dokumentů (MongoDB), přenos dat mezi mikroslužbami (v message brokerech), caching.
    • PostgreSQL Protocol: Jediná správná volba pro komunikaci klientské aplikace s PostgreSQL serverem. Poskytuje úplný kontext, bezpečnost a spolehlivost.

Analogii: Posíláte dopis. BSON je jen samotný text na papíře. PostgreSQL protokol je celá obálka i s adresou, razítkem pošty a doprovodnými formuláři, které zajistí, že dopis dojde správně a adresát mu porozumí.

Sdílet