Logické operace s hodnotou NULL

qwertz

Logické operace s hodnotou NULL
« kdy: 28. 04. 2018, 08:56:57 »
Občas se při práci s SQL (eventuelně jinde) potýkám se školáckým problémem, kdy se snažím (nevědomky) provést nějakou operaci s hodnotou NULL. Než tuhle pitomou chybu vždycky odhalím, je to k naštvání jak podivně se to chová  ;D

V praxi platí, že operace porovnání čehokoli s NULL nevrací "false" ale NULL, a operace 1 + NULL nevrací 1 ale NULL. Z jakého důvodu je to vlastně takto definováno?  U matematické operace si lze asi představit, proč nechat výpočet spadnout do NULL, ale například u porovnání  1 = NULL fakt nechápu, proč nevrátit hodnotu "false".
« Poslední změna: 30. 04. 2018, 07:15:13 od Petr Krčmář »


v

Re:logické operace s hodnotou NULL
« Odpověď #1 kdy: 28. 04. 2018, 09:27:45 »
já to beru tak, že NULL znamená chybějící hodnotu a pokud binární operaci chybí jeden operand tak chybí i výsledek
a pak SQL není Cčko :)

Kit

Re:logické operace s hodnotou NULL
« Odpověď #2 kdy: 28. 04. 2018, 11:20:57 »
NULL není nula, prázdný string, ani false. Prostě nic.
Pokud chceš NULL transformovat na nějakou konkrétní hodnotu, použij COALESCE()





Re:logické operace s hodnotou NULL
« Odpověď #3 kdy: 28. 04. 2018, 11:22:43 »
primárně jde o rychlost, mít u každého porovnání ještě povinnou kontrolou na null je drahé a databáze šetří. Od toho jsou anotace u sloupců not null či default value, aby se právě tomuhle zabránilo.

Záleží na typu databáze, ale zpravidla NULL hodnoty neexistují v uložišti a nikam se neukládají. Jakékoliv větvení nebo podmínkové skoky jsou na úrovni CPU velice drahé a databáze je primárně určena pro rychlou práci s daty, to se od ní čeká a uživatelskou přívětivost ať si řeší programy nebo správný design modelu.

Za tohle chování jsem docela rád, nemám problém si tohle pohlídat a v kritických systémech ocením vyšší výkon za cenu lehce složitějšího vývoje.

Franta <xkucf03/>

Re:logické operace s hodnotou NULL
« Odpověď #4 kdy: 28. 04. 2018, 12:01:07 »
Je to celkem logické: pokud chápeš NULL jako neznámou hodnotu, tak ji nelze porovnávat s jinou hodnotou, protože výsledkem by mohlo být true i false – to nevíš, tudíž výsledkem je opět neznámá hodnota tzn. NULL.


uuuuuuuu

Re:logické operace s hodnotou NULL
« Odpověď #5 kdy: 28. 04. 2018, 12:53:53 »
Null je cerna dira, napr. Jako /dev/null.
Cerna dira plus cokoliv je cerna dira.

qwertz

Re:logické operace s hodnotou NULL
« Odpověď #6 kdy: 28. 04. 2018, 13:54:03 »
NULL není nula, prázdný string, ani false. Prostě nic.
Pokud chceš NULL transformovat na nějakou konkrétní hodnotu, použij COALESCE()

COALESCE() znám a používám. Občas se prostě ve složitějším kódu zadaří, že nějaká funkce pro určitý případ vrátí NULL aniž bych to dopředu pohlídal a pak jsem naštvaný, protože se to chová divně  ;D

Je to celkem logické: pokud chápeš NULL jako neznámou hodnotu, tak ji nelze porovnávat s jinou hodnotou, protože výsledkem by mohlo být true i false – to nevíš, tudíž výsledkem je opět neznámá hodnota tzn. NULL.

Já chápu NULL jako žádnou hodnotu, proto bych tak nějak čekal že třeba srovnání "text" = NULL vrátí false (něco se nerovná nic).

Zjevný smysl to dává spíš u matematických operací, přestože by se asi při troše dobré vůle dala zavést konvence, že "operátor NULL" (např. + NULL) se jednoduše ignoruje, takže 1+ NULL vrátí 1, 1 * NULL vrátí 1 apod. Ale chápu, že to má zřejmě výkonové důvody.

Ravise

  • ***
  • 113
    • Zobrazit profil
    • E-mail
Re:logické operace s hodnotou NULL
« Odpověď #7 kdy: 28. 04. 2018, 14:14:36 »
NULL není ani tak prázdná hodnota (jako třeba ve smyslu prázdného řetězce), jako spíš ne-hodnota, něco nedefinovaného. Podobně jako konstanta+$RANDOM je ve své podstatě taky $RANDOM. konstanta==$RANDOM? No, může a nemusí. Výsledek porovnání je taky "random".

Sten

Re:logické operace s hodnotou NULL
« Odpověď #8 kdy: 28. 04. 2018, 14:52:28 »
Pokud by to mělo mít definovány výsledek, tak hrozí, že rozbijete logické axiomy. Jaký má být třeba výsledek 0 < NULL? JavaScript se to snaží definovat, ale má to fakt divné následky (0 < null ≡ false a 0 == null ≡ false, ale 0 <= null ≡ true).

Re:logické operace s hodnotou NULL
« Odpověď #9 kdy: 28. 04. 2018, 17:03:26 »
Občas se při práci s SQL (eventuelně jinde) potýkám se školáckým problémem, kdy se snažím (nevědomky) provést nějakou operaci s hodnotou NULL. Než tuhle pitomou chybu vždycky odhalím, je to k naštvání jak podivně se to chová  ;D

V praxi platí, že operace porovnání čehokoli s NULL nevrací "false" ale NULL, a operace 1 + NULL nevrací 1 ale NULL. Z jakého důvodu je to vlastně takto definováno?  U matematické operace si lze asi představit, proč nechat výpočet spadnout do NULL, ale například u porovnání  1 = NULL fakt nechápu, proč nevrátit hodnotu "false".

Pokud si to dobře vybavuju, tak NULL v SQL odpovídá tomu, že v daném sloupci záznamu není žádná hodnota, prostě tam není nic.
(a proto NULL u stringu není prázdný řetězec, a ani to není 0 pro čísla)

A jak s tím cokoli porovnávat, nebo provádět matematické operace?

A proto je tam "speciální konstrukce" IS NULL / IS NOT NULL.

Další detaily už si moc nepamatuju, to je třeba si dostudovat.
(a každá konkrétní databáze může k normě přidat svoje špecifiká)

Trupik

Re:logické operace s hodnotou NULL
« Odpověď #10 kdy: 28. 04. 2018, 17:27:31 »
https://en.wikipedia.org/wiki/Null_(SQL)
Ľudia, mohli by ste si aspoň prvý odstavec na wikipedii prečítať, než začnete mlžiť. NULL (v SQL) znamená "chýbajúcu informáciu a nepoužiteľnú informáciu". NULL (v SQL) nie je hodnota, ale stav. S optimalizáciou to nemá nič spoločné - v skutočnosti to komplikuje ako uloženie informácie, tak aj všetky operácie s ňou.

Za najväčšiu chybu pri návrhu jazyka SQL považujem, že použili na túto vec názov "NULL". Nepoznám jediného programátora, ktorý by si o to nenabil držku, pretože v ostatných "tradičných" programovacích jazykoch NULL znamená niečo iné.

Sten

Re:logické operace s hodnotou NULL
« Odpověď #11 kdy: 28. 04. 2018, 17:49:27 »
Nepoznám jediného programátora, ktorý by si o to nenabil držku, pretože v ostatných "tradičných" programovacích jazykoch NULL znamená niečo iné.

Snad ve všech jazycích znamená null chybějící nebo nepoužitelnou informaci, a používání takové informace buď propaguje null (monády, optional) nebo rovnou selže (NullPointerException, SIGSEGV). Jen v pointerové aritmetice je null hodnota, a ta je prakticky vždy rovná nule.

Re:logické operace s hodnotou NULL
« Odpověď #12 kdy: 28. 04. 2018, 19:23:19 »
V praxi platí, že operace porovnání čehokoli s NULL nevrací "false" ale NULL, a operace 1 + NULL nevrací 1 ale NULL. Z jakého důvodu je to vlastně takto definováno?  U matematické operace si lze asi představit, proč nechat výpočet spadnout do NULL, ale například u porovnání  1 = NULL fakt nechápu, proč nevrátit hodnotu "false".
Já v tom nevidím žádný problém - libovolná operace vůči NULLu je NULL - nevidím žádný důvod, proč by toto pravidlo mělo mít výjimky (i když je samozřejmě má). Určitou logiku to dostane, až když člověk začne řešit predikáty IN, NOT IN.

NULL je relativně kontroverzní vlastnost SQL - teoreticky není potřeba (dost možná je to reakce na COBOL) a existují teoretické relační dotazovací jazyky bez NULL. Nicméně praktický smysl tam je - je to jedna hodnota, která je pro všechny typy mimo obor hodnot. Takže odpadá nutnost si definovat magické konstanty: "", -1, 0, 0000-00-00, ...

Z hlediska CPU, pokud budu mluvit o Postgresu, tak pro tabulky s vyššíma desítkama sloupců už může být test na NULL znát - tabulky, kde nejsou NULL hodnoty se načítají o fous rychleji (ale pozná se to třeba až u nějakého 70 - 80 sloupce). Ušetří se na uložišti - NULL je uložen jako 1bit bez ohledu na datový typ. Např. prázdný řetězec má minimálně 1byte, 0 v int má 4 bajty, ..

Jinak existuje několik funkcí a operátorů, které jsou vůči NULL imunní .. pro vás asi nejzajímavější by mohly být operátory IS DISTINCT FROM nebo IS NOT DISTINCT FROM, což je <> a = které zvládne NULL - v detailu https://stackoverflow.com/questions/27134368/is-is-distinct-from-a-real-mysql-operator

Franta <xkucf03/>

Re:logické operace s hodnotou NULL
« Odpověď #13 kdy: 28. 04. 2018, 20:09:32 »
NULL je relativně kontroverzní vlastnost SQL - teoreticky není potřeba (dost možná je to reakce na COBOL) a existují teoretické relační dotazovací jazyky bez NULL. Nicméně praktický smysl tam je - je to jedna hodnota, která je pro všechny typy mimo obor hodnot. Takže odpadá nutnost si definovat magické konstanty: "", -1, 0, 0000-00-00, ...

Ono lidi občas na to NULL v SQL nadávají, ale když se člověk zamyslí, jak by pak vypadal datový model běžné aplikace, tak by to asi nikdo používat nechtěl. Čisté řešení by bylo přesunout nepovinné atributy do samostatných tabulek a provázat je přes cizí klíče. Pak by si člověk užil opravdu hodně JOINů… A prasácké řešení je zahnojit model a kód těmi magickými konstantami – a pak se divit, proč se to chová „podivně“ a vypadávají z toho nečekané výsledky – protože se třeba někde přičetla ta -1 nebo jiná speciální hodnota. To je ještě větší peklo než to první řešení.

Ale pokud někdo touží po SQL bez NULL, může ho klidně mít – stačí si u všech sloupců nastavit NOT NULL a tuto hodnotu jednoduše nepoužívat.

qwertz

Re:logické operace s hodnotou NULL
« Odpověď #14 kdy: 28. 04. 2018, 21:10:20 »
Ale pokud někdo touží po SQL bez NULL, může ho klidně mít – stačí si u všech sloupců nastavit NOT NULL a tuto hodnotu jednoduše nepoužívat.

až na to že hodnotu NULL může vrátit některá built-in funkce.