Autor Zpráva
SteveO
Profil *
Zdravím, rád bych konečně správně pochopil význam nulového sloupce.
Pokud sloupec NENÍ NULL, znamená to, že SQL dotaz vyhodí chybu, když do něj nic neuložím, tzn. že v dotazu s ním "nepočítám"?
Protože aktuálně mám všechny sloupce v DB nenulové (NULL není zaškrtnuto v PMA), výchozí hodnota je "Žádná" a v pohodě do ní přidám řádek, který v daném sloupci nic nemá.
Dále, je lepší z hlediska efektivity a náročnosti na velikost DB, v mít v DB nulový sloupec a hodnoty NULL u řádků, kde je daný sloupec prázdný, nebo je lepší mít nenulové sloupec s prázdnou hodnotou?
Rozdíl mezi NULL a žádnou hodnotou chápu takto: přesto, že ve sloupci je prázdný řetězec, tak není NULL, protože "prázdná hodnota" je taky hodnota.
Prosím o vysvětlení. Kdy je tedy vhodné používat NULL? Mezi nenulovým a nulovým nic není? Myslím tím zda lze udělat sloupec, který nemá určeno, zda je NULL nebo ne.
Děkuji. :)
ShiraNai7
Profil
SteveO:
a v pohodě do ní přidám řádek, který v daném sloupci nic nemá.
"Nic nemá" (tj třeba prázdný řetězec) není to samé jako NULL. Sám jsi to napsal.

Prosím o vysvětlení. Kdy je tedy vhodné používat NULL?
NULL je dobrý způsobo jak rozlišit mezi "hodnotou" a "žádnou hodnotou". To znamená, že je lepší určovat "žádnou hodnotu" jako NULL pro číselné sloupce (namísto nějakého "magického" čísla, třeba 0 nebo -1) a pro řetězce namísto prázdného řetězce.

NULLový sloupec je taky potřeba pro nepovinné reference přes cizí klíče.

Jestli je IS NULL znatelně rychlejší než sloupec='' nebo jiné srovnání netuším.
SteveO
Profil *
Dobře, ale když mám třeba tabulku se sloupci "nazev" a "text", které nejsou nulové a pak použiju dotaz INSERT INTO tabulka (nazev) VALUES ('název něčeho'), proč to nevyžaduje vyplnit taky sloupec "text"?
Pochopil bych to, kdybych použil dotaz INSERT INTO tabulka (nazev, text) VALUES ('název něčeho', ''), ale takhle se mi to zdá divný...


Aha, tak teď mi to nefunguje :) Musím použít ten druhý dotaz, aby se to DB přidal řádek, zajímavé... přísahal bych, že předtím to šlo oběma způsoby.
ShiraNai7
Profil
SteveO:
MySQL má automatické výchozí hodnoty dle datového typu. Číselné budou 0, řetězce budou prázdné a tak dále.
SteveO
Profil *
Takže (kdybych to bylo potřeba) nejde teoreticky udělat, aby SQL dotaz neprošel (na straně databáze), pokud není v INSERTu sloupec vyplněn? Já myslel, že právě k tomu to označení jako NULL/NOT NULL slouží.
Kajman
Profil
Zrovna u řetězců je tězké ukázat velký význam. Navíc pro některé databáze je prázdný řetězec NULL a pro některé je to hodnota různá od NULL.

Prosím o vysvětlení. Kdy je tedy vhodné používat NULL?

Význam NULL hodnot by se dal např. pochopit u aplikace, která bude z teploměru ukládat aktuální hodnotu s časovým příznakem. Pokud je teploměr polámaný a nevrátí hodnotu, je dobré uložit NULL, protože při uložení nuly by pak např. vyšly špatně průměry pro daný den. Ale díky NULL položkám máme informaci, kdy aplikace běžela, ale teploměr nefungoval.
Beginner
Profil
Nevím jak vám, ale mně MySQL vyhazuje chybu, kdy není vyplněna povinná hodnota.
Joker
Profil
SteveO:
proč to nevyžaduje vyplnit taky sloupec "text"?
Protože když daný sloupec má default hodnotu, vyplní se automaticky tato.

Jinak NULL je určený pro situace, kdy je potřeba u sloupce rozlišit prázdnou hodnotu. Řekněme třeba, že mám hodnotu typu číslo, která nemusí být vyplněna. Jak uložím, že nebyla vyplněna. Můžu místo toho uložit třeba 0, ale jak pak rozliším, jestli hodnota je vyplněna a je 0, nebo není vyplněna?
U řetězců je obvykle jako „prázdná hodnota“ dostačující prázdný řetězec, ale dejme tomu, že mám skript, který odněkud načítá zprávy a ukládá je do databáze. Zpráva může být i prázdná, nebo může dojít k chybě a zpráva se vůbec nenačte, což je rozdíl. Tady lze opět použít NULL pro „hodnota nebyla načtena“ a prázdný řetězec pro „hodnota byla načtena a je to prázdný řetězec“.
Tak k tomu slouží NULL.

Dodatek - Kajman: Vtipné, příklad s teploměrem jsem měl taky rozepsaný a pak jsem vymýšlel něco s řetězci :-)
SteveO
Profil *
Mně právě žádnou chybu nevyhodí... Ani v PMA, ani když to udělám PHPkem... Už mi z toho hrabe.


Jasné, díky, význam NULL už chápu.
Ale nejde mi do hlavy, proč skript nestávkuje, když nevyplním povinnou položku :-/.
Kajman
Profil
Chybu to (ne)hází podle nastavení sql modu v mysql, viz.
http://dev.mysql.com/doc/refman/5.5/en/server-sql-mode.html#sqlmode_strict_all_tables
SteveO
Profil *
Joker:
Protože když daný sloupec má default hodnotu, vyplní se automaticky tato.
Jenže sloupec přece default hodnotu nemá, když je v PMA vidím ve atributu Výchozí kurzívou napsáno Žádná, nebo ano?
ShiraNai7
Profil
Beginner:
Chybu ti to může házet jen v případě, že tam cpeš NULL a sloupec je NOT NULL anebo se jedná o sloupec s cizím klíčem.

edit: vypadá to, že na to má skutečně vliv ten sql_mode nastavený na STRICT_ALL_TABLES
SteveO
Profil *
Čili to znamná, že pro ten případ, který jsem popisoval, to skutečně házet chybu může, v závislosti na nastavení serveru?
ShiraNai7
Profil
SteveO:
Ano. Zkus si po připojení k MySQL (případně jako první dotaz pokud to spouštíš třeba přes phpMyAdmina apod) spustit tohle:
set @@session.sql_mode=STRICT_ALL_TABLES; 
Poté to nepustí INSERT, kde nejsou uvedeny hodnoty pro všechny sloupce, které nemají výchozí hodnotu.
SteveO
Profil *
Opravdu je to tak... Navíc jsem přišel na poznatek, že pokud vkládám řádek přes funkci Vložit v PMA, chyba se vypíše vždy, když něco chybí.
Když potom vygenerovaný SQL kód spustím znova přes funkci SQL, chyba se nevypíše. Ale pokud přidám před kód set @@session.sql_mode=STRICT_ALL_TABLES;, chyba se tam objeví taky.
Bezva, díky moc! Myslíš, že je vhodné si tuhle "ochranu" v PHP automaticky vždy zapínat?
ShiraNai7
Profil
SteveO:
Asi jsem vždy fungoval na MySQL serverech, kde byla tato volba aktivována, protože jsem byl sám překvapen, že to pustí INSERT, kde nejsou uvedeny hodnoty pro sloupce bez výchozích hodnot.

Minimálně pro vývoj je určitě dobré použít tento mód. Nedojde pak k tomu, že se aplikace rozbije při nasazení na server s tímto striktnějším nastavením.
SteveO
Profil *
Fajn :)
A ještě jedna věc - pokud teda budu mít v DB řádky, co mají hodnoty NULL, a pak použiju WHERE nulovy_sloupec='', vrátí mi to ty řádky taky, když nejsou '', ale NULL? Nebo musím v tomhle případě použít WHERE nulovy_sloupec IS NULL?
ShiraNai7
Profil
SteveO:
sloupec='' vrátí pouze sloupce s prázdným řetězcem
sloupec IS NULL vrátí pouze sloupce obsahující NULL

MySQL toto rozlišuje.
SteveO
Profil *
Hmm, dobrá. A chyby, co se dají zapnout tou klauzulí, cos mi poradil, se můžou vyskytnout jen při INSERTu, nebo ještě u jiného typu dotazu?
ShiraNai7
Profil
SteveO:
Je toho víc. Řídí to, jak moc je server "tolerantní" k tomu, co se po něm chce.
http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html
SteveO
Profil *
A lze nějak vytunit SQL dotaz, abych nemusel psát toto, když má třeba tabulku s knížkama a chci přidat další, ale chci zatím vyplnit jen název, nikoliv počet stran, druh vazby, žánr atd.?

INSERT INTO knihy (nazev, pocetstran, vazva, zanr, dalsisloupec, dalsisloupec2) VALUES ('Nová knížka', '', '', '', '', '')

Takhle to ještě není problém, ale když je těch sloupců, do který zatím nechci nic vyplnit třeba 50, tak už to je opruz...


Když napíšu jen INSERT INTO knihy (nazev) VALUES ('Nová knížka'), tak to samozřejmě neprojde.


Ale když o tom tak přemýšlím, tak tím bych šel proti základnímu návrhu a možnostem MySQL, mít něco pod kontrolou... takže bude asi fakt lepší dát ty sloupce jako NULL.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0