MySQL (7) - hrátky s čísly
Další trocha databázové teorie MySQL, dnes o ukládání čísel.
22.3.2005 15:00 |
Petr Zajíc
| Články autora
| přečteno 60672×
V předešlém díle jsme uvedli některé základní věci, které byste měli
znát při ukládání řetězců
do databáze MySQL. Dnes se podíváme na to, jak MySQL ukládá čísla.
Uvidíte,
že s tím může být docela zábava.
MySQL a celá čísla
Z programátorských důvodů existuje celá řada datových typů, do nichž
lze v
MySQL uložit celá čísla. Liší se zejména tím, jak velká čísla může
takový sloupec pojmout. Nejmenším celočíselným typem je TINYINT, který
může nabývat hodnot od -128 do +127, včetně. V praxi jej zřejmě moc
často nepoužijete, leda snad pro uložení čísel, které zkrátka nikdy
větší nebudou (například den v týdnu). Pro TINYINT je v databázi
potřeba jen jeden bajt místa.
SMALLINT je již rozsahem větší a bude se tedy používat
mnohem častěji. Uloží celá čísla od -32 768 do +32 767. S
oblibou jej
nasazuji třebas v účetních programech na číslování dokladů, málokdo má
totiž víc než 32767 dokladů v účetním roce. SMALLINT zabírá v databázi
dva bajty.
Potom má MySQL k dispozici datový typ MEDIUMINT. Slouží pro uložení
čísel od -8 388 608 do 8 388 607 (to je +-2^23). V
databázi zabírá tři
bajty a nemůžu si na něj zvyknout. Ono ve skutečnosti typu MEDIUMINT
nic není, jen se v některých DBMS systémech nevyskytuje a tak ho nemám
v krvi. Dokážu si ale docela dobře představit, že by se na spoustě míst
dal použít místo typu INTEGER, o němž je řeč níže. Tak třeba
automatická čísla řádků by klidně mohla být MEDIUMINT, protože obvykle stačí dimenzovat tabulku
na osm milionů řádků.
Datový typ INTEGER je naopak databázová klasika. Lze jej zkráceně
deklarovat jako INT a pojme celá čísla v rozpětí od
-2 147 483 648 do
2 147 483 647. Typicky se používá pro údaje sloužící k
číslování řádků,
protože pro většinu aplikací jsou dvě miliardy řádků v jedná tabulce
víc než dost. INTEGER zabere v databázi 4 bajty místa.
MySQL však jde ještě dál a "umí" uložit i větší celá čísla. Typ
BIGINT je schopen pracovat s numery od
-9 223 372 036 854 775 808 do
9 223 372 036 854 775 807. Tak veliké
číslo ani neumím přečíst ;-). Nenapadá mě žádný důvod, proč by v praxi
musel programátor sáhnout k používání něčeho tak obrovského. Snad jen
na nějaké vědeckotechnické výpočty. V manuálu je navíc popsáno, že
práce s tímto datovým typem přináší určitá úskalí, takže pokud jej
musíte používat, nastudujte to.
Celá čísla bez znaménka
Aby to s těmi čísly nebylo tak jednoduché, dodejme ještě, že MySQL
umožňuje použít v definici čísla klauzuli UNSIGNED ("bez znaménka"). To
způsobí, že se v daném typu budou skladovat pouze nezáporná čísla.
"Ušetřený" bajt se pak použije na zvýšení rozsahu čísla. Nejlépe se to
dá pochopit na
příkladu: TINYINT pojme čísla od -127 do +128, TINYINT UNSIGNED od 0 do
255. Neboli, stále se jedná o interval zahrnující 256 čísel, jsou však
"posunuta" tak, aby začínala nulou.
Tip: K automatickému číslování
řádků se obyčejně používají kladná
čísla (ačkoli to principielně není nutné). Dokážu si tedy představit
pro sloupec s automatickým číslem například použití typu MEDIUMINT
UNSIGNED, což mi dává rozsah od nuly
do 16 777 215.
Nepřesná desetinná čísla
Existují dva datové typy, které se v MySQL používají pro uložení
nepřesných desetinných čísel. Proč nepřesných? Protože při uložení
čísel v takovém případě dojde k jejich zaokrouhlení. Datové typy FLOAT
a DOUBLE se liší víceméně jen zobrazovaným rozsahem a počtem
desetinných míst. Rozsahy nebudu uvádět; jsou obrovské a jsou v manuálu.
Se zaokrouhlováním čísel typu FLOAT a DOUBLE je ale docela zábava.
Představte si například, že chcete do sloupce FLOAT a DOUBLE uložit
výsledek výpočtu "pět děleno třemi". Jak pravděpodobně víte, výsledkem
je číslo s nekonečným periodickým rozvojem a v databázi to dopadne tak,
že se do sloupce typu float uloží 1.66667 a do sloupce typu double
1.66666666666667.
Naštěstí můžete přesnost uložení trochu ovlivnit. U FLOAT a DOUBLE
můžete při jejich definici zadat požadovaný počet desetinných míst,
například FLOAT (10,5) nebo DOUBLE (20,10). Uvedené příklady znamenají
to, že:
- U FLOAT(10,5) se použije celkem deset znaků k zobrazení a pět
desetinných míst. Pět děleno třemi se uloží jako 1.66667. Číslo
500000:3 se ale uloží jako 99999.99999 a vznikne varování. Na uložení
tak velkého čísla je typ FLOAT(10,5) malý.
- U DOUBLE(20,10) se použije celkem dvacet znaků k zobrazení a 10
desetinných míst. Pět děleno třemi se uloží jako 1.6666666667. Číslo
500000:3 dopadne v pohodě jako 166666.6666666667.
Z toho, co bylo řečeno asi tušíte, že s nepřesnými desetinnými čísly
je docela potíž. Moje rada je: nepoužívejte je, pokud vysloveně
nemusíte. Rozhodně je nepoužívejte na uložení takových věcí, jako je
množství zboží ve faktuře nebo kupříkladu sazba DPH. Početními
operacemi s
nepřesnými čísly se totiž zaokrouhlovací chyby kumulují. Rvněž bídně
selže pokus nepřesná čísla nějak porovnávat nebo použít jako zákad pro
spojení. Když už musíte tato čísla porovnávat, použijte nějaké
intervaly. Takže namísto myšlenky typu:
jestliže [nepřesné
číslo] = 10000 tak ...
použijte (pokud opravdu musíte) něco ve smyslu
jestliže [nepřesné
číslo] >= 9999.9 a [nepřesné číslo] <= 10000.1 tak ...
je to ale poměrně otravné (a pomalé). Daleko lepší je používat
přesná desetinná čísla.
Přesná desetinná čísla
Existuje MySQL datový typ DECIMAL, který ukládá desetinná čísla s
pevnou čárkou. Deklaruje se jako DECIMAL (x,y), přičemž o parametrech
platí to, co bylo řečeno výše u typů FLOAT a DOUBLE. Protože ukládá
vnitřně čísla jako řetězec, netrpí chybami při zaokrouhlování. S
výhodou se používá pro uložení peněžních hodnot; některé DBMS mají
dokonce definován typ MONEY, který odpovídá DECIMAL (x,4).
Rozhodně doporučuji používat DECIMAL všude tam, kde se jedná o
peněžní hodnoty (například, v účetních programech) nebo o přesně
stanovitelné zlomky (třeba "půl kila hřebíků"). Teto typ je sice
teoreticky pomalejší než nepřesná čísla, ale konec potíží se
zaokrouhlováním za to ve většině případů stojí.
U všech typů desetinných čísel (přesných i nepřesných) můžete použít
příznak UNSIGNED. Jen pozor, funguje to jinak než u čísel celých. Stane
se to, že do sloupce nepůjdou uložit záporné hodnoty, ale rozsah
kladných hodnot, které sloupec pojme se nezvýší.
Překročení rozsahu
Upřímě řečeno mi způsob, jakým se MySQL chová při překročení rozsahu
sloupce vůbec nevyhovuje. Jestliže se totiž například do pole, kam má
být uložen TINYINT pokusíme vložit číslo mimo rozsah, příkaz NESELŽE,
vyvolá varování, a vloží NEJBLIŽÍ povolenou hodnotu (v případě TINYINT
tedy hodnotu 128). Ve většině případů tedy nepůjde při práci s MySQL
spoléhat na to, že při práci s čísly mimo rozsah skončí operace chybou
a bude se to moci nějak řešit. Pamatujte na to; toto chování vede k
tomu, že v databázi můžete mít hodnoty, které jste tam nezadali!
Verze pro tisk
|
Příspívat do diskuze mohou pouze registrovaní uživatelé.
|
|

Vyhledávání software

Vyhledávání článků
28.11.2018 23:56 /František Kučera Prosincový sraz spolku OpenAlt se koná ve středu 5.12.2018 od 16:00 na adrese Zikova 1903/4, Praha 6. Tentokrát navštívíme organizaci CESNET. Na programu jsou dvě přednášky: Distribuované úložiště Ceph (Michal Strnad) a Plně šifrovaný disk na moderním systému (Ondřej Caletka). Následně se přesuneme do některé z nedalekých restaurací, kde budeme pokračovat v diskusi.
Komentářů: 1
12.11.2018 21:28 /Redakce Linuxsoft.cz 22. listopadu 2018 se koná v Praze na Karlově náměstí již pátý ročník konference s tématem Datová centra pro business, která nabídne odpovědi na aktuální a často řešené otázky: Jaké jsou aktuální trendy v oblasti datových center a jak je optimálně využít pro vlastní prospěch? Jak si zajistit odpovídající služby datových center? Podle jakých kritérií vybírat dodavatele služeb? Jak volit vhodné součásti infrastruktury při budování či rozšiřování vlastního datového centra? Jak efektivně datové centrum spravovat? Jak co nejlépe eliminovat možná rizika? apod. Příznivci LinuxSoftu mohou při registraci uplatnit kód LIN350, který jim přinese zvýhodněné vstupné s 50% slevou.
Přidat komentář
6.11.2018 2:04 /František Kučera Říjnový pražský sraz spolku OpenAlt se koná v listopadu – již tento čtvrtek – 8. 11. 2018 od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5). Tentokrát bez oficiální přednášky, ale zato s dobrým jídlem a pivem – volná diskuse na téma umění a technologie, IoT, CNC, svobodný software, hardware a další hračky.
Přidat komentář
4.10.2018 21:30 /Ondřej Čečák LinuxDays 2018 již tento víkend, registrace je otevřená.
Přidat komentář
18.9.2018 23:30 /František Kučera Zářijový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 20. 9. 2018 od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5). Tentokrát bez oficiální přednášky, ale zato s dobrým jídlem a pivem – volná diskuse na téma IoT, CNC, svobodný software, hardware a další hračky.
Přidat komentář
9.9.2018 14:15 /Redakce Linuxsoft.cz 20.9.2018 proběhne v pražském Kongresovém centru Vavruška konference Mobilní řešení pro business.
Návštěvníci si vyslechnou mimo jiné přednášky na témata: Nejdůležitější aktuální trendy v oblasti mobilních technologií, správa a zabezpečení mobilních zařízení ve firmách, jak mobilně přistupovat k informačnímu systému firmy, kdy se vyplatí používat odolná mobilní zařízení nebo jak zabezpečit mobilní komunikaci.
Přidat komentář
12.8.2018 16:58 /František Kučera Srpnový pražský sraz spolku OpenAlt se koná ve čtvrtek – 16. 8. 2018 od 19:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát jsou tématem srazu databáze prezentaci svého projektu si pro nás připravil Standa Dzik. Dále bude prostor, abychom probrali nápady na využití IoT a sítě The Things Network, případně další témata.
Přidat komentář
16.7.2018 1:05 /František Kučera Červencový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 19. 7. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát bude přednáška na téma: automatizační nástroj Ansible, kterou si připravil Martin Vicián.
Přidat komentář
Více ...
Přidat zprávičku
 Poslední diskuze
31.7.2023 14:13 /
Linda Graham iPhone Services
30.11.2022 9:32 /
Kyle McDermott Hosting download unavailable
13.12.2018 10:57 /
Jan Mareš Re: zavináč
2.12.2018 23:56 /
František Kučera Sraz
5.10.2018 17:12 /
Jakub Kuljovsky Re: Jaký kurz a software by jste doporučili pro začínajcího kodéra?
Více ...
|