Logické operace s hodnotou NULL

Re:logické operace s hodnotou NULL
« Odpověď #15 kdy: 29. 04. 2018, 05:43:50 »
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.
Mluvím za Postgres - základní vestavěné funkce typicky vrací NULL pouze pokud je některý parametr NULL. Jinak při chybě vyhodí výjimku. MySQL se bude chovat jinak, tak jsou víc fault tolerant a právě více používají NULLy. U Pg vím, že snad asi jen funkce pro práci s poli mohou vracet NULL - pokud se sáhne mimo pole, a pokud se ptám na rozměry prázdného pole (přičemž to poslední chování se spíš bere jako chyba, kterou nejde opravit z důvodu porušení kompatibility (a je tam alternativní funkce, která se chová jinak)).


qwertz

Re:logické operace s hodnotou NULL
« Odpověď #16 kdy: 29. 04. 2018, 07:20:30 »
Mluvím za Postgres - základní vestavěné funkce typicky vrací NULL pouze pokud je některý parametr NULL. Jinak při chybě vyhodí výjimku.
Těch scénářů bude víc. Např. substring(regex) vrátí NULL, když nenajde definovaný pattern. Pak už jen stačí výsledek porovnat s hledaným stringem, výsledný boolean převést na integer a něco s ním počítat a výsledný NULL vyleze místě, kde ho na první pohled nečekáte  ;D

Prostě je třeba automaticky pořád myslet na to, které funkce vrací NULL a hned to ošetřit např. COALESCE().

Re:logické operace s hodnotou NULL
« Odpověď #17 kdy: 29. 04. 2018, 09:40:43 »
Mluvím za Postgres - základní vestavěné funkce typicky vrací NULL pouze pokud je některý parametr NULL. Jinak při chybě vyhodí výjimku.
Těch scénářů bude víc. Např. substring(regex) vrátí NULL, když nenajde definovaný pattern. Pak už jen stačí výsledek porovnat s hledaným stringem, výsledný boolean převést na integer a něco s ním počítat a výsledný NULL vyleze místě, kde ho na první pohled nečekáte  ;D

Prostě je třeba automaticky pořád myslet na to, které funkce vrací NULL a hned to ošetřit např. COALESCE().

Ju, to tam je - důvod netuším - asi chtěli tvůrci rozlišit mezi prázdným řetězcem a žádným řetězcem - nebo je to funkce, která přišla do standardu z Oracle, a tam se mezi NULLem a prázdným řetězcem nerozlišuje. Nicméně stále tohle chování je opravdu velkou výjimkou - což možná působí víc komplikací než kdyby bylo obvyklé. SQL mám rád a beru ho za jeden z nejlepších IT nástrojů, ale ANSI SQL rozhodně není do mrtě konzistentní.

Kit

Re:logické operace s hodnotou NULL
« Odpověď #18 kdy: 29. 04. 2018, 12:01:31 »
Mluvím za Postgres - základní vestavěné funkce typicky vrací NULL pouze pokud je některý parametr NULL. Jinak při chybě vyhodí výjimku.
Těch scénářů bude víc. Např. substring(regex) vrátí NULL, když nenajde definovaný pattern. Pak už jen stačí výsledek porovnat s hledaným stringem, výsledný boolean převést na integer a něco s ním počítat a výsledný NULL vyleze místě, kde ho na první pohled nečekáte  ;D

Prostě je třeba automaticky pořád myslet na to, které funkce vrací NULL a hned to ošetřit např. COALESCE().

NULL je také informací. COALESCE() tuto informaci nahrazuje jinou informací, která nemusí být vždy vhodná. Dost často se setkávám s tím, že někdo do databáze místo času NULL narve nějakou nesmyslnou hodnotu "0000-00-..." To je na zabití.

Franta <xkucf03/>

Re:logické operace s hodnotou NULL
« Odpověď #19 kdy: 29. 04. 2018, 12:32:01 »
Mluvím za Postgres - základní vestavěné funkce typicky vrací NULL pouze pokud je některý parametr NULL. Jinak při chybě vyhodí výjimku.
Těch scénářů bude víc. Např. substring(regex) vrátí NULL, když nenajde definovaný pattern. Pak už jen stačí výsledek porovnat s hledaným stringem, výsledný boolean převést na integer a něco s ním počítat a výsledný NULL vyleze místě, kde ho na první pohled nečekáte  ;D

Prostě je třeba automaticky pořád myslet na to, které funkce vrací NULL a hned to ošetřit např. COALESCE().

NULL je také informací. COALESCE() tuto informaci nahrazuje jinou informací, která nemusí být vždy vhodná. Dost často se setkávám s tím, že někdo do databáze místo času NULL narve nějakou nesmyslnou hodnotu "0000-00-..." To je na zabití.

Nebo 2999-12-31 23:59:59 jako „nekonečno“ – jasně, ten software v tom roce už existovat nebude, ale stejně…

BTW: máte někdo nápad, jak zaznamenávat datum a čas s tím, že časová složka nemusí být vždy přítomná? Tzn. někdy známe jen datum ale ne čas. Špatné řešení je dát čas 00:00:00, protože pak nejde rozlišit zda se daná věc stala a) na začátku daného dne nebo b) kdykoli během dne (nevíme, kdy). Asi nezbývá, než to rozdělit do dvou sloupců/parametrů a čas mít někdy NULL, že?


Sten

Re:logické operace s hodnotou NULL
« Odpověď #20 kdy: 29. 04. 2018, 13:01:36 »
BTW: máte někdo nápad, jak zaznamenávat datum a čas s tím, že časová složka nemusí být vždy přítomná? Tzn. někdy známe jen datum ale ne čas. Špatné řešení je dát čas 00:00:00, protože pak nejde rozlišit zda se daná věc stala a) na začátku daného dne nebo b) kdykoli během dne (nevíme, kdy). Asi nezbývá, než to rozdělit do dvou sloupců/parametrů a čas mít někdy NULL, že?

Rozdělit to do dvou sloupců, při porovnání budete potřebovat dva údaje (porovnání data, porovnání času), jinak nebude fungovat porovnání data bez času s datem s časem ve stejném dni (stejný den = TRUE, stejný čas = NULL).

qwertz

Re:logické operace s hodnotou NULL
« Odpověď #21 kdy: 29. 04. 2018, 13:01:57 »
NULL je také informací. COALESCE() tuto informaci nahrazuje jinou informací, která nemusí být vždy vhodná. Dost často se setkávám s tím, že někdo do databáze místo času NULL narve nějakou nesmyslnou hodnotu "0000-00-..." To je na zabití.

Ano, to je kolosální pitomost. Nicméně zda pole může nebo nemůže obsahovat NULL je zřejmé na první pohled (definice sloupce NOT NULL). Tam se to dá odchytit celkem snadno. Na rozdíl od funkce, kde se hodnota NULL "nečekaně" objeví na výstupu. Jasně, každá funkce má definováno, zda vrací NULL a za jakých podmínek, ale to už je třeba aktivné hlídat.

BTW: máte někdo nápad, jak zaznamenávat datum a čas s tím, že časová složka nemusí být vždy přítomná?
čisté řešení je to rozdělit a když chybí nahradit NULL.

Kit

Re:logické operace s hodnotou NULL
« Odpověď #22 kdy: 29. 04. 2018, 13:06:56 »
BTW: máte někdo nápad, jak zaznamenávat datum a čas s tím, že časová složka nemusí být vždy přítomná? Tzn. někdy známe jen datum ale ne čas. Špatné řešení je dát čas 00:00:00, protože pak nejde rozlišit zda se daná věc stala a) na začátku daného dne nebo b) kdykoli během dne (nevíme, kdy). Asi nezbývá, než to rozdělit do dvou sloupců/parametrů a čas mít někdy NULL, že?

Nabízí se ukládat takový časový údaj ve stringu:
"2018-04" - někdy v dubnu 2018
"2018-04-29 13" - dnes ve mezi 13. a 14. hodinou

Kit

Re:logické operace s hodnotou NULL
« Odpověď #23 kdy: 29. 04. 2018, 13:13:23 »
NULL je také informací. COALESCE() tuto informaci nahrazuje jinou informací, která nemusí být vždy vhodná. Dost často se setkávám s tím, že někdo do databáze místo času NULL narve nějakou nesmyslnou hodnotu "0000-00-..." To je na zabití.

Ano, to je kolosální pitomost. Nicméně zda pole může nebo nemůže obsahovat NULL je zřejmé na první pohled (definice sloupce NOT NULL). Tam se to dá odchytit celkem snadno. Na rozdíl od funkce, kde se hodnota NULL "nečekaně" objeví na výstupu. Jasně, každá funkce má definováno, zda vrací NULL a za jakých podmínek, ale to už je třeba aktivné hlídat.

Velmi často se chybuje v tom, že se NOT NULL definuje automaticky v každém sloupci a pak se pracně obchází situace, kdy tam žádný časový údaj nemá být uložen (schváleno dne apod.) Základem je naučit se s hodnotou NULL pracovat a nechat ji tam, kde má být.

Franta <xkucf03/>

Re:logické operace s hodnotou NULL
« Odpověď #24 kdy: 29. 04. 2018, 13:41:37 »
BTW: máte někdo nápad, jak zaznamenávat datum a čas s tím, že časová složka nemusí být vždy přítomná? Tzn. někdy známe jen datum ale ne čas. Špatné řešení je dát čas 00:00:00, protože pak nejde rozlišit zda se daná věc stala a) na začátku daného dne nebo b) kdykoli během dne (nevíme, kdy). Asi nezbývá, než to rozdělit do dvou sloupců/parametrů a čas mít někdy NULL, že?

Nabízí se ukládat takový časový údaj ve stringu:
"2018-04" - někdy v dubnu 2018
"2018-04-29 13" - dnes ve mezi 13. a 14. hodinou

Tam bude problém, kam dát časovou zónu a obecně se mi nelíbí používání jiného datového typu… stejně by to pak bylo potřeba obalit vlastními funkcemi, aby se s tím dalo pracovat.

Zajímavější by byl datový typ, který by kromě samotné informace obsahoval i její přesnost. Nebo to dát do dvou sloupců (případně do jednoho typu „interval“) a ten první by značil dolní mez a ten druhý horní. A výsledkem porovnání by pak byly čtyři možné stavy:

  • událost A nastala před událostí B
  • událost B nastala před událostí A
  • události A a B nastaly v přesně stejný okamžik
  • událost A a B nastaly ve stejný den (měsíc, rok, minutu…), ale nedokážeme přesněji říct, zda bylo dřív A nebo B

Resp. jsou to spíš tři stavy, protože ta třetí možnost je speciální případ té čtvrté, jelikož i ten „přesně stejný okamžik“ má nějakou granularitu (měříme na minuty, vteřiny, ms, ns… ale v rámci dané jednotky už to nedokážeme přesněji rozlišit).

Pokud půjdeme ještě o krok dál, mohli bychom evidovat pravděpodobnost, s jakou je daná informace pravdivá. Na tohle jsem se ptal kdysi ve škole, ale nikdo mi na to nedokázal odpovědět (v kontextu SQL a relačních databází). Např. budeme mít část hodnot přesně změřených, tak u nich dáme pravděpodobnost 100 % a pak máme část hodnot, které jsme tak trochu odhadovali, měřili nepřesným nástrojem atd. tak u nich dáme pravděpodobnost třeba jen 80 %. Když pak budeme dělat nějaké agregace, může nám z toho vypadnout i pravděpodobnost celkového výsledku, optimistické a pesimistické odhady…

Re:logické operace s hodnotou NULL
« Odpověď #25 kdy: 29. 04. 2018, 14:12:27 »
BTW: máte někdo nápad, jak zaznamenávat datum a čas s tím, že časová složka nemusí být vždy přítomná? Tzn. někdy známe jen datum ale ne čas. Špatné řešení je dát čas 00:00:00, protože pak nejde rozlišit zda se daná věc stala a) na začátku daného dne nebo b) kdykoli během dne (nevíme, kdy). Asi nezbývá, než to rozdělit do dvou sloupců/parametrů a čas mít někdy NULL, že?

Nabízí se ukládat takový časový údaj ve stringu:
"2018-04" - někdy v dubnu 2018
"2018-04-29 13" - dnes ve mezi 13. a 14. hodinou

Tam bude problém, kam dát časovou zónu a obecně se mi nelíbí používání jiného datového typu… stejně by to pak bylo potřeba obalit vlastními funkcemi, aby se s tím dalo pracovat.

Zajímavější by byl datový typ, který by kromě samotné informace obsahoval i její přesnost. Nebo to dát do dvou sloupců (případně do jednoho typu „interval“) a ten první by značil dolní mez a ten druhý horní. A výsledkem porovnání by pak byly čtyři možné stavy:

  • událost A nastala před událostí B
  • událost B nastala před událostí A
  • události A a B nastaly v přesně stejný okamžik
  • událost A a B nastaly ve stejný den (měsíc, rok, minutu…), ale nedokážeme přesněji říct, zda bylo dřív A nebo B

Resp. jsou to spíš tři stavy, protože ta třetí možnost je speciální případ té čtvrté, jelikož i ten „přesně stejný okamžik“ má nějakou granularitu (měříme na minuty, vteřiny, ms, ns… ale v rámci dané jednotky už to nedokážeme přesněji rozlišit).

Pokud půjdeme ještě o krok dál, mohli bychom evidovat pravděpodobnost, s jakou je daná informace pravdivá. Na tohle jsem se ptal kdysi ve škole, ale nikdo mi na to nedokázal odpovědět (v kontextu SQL a relačních databází). Např. budeme mít část hodnot přesně změřených, tak u nich dáme pravděpodobnost 100 % a pak máme část hodnot, které jsme tak trochu odhadovali, měřili nepřesným nástrojem atd. tak u nich dáme pravděpodobnost třeba jen 80 %. Když pak budeme dělat nějaké agregace, může nám z toho vypadnout i pravděpodobnost celkového výsledku, optimistické a pesimistické odhady…

To už se dostáváte do fuzzy aritmetiky - s klasickými typy by to šlo dost ztuha - ale asi by nebyl problém napsat si vlastní typy, kde by se bokem ukládala pravděpodobnost (případně přesnost). Viděl jsem pár studií, které se o něco takového pokoušely, ale asi to neopustilo akademickou půdu. Případně se to řeší v aplikaci.

Re:logické operace s hodnotou NULL
« Odpověď #26 kdy: 29. 04. 2018, 14:14:04 »
BTW: máte někdo nápad, jak zaznamenávat datum a čas s tím, že časová složka nemusí být vždy přítomná? Tzn. někdy známe jen datum ale ne čas. Špatné řešení je dát čas 00:00:00, protože pak nejde rozlišit zda se daná věc stala a) na začátku daného dne nebo b) kdykoli během dne (nevíme, kdy). Asi nezbývá, než to rozdělit do dvou sloupců/parametrů a čas mít někdy NULL, že?

Nabízí se ukládat takový časový údaj ve stringu:
"2018-04" - někdy v dubnu 2018
"2018-04-29 13" - dnes ve mezi 13. a 14. hodinou

V PG je možné použít date range nebo timestamp range. Tudíž string není nutný - a můžete vyhledávat kolize intervalů, případně jejich sjednocení, ..

ded.kenedy

Re:logické operace s hodnotou NULL
« Odpověď #27 kdy: 29. 04. 2018, 23:23:24 »
Citace
Citace
Pokud půjdeme ještě o krok dál, mohli bychom evidovat pravděpodobnost, s jakou je daná informace pravdivá. Na tohle jsem se ptal kdysi ve škole, ale nikdo mi na to nedokázal odpovědět (v kontextu SQL a relačních databází). Např. budeme mít část hodnot přesně změřených, tak u nich dáme pravděpodobnost 100 % a pak máme část hodnot, které jsme tak trochu odhadovali, měřili nepřesným nástrojem atd. tak u nich dáme pravděpodobnost třeba jen 80 %. Když pak budeme dělat nějaké agregace, může nám z toho vypadnout i pravděpodobnost celkového výsledku, optimistické a pesimistické odhady…

To už se dostáváte do fuzzy aritmetiky - s klasickými typy by to šlo dost ztuha - ale asi by nebyl problém napsat si vlastní typy, kde by se bokem ukládala pravděpodobnost (případně přesnost).

To, co chce provadet Franta <xkucf03/>, neni fuzzy aritmetika (coz je IMHO teda docela pochybna aplikace fuzzy logiky), ale pouze intervalova aritmetika, ktera by bez vetsich problemu mela jit uchopit zavedenim vlastniho dvouprvkoveho kompozitniho typu a deklaraci vhodnych operatoru a agregacnich funkci. Coz vse Postgres umi.

Vetsi problem nez uchopit to technicky, bude pro vetsinu lidi problem uchopit to koncepcne. V podstate se jedna o zpracovani nejistoty (uncertainty) v datech. Avsak moznych typu nejistoty v datech je hned nekolik druhu. Jenom v predchozich prispevcich byly zmineny tri, a aby se databaze chovaly spravne a data davala smysl, je potreba spravne volit typ nejistoty a prace s nim.

Jedna vec je napriklad nejistota zpusobena merenim, tj. namerena hodnota +/- presnost meridla. V tomto pripade nejde rict, ze hodnota je 10 cm s pravdepodobnosti 80% a 10.2 cm s pravdepodobnosti 20%.

Vedle toho se da uvazovat o pravdepodponosti nejakeho jevu, napr. atribut y ma hodnotu Q s pravdepodobnosti 40%; nebo radek [x,y,z] se vyskytuje v tabulce s pravdepodobnosti 30%. To umoznuje resit ulohy typu, kniha se nachazi v knihovne na 90%, nebo zamestnanec se nachazi v kancelari XY s pravdepodobnosti 80% a v kancelari YZ s pravdepodobnosti 10%. Timto smerem se vydavaji pravdepodobnosti databaze.

A aby toho nebylo dost, muzeme data v rel. databazi uchopit jeste s pomoci fuzzy logiky. To v tom pripade znamena, ze zacneme uvazovat stupne pravdivosti jednotlivych vyroku. Napr. vyrok: "logo postgresql je modre" ma stupen pravdivosti 1; "logo mysql je modre" muze mit stupen pravdivosti 0.6; pricemz  "logo mysql je oranzove" muze mit treba stupen pravdivosti 0.5 a  "logo mysql je ruzove" ma stupen pravdivosti 0 (nepravdivy vyrok)