Ukládání datumů v databázi
Ve většině databází je k dispozici speciální typ pro ukládání datumu kalendářního data – obvykle se jmenuje DATE. Já ho mám rád a používám ho, někdo ale tvrdošíjně pro ukládání datumu používá obyčejné číslo, obvykle ve významu UNIX_TIMESTAMP a argumentuje tím, že se s ním pohodlněji pracuje. To jednak není pravda a jednak je chyba nevyužívat existující infrastrukturu – kvůli tomu vznikl problém roku 2000 a kvůli tomu bude problém i s rokem 2038 (kdy 32bitový timestamp přeteče).
Zdánlivá vyšší jednoduchost práce s datumem uloženým v čísle je při jeho formátování:
<?php
$row = mysql_fetch_assoc(mysql_query("SELECT * FROM diskuse"));
// datum uložený v číselném sloupci
echo date("j.n.Y H:i:s", $row["vlozeno"]);
// datum uložený ve sloupci typu DATE
echo preg_replace('~^([0-9]+)-0?([0-9]+)-0?([0-9]+)~', '\\3.\\2.\\1', $row["vlozeno"]);
// mezipřevod na timestamp v PHP
echo date("j.n.Y H:i:s", strtotime($row["vlozeno"]));
// formátování na úrovni databáze
$row = mysql_fetch_assoc(mysql_query("SELECT *, DATE_FORMAT(vlozeno, '%e.%c.%Y %H:%i:%s') AS vlozeno_f FROM diskuse"));
echo $row["vlozeno_f"];
?>
Vzhledem k tomu, že všude na webu budeme chtít datum nejspíš vypisovat jednotně, je stejně lepší si na formátování datumu napsat funkci a všude ji používat – co bude uvnitř této funkce je druhořadé, volání bude stejně snadné v obou případech. Datum se dá funkcí DATE_FORMAT formátovat už na úrovni databáze, to ale při používání mysql_fetch_assoc práci poněkud znepohodlňuje (je třeba aliasovat).
Při uložení datumu do správného typu je také s datumem čistší práce na úrovni databáze:
<?php
// smazání diskusních příspěvků starších než 14 dní
mysql_query("DELETE FROM diskuse WHERE vlozeno + INTERVAL 14 DAY < NOW()"); // datum uložený ve sloupci typu DATE
mysql_query("DELETE FROM diskuse WHERE vlozeno + 14*24*60*60 < UNIX_TIMESTAMP()"); // datum uložený v číselném sloupci
?>
Ke sloupci typu DATE není vhodné přičítat číslo, protože v tom případě ho MySQL převede na formát YYYYMMDD
, takže např. přičtení 100 přičte jeden měsíc.
Přijďte si o tomto tématu popovídat na školení Návrh a používání MySQL databáze.
Diskuse
Michal Hantl:
Proč by neměl být timestamp za 33 let třeba 128 bitový? To bych se vsadil, že budou určitě minimálně 128bitové procáky.
17.10.2005 10:16:33
Mozna jsem naivni, ale take se mi nechce verit, ze bychom meli mit za vice nez 30 let problem s nejakymi 32 bity :)
btw - je vam vsem jasne, ze klasicke datum bude mit setsakra problem v roce 10000? :)
17.10.2005 10:37:02
Problém je podobný jako s rokem 2000. Vznikl proto, že lidem bylo líto zapisovat rok čtyřciferně. Problém roku 2038 bude v tom, že lidem je líto zapisovat timestamp nějakým zvláštním typem. Používá se čtyřbajtový int a ještě nějakou dobu se používat bude. Před rokem 2038 se jistě používat přestane (třeba už za nějakých 10 let s kompletním nástupem 64bitových procesorů), ale nutnost zkontrolovat, jestli pro uložení data a času někde není použit čtyřbajtový int, zůstane. Stejně, jako u problému roku 2000 nestačilo před všechny datumy dopsat "19".
17.10.2005 11:37:27
<em>anonymní</em>:
Misto ctyrbytoveho intu se proste zacne pouzivat osmibytovy.
17.10.2005 13:14:14
Jistě, ale co staré aplikace? Vyměnit všechny čtyřbajtové inty za osmibajtové by mohlo napáchat ještě větší škody.
17.10.2005 18:30:00
No právě. Kdyby všichni používali time_t, tak by se předefinovala jedna konstanta v jednom hlavičkovém souboru, všechno by se překompilovalo a hotovo. Ale co když někdo někde neprozřetelně použil přímo int, nebo dokonce int32?
18.10.2005 14:57:32
Počítače nejsou jenom osobní počítače. Myslíš že se už dneska nepoužívají osmibitové a šestnáctibitové procesory?
17.10.2005 12:18:45
Michal Hantl:
Šlo mi hlavně o to, že argument toho, že za 33 let timestamp "dojde" asi nebude hlavním důvodem, proč ukládat čas v jiném formátu. Navíc.. za 33 let bude php verze XY a problém se bude řešit jinak. Teda.. jestli v php ještě nějaký exot bude dělat:).
17.10.2005 15:34:42
S tím souhlasím. Zrovna v MySQL to lze vyřešit už teď použitím BIGINT místo INT.
Sranda může být spíše s některými jednoúčelovými počítači. Ale pádů letadel a výpadků elektřiny se bát nemusíme, taková sranda to asi nebude. :-)
17.10.2005 17:37:13
Co máš za problém s php a co máš proti nám exotům co v něm děláme?
27.7.2007 20:48:06
trpaslice.helga:
Já myslel, že to nemyslel jako urážku dnešních php kodérů...jen prostě za 33 let asi těžko bude php ještě používané...před x lety si taky lidi mysleli, že některé programovací jazyky vydrží navždy jak jsou dokonalé...a hle, po některých není ani vidu, ani slechu už desítky let...
18.8.2007 16:16:35
salko:
A ja by som pridal, ze typ DATE je vynikajuci, ale vo verziach MySQL 3.x (neviem ako su na tom 4 verzie) uklada data vyhradne podla lokalneho casoveho pasma servera. Inak povedane, nema ulozene nikde udaj o tom, ze v akom casovom pasme sa dana hodnota nachadza. Ale ludia co nepotrebuju pracovat s casovymi pasmami sa tato vec netyka.
17.10.2005 10:27:59
Lukáš Mačí:
Malinko OT:Nevím, jestli je zrovna vhodné považovat za nevýhodu jednoho řešení a výhodu druhého něco, co nastane v tak daleké budoucnosti. Jsme si jistí, že v 2038 budeme používat databáze tak jako dnes?
17.10.2005 12:27:03
Jan Vrana:
Problem není pouze v budoucnostu ale i v minulosti.
Skuste si naprogramovat napriklad databazy historickych udalosti a pokud mozno s polem DATUM pracovat jako s Datumem. Myslim ze uz na zacatku 20stoleti zacnou problemy. :((
17.10.2005 13:08:22
Problém roku 2038 se mi zdá možná i závažnější než 2000. Nevím kolik lidí by napadlo šetřit binární pamětí tím, že se použije méně dekadických cifer.
Zatímco ten signed int je vidět na hodně místech, například v 32-bitovém Linuxu. Taky nechápu, proč se používá signed, když unsigned by vydrželo dvakrát dýl...
Ale k tématu. Teď se začíná docela prosazovat SQLite. SQLite 2 pracuje se vším jako s řetězcem, nepracuje se tam lépe s timestampem než s ISO datem?
17.10.2005 12:30:00
Jakub Podhorský:
dřív jsem taky používal zásadně unix timestamp ale potom co jsem se naučil s funkcema pro práci s datumem v MySQL jsem ho naprosto zavrhl...navíc už na první pohled přesně vím co ten datum znamená narozdíl od směsice čísel
17.10.2005 13:07:58
Leo:
Ono asi hodne zalezi na tom, k cemu to datum/cas v db pouzivate (jinak by stacil jediny zpusob zapisu). Pokud to ma byt lidsky citelne (delam z toho treba vystup na stranku, nebo co db koukam casto vlastnima ocima primo), pak treba DATETIME, pokud to slouzi treba jen k hlidani timeoutu, staci tak ukladat time z PHP. Leo
17.10.2005 15:17:17
RejpalCZ:
Hádám, že tvar "datumů" byl použit nikoli z neznalosti, nýbrž kvůli možným problémům s výkladem správného tvaru.
Přeci jen, co si představíte, když se řekne "Ukládání dat v databázi?"
... tohle je sice gramaticky špatně, ale zato všem hned jasné :-)
17.10.2005 16:53:07
Hádáš správně ;-).
17.10.2005 17:06:12
Medhi:
Posílal jsem již mail, ale radši než neexistující slovo bych použil třeba kalendářních dat.
17.10.2005 20:55:33
„U podstatného jména datum nelze odmítat v některých typech textů (zvláště těch, v nichž je třeba rozlišit kalendářní a počítačová data) ani tvary mužského rodu zejména v množném čísle, tj. datumy, datumů, datumům, datumy, o datumech, datumy. Např. Mezi nejčastější data patří datumy.“
http://prirucka.ujc.cas.cz/?id=263#nadpis33.6.2010 10:54:39
Arcao:
Hlavne se mi zda ze porovnavani casu s unix timestampem je rychlejsi. A o to tady vetsinou jde.
17.10.2005 19:19:57
Jakub Podhorský:
imho s dnešní výpočetní silou? má se o tom vůbec cenu bavit a vůbec se takovou zbytečnostní zahazovat....pro mě osobně je důležitější že když například při vývoji často testuju aplikaci a do DB ukládám datumy a potřebuju vědět co se mi tam přesně ukládá tak radši mám tabulku ve formátu DATE ze které hned na první pohled vím o co de a ne tu směsici čísel z který vím akorát tak jednu věc :)
17.10.2005 22:38:19
Antonín:
No. S dnešní výpočetní silou... Ok můžeš tomu říkat zbytečnost, když se jedná o pár operací. Představ si, že budeš potřebovat pracovat cca s 5 000 000 údaji v databázi a s každým z nich provést nějakou operaci. V tomhle případě tě již začne zajímat, který ze způsobů je rychlejší.
28.5.2015 21:50:09
<em>anonymní</em>:
Tohle jsem potreboval vedet, dekuju !
30.10.2005 14:14:58
Jirka Táborský:
Po mnoha letech jsem nasel DATE_FORMAT, zaplat buh za nej, dost mi to zjednodusuje praci.
2.3.2006 14:23:16