sql >> Databáze >  >> RDS >> Mysql

Mysql:Uložte pole dat do jednoho sloupce

Za prvé, to opravdu nechcete dělat. Sloupec v RDBMS je zamýšlen jako atomický, protože obsahuje pouze jednu informaci. Pokus o uložení více než jedné části dat do sloupce je porušením prvního normálního formuláře.

Pokud to absolutně musíte udělat, musíte data převést do formuláře, který lze uložit jako jednu položku dat, obvykle řetězec. Můžete použít mechanismus serialize() PHP, analýzu XML (pokud jsou data náhodou strom dokumentu), json_encode() atd.

Jak se ale na taková data efektivně ptát? Odpověď je, že nemůžete.

Také, pokud někdo jiný převezme váš projekt později, budete ho opravdu otravovat, protože se serializovanými daty v databázi je hrozné pracovat. Vím to, protože jsem takové projekty zdědil.

Zmínil jsem se, že to opravdu nechceš udělat? Musíte přehodnotit svůj návrh, aby jej bylo možné snáze uložit z hlediska atomových řad. Pro tato data použijte například jinou tabulku a pomocí cizích klíčů je spojte s kmenovým záznamem. Z nějakého důvodu se jim říká relační databáze.

AKTUALIZACE :Byl jsem dotázán na požadavky na ukládání dat, například na to, zda by jeden řádek byl levnější z hlediska úložiště. Odpověď zní, v typických případech ne, není, a v případech, kdy je odpověď ano, cena, kterou za to zaplatíte, nestojí za to.

Pokud použijete tabulku se 2 sloupci (1 sloupec pro cizí klíč záznamu, do kterého vzorek patří, jeden pro jeden vzorek), pak bude každý sloupec vyžadovat v nejhorším případě 16 bajtů (8 bajtů pro sloupec longint klíče, 8 bajtů pro číslo s plovoucí desetinnou čárkou s dvojitou přesností). Pro 100 záznamů je to 1 600 bajtů (bez ohledu na režii db).

U serializovaného řetězce ukládáte v nejlepším případě 1 bajt na znak v řetězci. Nemůžete vědět, jak dlouhý bude řetězec, ale pokud předpokládáme, že 100 vzorků se všemi uloženými daty nějakou vymyšlenou shodou okolností všechny spadají mezi 10 000,00 a 99999,99, přičemž za desetinnou čárkou jsou vždy pouze 2 číslice, pak jste dívám se na 8 bajtů na vzorek. V tomto případě vše, co jste ušetřili, je režie cizích klíčů, takže velikost požadovaného úložiště vychází na 800 bajtů.

To je samozřejmě založeno na mnoha předpokladech, jako je kódování znaků vždy 1 bajt na znak, řetězce, které tvoří vzorky, nikdy nejsou delší než 8 znaků atd.

Ale samozřejmě je tu také režie jakéhokoli mechanismu, který používáte k serializaci dat. Absolutně nejjednodušší metoda, CSV, znamená přidání čárky mezi každý vzorek. To přidá n-1 bajtů k uloženému řetězci. Takže výše uvedený příklad by nyní měl 899 bajtů, a to s nejjednodušším schématem kódování. JSON, XML, dokonce i serializace PHP přidávají více režijních znaků než toto a brzy budete mít řetězce, které jsou mnohem delší než 1600 bajtů. A to vše s předpokladem 1 bajtového kódování znaků.

Pokud potřebujete indexovat vzorky, požadavky na data vzrostou ještě neúměrněji proti řetězcům, protože řetězcový index je z hlediska úložiště mnohem dražší než index sloupců s pohyblivou řádovou čárkou.

A samozřejmě, pokud vaše vzorky začnou přidávat další číslice, úložiště dat se zvýší. 39281.3392810 nebude možné uložit v 8 bajtech jako řetězec, a to ani v nejlepším případě.

A pokud jsou data serializována, databáze s nimi nemůže manipulovat. Nemůžete vzorky třídit, provádět s nimi jakékoli matematické operace, databáze ani neví, že jsou to čísla!

Abych byl upřímný, úložiště je v dnešní době směšně levné, můžete si koupit více TB disků za malé částky. Je úložiště opravdu tak kritické? Pokud nemáte stovky milionů záznamů, pochybuji, že ano.

Možná se budete chtít podívat na knihu s názvem SQL Antipatterns



  1. Příkaz SQL k vytvoření tabulky jako výsledek operace počítání?

  2. java.sql.SQLException:Pole nemá výchozí hodnotu

  3. jak napsat tento dotaz na vlastní připojení v mysql

  4. funkce oracle add_months se liší od Java