独家-美拆弹部队前军官:特朗普是来给美国“灭虫”

Null – specjalny znacznik w j?zyku SQL, wskazuj?cy, ?e dana nie istnieje w bazie danych. Wprowadzony przez twórc? relacyjnego modelu bazy danych, Edgara Franka Codda, znacznik Null istnieje, aby spe?ni? wymóg, ?e wszystkie prawdziwe systemy zarz?dzania relacyjn? baz? danych udost?pniaj? reprezentacj? ?informacji brakuj?cej i informacji niestosowalnej”. Codd zapocz?tkowa? równie? przedstawianie znacznika Null w teorii baz danych za pomoc? ma?ej greckiej litery omega (ω). NULL
to tak?e zarezerwowane s?owo w SQL, u?ywane do identyfikacji specjalnego znacznika Null.
Znacznik Null by? przedmiotem kontrowersji i powodem dyskusji z powodu powi?zanej z nim logiki trójwarto?ciowej, specjalnych wymagań wobec stosowania go w z??czeniach i wymagania jego specjalnej obs?ugi w funkcjach agreguj?cych i operatorach grupowania. Mimo wprowadzenia specjalnych funkcji i predykatów, aby w?a?ciwie obs?ugiwa? znacznik Null, jego przeciwnicy uwa?aj?, ?e rozwi?zywanie tych kwestii wprowadza niepotrzebne skomplikowanie i niekonsekwencj? do relacyjnego modelu baz danych.
Historia
[edytuj | edytuj kod]Null zosta? wprowadzony przez Edgara Franka Codda jako sposób na przedstawienie brakuj?cych danych w modelu relacyjnym. W pó?niejszym czasie Codd, w dwucz??ciowej serii opublikowanej w czasopi?mie ComputerWorld[1][2], wzmocni? swoje wymagania pisz?c, ?e wszystkie RDBMS powinny wspiera? Null, aby wskaza? brakuj?ce dane. Codd wprowadzi? równie? trójwarto?ciow? logik? sk?adaj?c? si? z warto?ci logicznych Prawda, Fa?sz i Nieznany, które s? ?ci?le zwi?zane z poj?ciem Null. Warto?? logiczna Nieznany jest uzyskiwana gdy Null jest porównana z dowoln? dan? lub innym Null.
Codd wskaza? w swojej ksi??ce The Relational Model for Database Management, Version 2 z 1990 roku, ?e pojedynczy Null nakazany przez standard SQL jest niewystarczaj?cy i powinien by? zast?piony przez dwa wska?niki typu Null, aby móc wskaza? powód dlaczego danych brakuje. Te dwa znaczniki s? powszechnie znane jako ?warto?ci-A” i ?warto?ci-I”, przedstawiaj?ce odpowiednio ?brakuj?ce, lecz daj?ce si? stosowa?” i ?brakuj?ce, lecz niew?a?ciwe”[3]. Zalecenia Codda wymaga?oby rozszerzenia systemu logiki SQL, aby umie?ci? cztery zmienne logiczne. Z powodu dodatkowych komplikacji, pomys? wielu warto?ci typu Null nie uzyska? powszechnej akceptacji.
Logika trójwarto?ciowa
[edytuj | edytuj kod]Poniewa? Null nie jest cz?onkiem jakiejkolwiek domeny danych, nie jest on rozwa?any jako ?warto??”, lecz raczej jako znacznik (lub symbol zast?pczy) wskazuj?cy na brak warto?ci. Z uwagi na to, porównywanie z Null nigdy nie mo?e zwróci? Prawdy lub Fa?szu, lecz zawsze trzeci logiczny wynik, Nieznany[4]. Logiczny wynik poni?szego wyra?enia, które porównuje warto?? 10 z Null to Nieznany.
SELECT 10 = NULL -- Wynik to Nieznany
Jednak?e w pewnych operacjach z Null, mo?na otrzyma? warto?ci, je?li Null nie ma wp?ywu na wyniki takiej operacji. Rozwa?aj?c nast?puj?cy przyk?ad:
SELECT NULL OR TRUE -- Wynik to Prawda
W tym przypadku, fakt, ?e warto?? z lewej strony operatora sumy logiczniej (OR
) jest nieznana jest bez znaczenia, poniewa? wynikiem tej sumy mo?e by? Prawda, niezale?nie od warto?ci z lewej strony.
SQL realizuje trzy wyniki logiczne, czyli implementacje SQL musz? zapewni? specjaln? logik? trójwarto?ciow?. Zasady rz?dz?ce trójwarto?ciow? logik? SQL s? przedstawione w tabelach poni?ej (p i q reprezentuj? stany logiczne)[5].
|
|
Podstawowe operatory porównuj?ce w SQL zawsze zwracaj? Nieznany kiedy porównywane jest cokolwiek z Null, wobec czego standard SQL dostarcza dwa specjalne i specyficzne dla Null predykaty porównuj?ce. Predykaty IS NULL
i IS NOT NULL
sprawdzaj? czy dana jest, albo nie jest, Null[6].
Typowanie danych
[edytuj | edytuj kod]W SQL Null nie ma typu, oznacza to, ?e nie jest on oznaczony jako liczba, znak lub jakikolwiek inny okre?lony typ danych[4]. Z tego powodu, czasami jest wymagane (lub po??dane) jawne konwertowanie Null do okre?lonego typu danych. Na przyk?ad, je?li RDBMS wspiera przeci??anie funkcji, SQL mo?e nie by? w stanie automatycznie dowi?za? w?a?ciwych funkcji bez znajomo?ci typów danych wszystkich parametrów, w??czaj?c w nie te, które zosta?y przekazane jako Null.
J?zyk przetwarzania danych
[edytuj | edytuj kod]Trójwarto?ciowa logika SQL wyst?puje w j?zyku przetwarzania danych (DML) w predykatach porównuj?cych, w wyra?eniach i zapytaniach DML. Klauzula WHERE
powoduje, ?e wyra?enie DML dzia?a tylko na wierszach dla których predykat zwraca Prawda. Wiersze, dla których predykat zwraca Fa?sz lub Nieznany nie bior? udzia?u w wyra?eniach DML INSERT
, UPDATE
lub DELETE
, oraz s? pomijane w zapytaniach SELECT
. Interpretowanie Nieznany i Fa?sz jako takich samych logicznych wyników to powszechny b??d wyst?puj?cy przy dzia?aniach z Null[5]. Nast?puj?cy prosty przyk?ad demonstruje tak? omy?k?:
SELECT *
FROM t
WHERE i = NULL;
Powy?szy przyk?ad zapytania logicznie zawsze zwraca zero wierszy poniewa? porównanie kolumny i z Null zawsze zwraca Nieznany, nawet dla wierszy w których i jest Null. Wynik Nieznany powoduje, ?e zapytanie SELECT
szybko pominie wszystkie wiersze. (Chocia?, w praktyce, niektóre narz?dzia SQL zwróc? wiersze stosuj?c porównanie z Null.)
Wyra?enie CASE
[edytuj | edytuj kod]Wyra?enie SQL CASE
dla Null dzia?a na takich samych zasadach jak klauzula DML WHERE
. Poniewa? mo?e ono by? rozwijane jako szereg warunków porównuj?cych, proste wyra?enie CASE
mo?e sprawdzi? wyst?pienia Null bezpo?rednio. Test na Null w prostym wyra?eniu CASE
zawsze zwraca Nieznany, jak poni?ej:
SELECT CASE i WHEN NULL THEN 'jest Null' -- To nigdy nie b?dzie zwrócone
WHEN 0 THEN 'jest zero' -- To b?dzie zwrócone kiedy i = 0
WHEN 1 THEN 'jest jeden' -- To b?dzie zwrócone kiedy i = 1
END
FROM t;
Poniewa? wyra?enie i = NULL
jest rozwijane do Nieznany jest bez znaczenia jak? warto?? ma kolumna i (nawet je?li zawiera Null), tekst 'jest Null'
nigdy nie b?dzie zwrócony.
Przeszukuj?ce wyra?enie CASE
tak?e zwraca pierwsz? warto?? dla której wynik predykatu porównuj?cego rozwija si? do Prawda, w??czaj?c porównania stosuj?ce predykaty IS NULL
i IS NOT NULL
. Nast?puj?cy przyk?ad pokazuje jak stosowa? przeszukuj?ce wyra?enie CASE
aby w?a?ciwie sprawdza? Null:
SELECT CASE WHEN i IS NULL THEN 'wynik Null' -- To jest zwrócone kiedy i jest NULL
WHEN i = 0 THEN 'zero' -- To jest zwrócone kiedy i = 0
WHEN i = 1 THEN 'jeden' -- To jest zwrócone kiedy i = 1
END
FROM t;
W przeszukuj?cym wyra?eniu CASE
, tekst 'wynik Null'
jest zwrócone dla wszystkich wierszy w których i jest Null.
Ograniczenia definiowane
[edytuj | edytuj kod]G?ówne miejsce gdzie logika trójwarto?ciowa krzy?uje si? z j?zykiem definicji danych (DDL) to zdefiniowane ograniczenia. Definiowane ograniczenie umieszczone na kolumnie dzia?a pod nieco zmienionymi regu?ami, ni? klauzula DML WHERE
. Podczas gdy klauzula DML WHERE
musi by? rozwini?ta do Prawda dla wiersza, ograniczenie definiowane nie mo?e si? rozwin?? do Fa?sz. To znaczy, ?e ograniczenie definiowane powiedzie si? je?li wynik to Prawda lub Nieznany. Nast?puj?ca przyk?adowa tabela ze zdefiniowanym ograniczeniem zabrania wstawienia ka?dej liczby ca?kowitej, ale pozwala na wstawienie Null, gdy? wynik sprawdzenia zawsze jest rozwijany do Nieznany dla Null[7].
CREATE TABLE t (
i INTEGER,
CONSTRAINT ck_i CHECK ( i < 0 AND i = 0 AND i > 0 ) );
Aby wymusi? ograniczenie na kolumnie aby nie akceptowa?a Nulli, mo?na zastosowa? ograniczenie NOT NULL
, jak to pokazano na przyk?adzie poni?ej. Ograniczenie NOT NULL
jest semantycznie równowa?ne z ograniczeniem definiowanym z predykatem IS NOT NULL
.
CREATE TABLE t ( i INTEGER NOT NULL );
Rozszerzenia proceduralne
[edytuj | edytuj kod]SQL/PSM (ang. SQL Persistent Stored Modules – trwale przechowywane modu?y) definiuje proceduralne rozszerzenia dla SQL, takie jak wyra?enie IF
. Jednak?e, g?ówni dostawcy SQL historycznie zawieraj? swoje w?asne zastrze?one rozszerzenia proceduralne. Proceduralne rozszerzenia dla p?tli i porównań dzia?aj? wed?ug regu? podobnych do zasad z wyra?eń i zapytań DML. Nast?puj?cy fragment kodu, w standardzie ISO SQL, demonstruje u?ycie trójwarto?ciowej logiki Null z wyra?eniem IF
.
IF i = NULL THEN
SELECT 'wynik to Prawda'
ELSEIF NOT(i = NULL) THEN
SELECT 'wynik to Fa?sz'
ELSE
SELECT 'wynik to Nieznany';
Wyra?enie IF
wykonuje akcj? tylko dla tych porównań, które rozwijaj? si? do Prawda. W wyra?eniach, w których si? rozwija do Fa?sz lub Nieznany, wyra?enie IF
przekazuje sterowanie do klauzuli ELSEIF
, a na końcu do klauzuli ELSE
. Wynikiem kodu powy?ej b?dzie zawsze wiadomo?? 'wynik to Nieznany'
poniewa? porównania z Null zawsze zwracaj? Nieznany.
Z??czenia
[edytuj | edytuj kod]Z??czenia zewn?trzne, tj. lewe z??czenie zewn?trzne, prawe z??czenie zewn?trzne i pe?ne z??czenie zewn?trzne, automatycznie umieszczaj? Null jako zamiennik dla warto?ci brakuj?cych w powi?zanych tabelach. Na przyk?ad w lewym z??czeniu zewn?trznym, Null jest umieszczany w miejscu brakuj?cych wierszy z tabeli, która pojawia si? po prawej stronie operatora LEFT OUTER JOIN
. Nast?puj?cy przyk?ad u?ywa dwóch tabel aby zademonstrowa? generowanie Null w lewym zewn?trznym z??czeniu.
Pierwsza tabela (Pracownik) zawiera identyfikatory i nazwy pracowników, natomiast druga tabela (NumerTelefonu) zawiera powi?zane z identyfikatorami pracowników numery telefonów, jak nast?puje.
|
|
Nast?puj?cy przyk?ad zapytania SQL wykonuje lewe zewn?trzne z??czenie na obu tych tabelach.
SELECT p.ID, p.Nazwisko, p.Imi?, nt.Numer
FROM Pracownik p
LEFT OUTER JOIN NumerTelefonu nt
ON p.ID = nt.ID;
Zbiór danych uzyskanych dzi?ki temu zapytaniu ukazuje jak SQL stosuje Null jako zamiennik dla brakuj?cych danych z prawostronnej tabeli (NumerTelefonu), jak nast?puje.
ID | Nazwisko | Imi? | Numer |
---|---|---|---|
1 | Jankowski | Jacek | 555-2323 |
2 | Krawiec | Ludwik | NULL |
3 | Tomaszewski | Tomasz | 555-9876 |
4 | Pawlikowska | Patrycja | NULL |
W SQL istniej? równie? z??czenia wewn?trzne i krzy?uj?ce, które nie generuj? zamienników Null dla brakuj?cych danych w powi?zanych tabelach.
Nale?y zwróci? szczególn? uwag?, w przypadkach gdy kolumny u?ywane jako kryteria w z??czeniach mog? zawiera? Null. Poniewa? Null nie równa si? jakiemukolwiek innemu Null, Nulle z jednej tabeli nie po??cz? si? z Nullami z powi?zanej kolumny z innej tabeli przy stosowaniu standardowych operatorów równo?ci. W takich przypadkach przydatna jest funkcja SQL COALESCE
lub wyra?enie CASE
do ?symulowania” równo?ci z Null w kryteriach z??czenia, jak równie? mo?na stosowa? predykaty IS NULL
lub IS NOT NULL
.
Nast?puj?cy predykat sprawdza równo?? warto?ci A i B, i traktuje Nulle jakby by?y równe. Operator IFNULL
jest wymagany poniewa? A = B zwraca Null je?li przynajmniej jeden z argumentów A lub B jest Null a NULL OR FALSE
samo z siebie zwraca Null.
IFNULL( A = B, FALSE ) OR ( A IS NULL AND B IS NULL )
Operacje matematyczne i konkatenacja tekstów
[edytuj | edytuj kod]Poniewa? Null nie jest warto?ci? danych, lecz raczej znacznikiem dla warto?ci nieznanej, u?ywanie operatorów matematycznych na Null skutkuje warto?ci? nieznan?, która jest reprezentowana przez Null[8]. W nast?puj?cym przyk?adzie, mno?enie 10 przez Null daje w wyniku Null:
10 * NULL -- Wynik to NULL
Mo?e to prowadzi? do nieoczekiwanych wyników. Na przyk?ad, podczas próby dzielenia Null przez zero, platforma mo?e zwróci? Null zamiast zg?osi? oczekiwany wyj?tek ?dzielenie przez zero”[8]. Chocia? takie zachowanie nie jest zdefiniowane przez standard ISO SQL, wiele dostawców DBMS traktuje t? operacj? podobnie. Na przyk?ad wszystkie platformy Oracle, PostgreSQL, MySQL Server, i Microsoft SQL Server zwracaj? wynik Null dla nast?puj?cego wyra?enia:
NULL / 0
Operacje konkatenacji tekstów, które s? powszechne w SQL, tak?e zwracaj? Null, kiedy jednym z argumentów jest Null[9]. Nast?puj?cy przyk?ad demonstruje wynik Null zwrócony przez operator konkatenacji tekstów ||
.
'kawa?ki ' || NULL || 'ryby' -- Wynikiem jest NULL
Nie jest to prawda we wszystkich implementacjach baz danych. Na przyk?ad w RDBMS Oracle, NULL i pusty tekst s? uznawane za to?same i st?d 'kawa?ki ' || NULL || 'ryby'
daje w wyniku 'kawa?ki ryby'
.
Funkcje agreguj?ce
[edytuj | edytuj kod]SQL definiuje funkcje agreguj?ce aby upro?ci? obliczenia agreguj?ce na danych po stronie serwera. Z wyj?tkiem funkcji COUNT(*)
, wszystkie funkcje agreguj?ce wykonuj? krok eliminacji Null tak, ?e warto?ci Null nie s? uwzgl?dniane w ostatecznym wyniku obliczeń[10]
Nale?y podkre?li?, ?e eliminacja warto?ci Null nie oznacza zast?pienie tych warto?ci przez zero. Na przyk?ad, w poni?szej tabeli, AVG(i)
(?rednia z warto?ci z i
) zwróci inne wyniki ni? AVG(j)
:
i | j |
---|---|
150 | 150 |
200 | 200 |
250 | 250 |
NULL | 0 |
W tym przypadku AVG(i)
to 200 (?rednia ze 150, 200 i 250), podczas gdy AVG(j)
to 150 (?rednia ze 150, 200, 250 i 0).
Grupowanie i sortowanie
[edytuj | edytuj kod]Poniewa? SQL 2003 definiuje, ?e ka?dy znacznik Null jest ró?ny od ka?dego innego, nast?pi?a potrzeba specjalnej definicji pozwalaj?cej na grupowanie warto?ci Null przy wykonywaniu pewnych operacji. SQL definiuje ?dowolne dwie warto?ci które s? równe sobie lub dowolne dwa Null” jako ?nieodr?bne”[11]. Taka definicja nieodr?bno?ci pozwala w SQL na grupowanie i sortowanie Nulli kiedy stosowana jest klauzula GROUP BY
(i inne s?owa kluczowe które dokonuj? grupowania).
Inne operacje, klauzule i s?owa kluczowe SQL, które stosuj? ?nieodr?bne” traktowanie Nulli to:
PARTITION BY
klauzula zaszeregowania i funkcje okienkowe jakROW_NUMBER
- operatory
UNION
,INTERSECT
iEXCEPT
, które traktuj? NULLe jako takie same w celu porównania/eliminacj wierszy - s?owo kluczowe
DISTINCT
stosowane w zapytaniachSELECT
SQL nie definiuje wprost domy?lnego porz?dku sortowania dla Null. W zamian, na systemach zgodnych, Null mo?e by? sortowane przed lub po warto?ciach danych za pomoc? klauzul NULLS FIRST
lub NULLS LAST
odpowiednio w wyra?eniu ORDER BY
. Jednak?e nie wszyscy dostawcy DBMS implementuj? t? funkcjonalno??. Dostawcy, którzy nie implementuj? tej funkcjonalno?ci, mog? okre?la? ró?ne traktowanie Null dla sortowania w DBMS[7].
Wp?yw na indeksowanie
[edytuj | edytuj kod]Niektóre produkty SQL nie indeksuj? kluczy z warto?ciami NULL. Na przyk?ad PostgreSQL przed wersj? 8.3 w dokumentacji dla indeksu o strukturze B-drzewa stwierdza, ?e planista zapytania SQL rozwa?a u?ycie indeksu gdy w zapytaniu s? u?yte operatory relacyjne (tj. < ≤ = ≥ >) oraz ich równowa?ne formy z?o?one (BETWEEN
i IN
), podkre?laj?c, ?e IS NULL
nie jest równoznaczne z = i nie podlega indeksowaniu[12]. W przypadku, gdy indeks wymusza unikatowo??, warto?ci NULL s? wykluczone z indeksu a unikatowo?? nie jest wymuszana pomi?dzy warto?ciami NULL. Warto?ci NULL s? w takim przypadku uznawane za ró?ne. Je?li unikatowy indeks zawiera wi?cej ni? jedn? kolumn?, to odrzucane s? tylko takie przypadki, w których wszystkie kolumny maj? takie same warto?ci[13]. Jest to spójne z definicj? SQL:2003 dotycz?c? zachowania skalarnego porównywania NULL.
Inna metoda indeksowania znaczników Null polega na traktowaniu ich jako nieodr?bnych, w zgodzie z definicj? zachowania w SQL:2003. Na przyk?ad wed?ug dokumentacji do Microsoft SQL Server warto?ci NULL
w kolumnach indeksowanych s? traktowane jako równe i zalecane jest tworzenie indeksów, lub ograniczeń UNIQUE
na kolumnach, w których NULL
nie jest dozwolone[14].
Obie te strategie s? spójne ze zdefiniowanym w SQL:2003 zachowaniem dla znaczników Null. Poniewa? metodologie indeksowania nie s? zdefiniowane przez standard SQL:2003, kwestie indeksowania Null, zarówno projekt jak i implementacja, s? pozostawione ca?kowicie gestii dostawców.
Funkcje obs?uguj?ce Null
[edytuj | edytuj kod]SQL definiuje dwie funkcje do jawnej obs?ugi Null: NULLIF
i COALESCE
. Obie funkcje s? skrótem dla przeszukuj?cego wyra?enia CASE
[15].
NULLIF
[edytuj | edytuj kod]Funkcja NULLIF
przyjmuje dwa parametry. Je?li pierwszy parametr jest równy drugiemu parametrowi to NULLIF
zwraca Null. W przeciwnym razie zwracana jest warto?? pierwszego parametru.
NULLIF(parametr1, parametr2)
Tak wi?c, NULLIF
to skrót dla nast?puj?cego wyra?enia CASE
:
CASE WHEN parametr1 = parametr2 THEN NULL ELSE parametr1 END
COALESCE
[edytuj | edytuj kod]Funkcja COALESCE
przyjmuje list? parametrów a zwraca pierwszy parametr z listy, który nie jest Null:
COALESCE(parametr1, parametr2, parametr3, ...)
COALESCE
jest zdefiniowana jako skrót dla nast?puj?cego wyra?enia SQL CASE
:
CASE WHEN parametr1 IS NOT NULL THEN parametr1
WHEN parametr2 IS NOT NULL THEN parametr2
WHEN parametr3 IS NOT NULL THEN parametr3
...
END
Niektóre DBMS SQL implementuj? specyficzne dla dostawcy funkcje podobne do COALESCE
. Niektóre systemy (np. Transact-SQL) implementuj? funkcj? ISNULL
, lub inne podobne funkcje, które s? funkcjonalnie podobne do COALESCE
.
Kontrowersje
[edytuj | edytuj kod]Powszechne b??dy
[edytuj | edytuj kod]Niezrozumienie zasad dzia?ania Null jest powodem du?ej liczby b??dów w kodzie SQL, zarówno w wyra?eniach zgodnych ze standardem ISO SQL jak równie? w dialektach wspieranych przez rzeczywiste systemy zarz?dzania bazami danych. B??dy te s? zwykle wynikiem pomylenia Null z 0 (zerem) b?d? pustym tekstem (warto?ci? tekstow? o d?ugo?ci zero, przedstawionej w zapisie SQL jako ''
). Jednak Null jest zdefiniowany przez standard ISO SQL jako ró?ny od obu, pustego tekstu i warto?ci liczbowej 0
. Podczas gdy Null wskazuje na brak danych dowolnej warto?ci, pusty tekst i liczba zero przedstawiaj? w?a?ciwe warto?ci.
Na przyk?ad klauzula WHERE
lub wyra?enie warunkowe mo?e porównywa? warto?? kolumny ze sta??. Cz?sto dochodzi do nieprawid?owego za?o?enia, ?e warto?? brakuj?ca mo?e by? ?mniejsza ni?” albo ?ró?na od” sta?ej je?li pole zawiera Null, lecz w rzeczywisto?ci takie wyra?enia zwracaj? Nieznany. Przyk?ad jest poni?ej:
SELECT *
FROM jaka?tabela
WHERE kolumna <> 1; -- Wiersze gdzie kolumna jest NULL nie b?d? zwracane,
-- w przeciwieństwie do oczekiwań wielu u?ytkowników.
Podobnie, warto?ci Null s? cz?sto mylone z pustymi tekstami. Rozwa?aj?c funkcj? LENGTH
, która zwraca liczb? znaków w tek?cie. Kiedy do funkcji zostaje przekazany parametr Null, to funkcja zwraca Null. Mo?e to prowadzi? do nieoczekiwanych wyników, je?li u?ytkownicy nie s? odpowiednio biegli w logice trójwarto?ciowej. Przyk?ad jest poni?ej:
SELECT *
FROM jaka?tabela
WHERE LENGTH(tekst) < 20; -- Wiersze gdzie tekst jest NULL nie b?d? zwracane.
Jest to dodatkowo skomplikowane z uwagi na to, ?e w niektórych programach interfejsu bazy danych, NULL jest zg?aszane jako pusty tekst, a puste teksty mog? by? nieprawid?owo zapisywane jako NULL.
Krytyka
[edytuj | edytuj kod]Realizacja Null w ISO SQL jest przedmiotem krytyki i dyskusji wzywaj?cej do zmian. W The Relational Model for Database Management: Version 2, Codd sugeruje, ?e SQL'owa realizacja Null zosta?a ?le wprowadzona i powinna by? zast?piona przez dwa ró?ne znaczniki typu Null. Znaczniki, które zaproponowa? to brakuj?ce, lecz daj?ce si? zastosowa? oraz brakuj?ce, lecz nie daj?ce si? zastosowa?, znane jako warto?ci-A i warto?ci-I odpowiednio. Zalecenia Codda, gdyby je zaakceptowa?, wymaga?yby wdro?enia czterowarto?ciowej logiki w SQL[3]. Pojawia?y si? równie? sugestie aby doda? kolejne znaczniki Null do zalecanych przez Codda, aby wskaza? wi?cej powodów ?brakuj?cych” danych, zwi?kszaj?c z?o?ono?? logiki systemu SQL. W ró?nych czasach pojawia?y si? tak?e propozycje aby wdro?y? mo?liwo?? definiowania ró?nych znaczników Null przez u?ytkownika. Z uwagi na z?o?ono?? obs?ugi Null i wymagań systemu logiki aby wspiera? ró?norakie znaczniki Null, ?adna z propozycji nie uzyska?a szerszej akceptacji.
Chris Date i Hugh Darwen, autorzy The Third Manifesto, zasugerowali, ?e realizacja Null w SQL jest wewn?trznie wadliwa i powinna by? wyeliminowana w ca?o?ci[16], wskazuj?c na niespójno?ci i b??dy w realizacji obs?ugi Null w SQL (szczególnie w funkcjach agreguj?cych) jako dowód, ?e ca?a koncepcja Null jest b??dna i powinna by? usuni?ta z modelu relacyjnego[17]. Inni, jak Fabian Pascal, wysun?? przekonanie, ?e ?sposób traktowania brakuj?cych danych w obliczeniach nie podlega modelowi relacyjnemu”.
Hipoteza zamkni?tego ?wiata
[edytuj | edytuj kod]Kolejnym punktem konfliktu na tle Null jest to, ?e narusza on model hipotezy zamkni?tego ?wiata relacyjnych baz danych przez wprowadzenie do niego hipotezy otwartego ?wiata[18]. Hipoteza zamkni?tego ?wiata, w odniesieniu do baz danych, stanowi, ?e ?wszystko co jest okre?lone w bazie danych, bezpo?rednio lub w sposób dorozumiany, to prawda; ca?a reszta to fa?sz”[19]. Takie spojrzenie zak?ada, ?e wiedza o ?wiecie zawarta w bazie danych jest kompletna. Jednak Null dzia?a wed?ug hipotezy otwartego ?wiata, w której pewne elementy zapisane w bazie danych s? uwa?ane za nieznane, powoduj?c, ?e wiedza zapisana w bazie danych jest niepe?na.
Prawo wy??czonego ?rodka
[edytuj | edytuj kod]SQL pozwala na trzy logiczne wybory, prawda, fa?sz i nieznany, co oznacza, ?e SQL jest zmuszony do ignorowania prawa wy??czonego ?rodka. Upraszczaj?c, prawo wy??czonego ?rodka stanowi, ?e maj?c dany wynik logiczny, jego przeciwieństwo mo?na uzyska?, stosuj?c operator logicznej negacji. Jednak?e nie ma to zastosowania w SQL dla null. Zgodnie z regu?ami prawa wy??czonego ?rodka, nast?puj?ce wyra?enie logicznie mo?na upro?ci?:
SELECT * FROM stuff WHERE ( x = 10 ) OR NOT ( x = 10 );
Prawo wy??czonego ?rodka pozwala na uproszczenie predykatu WHERE, które mo?na by zast?pi? nast?puj?cym wyra?eniem:
SELECT * FROM stuff;
To nie zadzia?a w SQL, gdy? kolumna x mog?aby zawiera? null, co w wyniku skutkowa?oby zwróceniem pewnych nowych wierszy.
W?a?ciwie:
SELECT * FROM stuff;
-- jest (z uwagi na logik? trójwarto?ciow?) równowa?ne z:
SELECT * FROM stuff WHERE ( x = 10 ) OR NOT ( x = 10 ) OR x IS NULL;
St?d, aby prawid?owo upro?ci? pierwsze wyra?enie w SQL jest wymagane, ?e zwrócone b?d? wszystkie wiersze w których x nie jest null.
SELECT * FROM stuff WHERE x IS NOT NULL;
Podczas gdy ignorowanie prawa wy??czonego ?rodka wi??e si? z dodatkowym skomplikowaniem logiki SQL, próby zastosowania tej regu?y w trójwarto?ciowej logice SQL prowadz? do dychotomii my?lenia.
Niespójno?ci w logicznym typie danych
[edytuj | edytuj kod]Standard ISO SQL:1999 wprowadzi? logiczny typ danych do trójwarto?ciowej logiki SQL. Logiczny typ danych, jak okre?lono w normie, mo?e przechowywa? warto?ci logiczne PRAWDA, FA?SZ i NIEZNANY. Null jest zdefiniowany w tym jednym przypadku jako równowa?ny warto?ci logicznej NIEZNANY.
Propozycja, ?e ?null równa si? warto?ci logicznej NIEZNANY” wprowadza niespójno?? w trójwarto?ciowej logice SQL. Jednym z g?ównych problemów jest to, ?e zaprzecza on podstawowej w?asno?ci null, mianowicie propagacji. Null, z definicji, jest propagowane przez wszystkie wyra?enia SQL. Warto?ci logiczne tej w?asno?ci nie maj?. Rozwa?aj?c nast?puj?ce scenariusze w SQL:1999, w których dwie warto?ci logiczne s? po??czone w z?o?ony predykat, zachodz? nast?puj?ce wyra?enia (zgodnie z regu?ami trójwarto?ciowej logiki SQL, jak to jest przedstawione w tabeli prawdy na pocz?tku artyku?u):
- ( PRAWDA LUB NIEZNANY ) → PRAWDA
- ( FA?SZ I NIEZNANY ) → FA?SZ
Jednak?e, z uwagi na propagacj? null, traktowanie null jako NIEZNANY skutkuje nast?puj?cymi niespójno?ciami w trójwarto?ciowej logice SQL:
( TRUE OR NULL )
→NULL
( = NIEZNANY )( FALSE AND NULL )
→NULL
( = NIEZNANY )
Standard SQL:1999 nie definiuje jak obs?ugiwa? te niespójno?ci, a wyniki mog? by? ró?ne, zale?nie od implementacji. Z powodu tych niespójno?ci i brakiem wsparcia od producentów systemów bazodanowych, logiczny typ danych w SQL nie uzyska? szerszej akceptacji. Obecnie wi?kszo?? platform SQL DBMS oferuje w?asne (i specyficzne) zalecenia dla przechowywania danych typu logicznego.
Nale?y zauwa?y?, ?e w PostgreSQL, warto?? null jest stosowana do przedstawiania wszystkich wyników NIEZNANY oraz zachodz? nast?puj?ce zale?no?ci:
( TRUE OR NULL )
→TRUE
( FALSE AND NULL )
→FALSE
( FALSE OR NULL ) IS NULL
→TRUE
( TRUE AND NULL ) IS NULL
→TRUE
MySQL zachowuje si? w tej kwestii podobnie do PostgreSQL (z ma?ym wyj?tkiem, ?e MySQL traktuje warto?? TRUE
tak samo jak liczb? 1 a warto?? FALSE
jak liczb? 0).
Przypisy
[edytuj | edytuj kod]- ↑ Edgar Frank Codd , Is Your Database Really Relational?, ?ComputerWorld”, 14 pa?dziernika 1985 (ang.). – Czy twoja baza jest naprawd? relacyjna?
- ↑ Edgar Frank Codd , Does Your DBMS Run By The Rules?, ?ComputerWorld”, 21 pa?dziernika 1985 (ang.). – Czy twój system zarz?dzania baz? danych dzia?a zgodnie z zasadami?
- ↑ a b Edgar Frank Codd , The Relational Model for Database Management, wyd. Version 2, Addison Wesley Publishing Company, 1990, ISBN 0-201-14192-2 (ang.).
- ↑ a b ISO/IEC 9075-1:2003 ↓, Section 4.4.2: The null value.
- ↑ a b Michael Coles , Four Rules for Nulls, ?SQL Server Central”, Red Gate Software, 27 czerwca 2005 (ang.).
- ↑ ISO/IEC 9075-2:2003 ↓, Section 8.7: null predicate.
- ↑ a b Michael Coles , Null Versus Null?, ?SQL Server Central”, Red Gate Software, 26 lutego 2007 (ang.).
- ↑ a b ISO/IEC 9075-2:2003 ↓, Section 6.2.6: numeric value expressions.
- ↑ ISO/IEC 9075-2:2003 ↓, Section 6.2.8: string value expression.
- ↑ ISO/IEC 9075-2:2003 ↓, Section 4.15.4: Aggregate functions.
- ↑ ISO/IEC 9075-2:2003 ↓, Section 3.1.6.8: Definitions: distinct.
- ↑ PostgreSQL 8.0.14 Documentation: Index Types [online], PostgreSQL [dost?p 2025-08-14], Cytat: B-trees can handle equality and range queries on data that can be sorted into some ordering. In particular, the PostgreSQL query planner will consider using a B-tree index whenever an indexed column is involved in a comparison using one of these operators: < ≤ = ≥ >
Constructs equivalent to combinations of these operators, such as BETWEEN and IN, can also be implemented with a B-tree index search. (But note that IS NULL is not equivalent to = and is not indexable.) (ang.). - ↑ PostgreSQL 8.0.14 Documentation: Unique Indexes [online], PostgreSQL [dost?p 2025-08-14], Cytat: When an index is declared unique, multiple table rows with equal indexed values will not be allowed. Null values are not considered equal. A multicolumn unique index will only reject cases where all of the indexed columns are equal in two rows. (ang.).
- ↑ Creating Unique Indexes, [w:] MSDN [online], Microsoft, wrzesień 2007 [dost?p 2025-08-14], Cytat: Handling NULL Values
For indexing purposes, NULL values compare as equal. Therefore, a unique index, or UNIQUE constraint, cannot be created if the key values are NULL in more than one row. Select columns that are defined as NOT NULL when columns for a unique index or unique constraint are chosen. (ang.). - ↑ ISO/IEC 9075-2:2003 ↓, Section 6.11: case expression.
- ↑ Hugh Darwen , Chris Date , The Third Manifesto [online] [dost?p 2025-08-14] (ang.).
- ↑ Hugh Darwen , The Askew Wall [online] [dost?p 2025-08-14] [zarchiwizowane z adresu 2025-08-14] (ang.).
- ↑ Chris Date , Database in Depth: Relational Theory for Practitioners, O'Reilly Media, Inc., maj 2005, s. 73, ISBN 0-596-10012-4 .
- ↑ Chris Date , Abstract: The Closed World Assumption [online], Data Management Association, San Francisco Bay Area Chapter [dost?p 2025-08-14] [zarchiwizowane z adresu 2025-08-14] (ang.).
Bibliografia
[edytuj | edytuj kod]- ISO/IEC, ISO/IEC 9075-1:2003, "SQL/Framework", ISO/IEC, 2003 (ang.).
- ISO/IEC, ISO/IEC 9075-2:2003, "SQL/Foundation", ISO/IEC, 2003 (ang.).
Linki zewn?trzne
[edytuj | edytuj kod]- Fabian Pascal , DATABASE DEBUNKINGS [online] [dost?p 2025-08-14] [zarchiwizowane z adresu 2025-08-14] (ang.).
- E.F. Codd , C.J. Date , MUCH ADO ABOUT NOTHING [online] [dost?p 2025-08-14] [zarchiwizowane z adresu 2025-08-14] (ang.). – Wiele ha?asu o nic
- Bug ID: 4032732 Unable to distinguish an SQL NULL string from empty string ('') [online] [dost?p 2025-08-14] (ang.). – Zg?oszenie b??du, ?e JDBC nie odró?nia NULL i pustego tekstu, które zosta?o zamkni?te z komentarzem, ?e to nie b??d.