Изменения

Перейти к: навигация, поиск

Неполные данные и null

1524 байта добавлено, 19:27, 4 сентября 2022
м
rollbackEdits.php mass rollback
{{В разработке}}
 
== Что означает null ==
Представим себе таблицы в БД университета ИТМО
=== Сравнение ===
==== = Равенство ====
{| style="background-color:#CCC;margin:0.5px;text-align:center"
!style="background-color:#EEE;color:#00F"| <tex>\bf{=}</tex>
|style="background-color:#FFF;padding:2px 30px"| <tex>false</tex>
|}
 
== Проблемы при работе с null ==
При работе с '''null''' в процессе разработки БД, во избежание непредвиденных ошибок, необъодимо заранее ознакомиться с тем, какие проблемы могут возникнуть.
=== Неоднозначность импликации Вывод логических выражений ==='''TODO: уточнить'''В новой тернарной логике работают не все правила преобразований, присущие двоичной.* A → B = (not A) or B{| style="background-color:#CCC;margin-left:2rem;text-align:center"!style="background-color:#EEE;color:#00F"| Например, нельзя полагать, что <tex>\bf{(not\ A)\ or\ B}</tex>!style="background-color:#EEE"| <tex>\bf{true}</tex>!style="background-color:#EEE"| <tex>\bf{unknown}</tex>!style="background-color:#EEE"| <tex>\bf{false}</tex>|-|style="background-color:#EEE;padding:2px 30px"| <tex>vee\bf{true}</tex>|style="background-color:#FFF;padding:2px 30px"| <tex>true</tex>|style="background-color:#FFF;padding:2px 30px"| <tex>unknown</tex>|style="background-color:#FFF;padding:2px 30px"| <tex>false</tex>|-|style="background-color:#EEE;padding:2px 30px"| <tex>\bf{unknown}</tex>|style="background-color:#FFF;padding:2px 30px"| <tex>true</tex>|style="background-color:#FFF;padding:2px 30px"| <tex>unknown</tex>|style="background-color:#FFF;padding:2px 30px"| <tex>unknown</tex>|-|style="background-color:#EEE;padding:2px 30px"| <tex>neg\bf{false}</tex>|style="background-color:#FFF;padding:2px 30px"| <tex>true</tex>|style="background-color:#FFF;padding:2px 30px"| <tex>true</tex>|style="background-color:#FFF;padding:2px 30px"| <tex>true</tex>|} * A → B = not (A and not B){| style="background-color:#CCC;margin-left:2rem;text-align:center"!style="background-color:#EEE;color:#00F"| <tex>\bf{not\ (A\ and\ not\ B)}</tex>!style="background-color:#EEE"| <tex>\bf{true}</tex>!style="background-color:#EEE"| <tex>\bf{unknown}</tex>!style="background-color:#EEE"| <tex>\bf{false}</tex>|-|style="background-color:#EEE;padding:2px 30px"| <tex>\bf{true}</tex>|style="background-color:#FFF;padding:2px 30px"| <tex>true</tex>|style="background-color:#FFF;padding:2px 30px"| <tex>unknown</tex>|style="background-color:#FFF;padding:2px 30px"| <tex>false</tex>|-|style="background-color:#EEE;padding:2px 30px"| <tex>\bf{unknown}</tex>|style="background-color:#FFF;padding:2px 30px"| <tex>true</tex>|style="background-color:#FFF;padding:2px 30px"| <tex>unknown</tex>|style="background-color:#FFF;padding:2px 30px"| <tex>unknown</tex>|-|style="background-color:#EEE;padding:2px 30px"| <tex>\bf{false}</tex>|style="background-color:#FFF;padding:2px 30px"| <tex>true</tex>|style="background-color:#FFF;padding:2px 30px"| <tex>true</tex>|style="background-color:#FFF;padding:2px 30px"| <tex>true</tex>|}Оказывается всегда истинно, потому что законы Де Моргана в данном случае теперь может получиться '''не работают'unknown''. <br>Поэтому при каждом преобразовании троичного логического выражения, лучше сверяться с таблицами истинности.
=== Скалярные операции, порождающие null ===
Следующие операции с '''null''' порождают '''null''', и иногда это может сбивать с толку начинающих разработчиков.
* <tex>=</tex>, <tex><></tex>, <tex><</tex>, <tex><=</tex>, <tex>></tex>, <tex>>=</tex>* <tex>+</tex>, <tex></tex>, <tex>*</tex>, <tex>/</tex>* <tex>\||</tex>* <tex>in</tex>
Рассмотрим несколько примеров.
<font color = blue>select</font> (1 + <font color = blue>null</font>) <font color = blue>from</font> Students;
== Работа с null в SQL ==
Несмотря на множество проблем, описанных выше, в SQL существуют механизмы, позволяющие корректно обработать '''null'''.=== Проверки значений ===Для сравнения с '''null''' используется <font color = blue>is null</font> (или <font color = blue>is not null</font>).Получить всех студентов с '''''null''''' в поле ''GroupId'' можно следующим образом: <font color = blue>select</font> StudentId <font color = blue>from</font> Students <font color = blue>where</font> GroupId <font color = blue>is null</font>;В общем виде синтаксис проверки значений выглядит следующим образом:<font color = red>значение</font> <font color = blue>is</font> <font color = red>[</font><font color = blue>not</font><font color =red>]</font> <font color =red>{</font><font color =blue>null</font>|true|false|unknown<font color =red>}</font>, например:* x <font color = blue>is not</font> true* x <font color = blue>or</font> x <font color = blue>is not null</font> Так же в SQL существует функция '''''coalesce(v1, v2, ...) =====* Принимает ''''', которая принимает произвольное число аргументов и возвращает первый не '''не null* '''. Если все аргументы '''null - ''', то возвращает '''null'''.
=== Ключи и null ===
==== DML ====
<font color = blue>where</font> и <font color = blue>having</font> считают истинным предикат '''только если он вернул ''true'''''
Зная этот факт можно, например убедиться, что ''false'' <font color = blue>and</font> ''unknown'' дает ''false''. Следующий запрос вернет 1:
<font color = blue>select</font> 1 <font color = blue>where not</font> (0 = 1 <font color = blue>and</font> 0 = <font color = blue>null</font>)
 
==== DDL ====
C точки зрения <font color = blue>check</font> constraint-ов не подходит только ''false''. ''Unknown'' превращается в ''true''
=== Типы столбцов ===
* В SQL столбцы могут быть <font color = blue>nullable</font> (по умолчанию)** и не <font color = grayblue>birthday datenullable</font>* <font color = blue>Не nullablebirthday date</font>** <font color = gray>birthday date</font> <font color = blue>not null</font>
Перед созданием <font color === Проверки значений ======= Синтаксис ====*значение is [not] {null|true|false|unknown}==== Примеры ====* x is blue>nullable</font> столбца, рекомендуется дополнительно обдумать, какой конкретно смысл вкладывается в '''null* x is not true* (x or x) is ''' в данном случае, не скажется ли это негативно на остальных запросах, в случае, если начать его использовать. Если есть возможность, во избежание дополнительных проблем, описанных выше, лучше объявлять столбцы '''not null'''.
=== Прочее ===
* <font color = blue>exists</font>** возвращает ''true'' или 'false'** если внутри получились только строки, Агрегирующие состоящие из '''null''', то вернет так же ''false''* агрегирующие функции(<font color = blue>count</font>, <font color = blue>sum</font>, <font color = blue>avg</font> и т.д.)** пропускают '''''null''''', т.е. не учитывают его при подсчете** при отсутствии аргументов, Order отличных от '''''null''''', возвращают '''''null'''''** исключением является <font color = blue>count</font>(*), что просто считает количество строк* <font color = blue>order by</font>** Помимо указаний порядка сортировки (asc или desc), можно указывать, куда ставить '''''null'''-ы'' - в начало или в конец. Например <font color = blue>order by</font> year nulls first. По умолчанию '''''null'''-ы'' складываются либо в начало, либо в конец, это нужно уточнять в документации к конкретной СУБД.
1632
правки

Навигация