[mysql] а нужен ли NULL ?

maxiim9

Вот скажите, какая практическая польза от NULL-значений по умолчанию?
Есть ли вред от использования

`num` int NOT NULL default '0'

Если нет, то почему бы не использовать всегда илициализированные переменные, так как это уменьшает неоднозначность начальных значений в базе.
Ведь обычно под NULL в программе подразумевается какое-либо осмысленное значение (например, 0 или пустая строка, или ещё что - не важно)...

tamusyav

Даже не знаю, что сказать... ботай матчасть на тему того, что такое NULL и зачем он нужен...
NULL - тоже вполне себе осмысленное значение, указывающее, например, на отсутствие данных. И это не 0 или пустая строка и считать одно другим далеко не всегда оправдано.

maxiim9

Я понимаю, что надо ботать мат.часть.
Кстати может прямую ссылку на мат.часть кто даст?
Но с практической точки зрения:
Будем рассматривать mysql как подспорье для web.
Допустим, есть некая анкета, которую заполняет человек через форму на сайте;
если поля в анкете оставлены пустыми, то в базу они попадут как пустая строка '', а не как NULL (в обычной реализации, если специально не заботиться об обратном).
В то же время возможен вариант, когда данные в таблицу вносились другим способом, и некоторые поля приняли значение NULL.
Дальше когда я делаю, например, SELECT DISTINCT записи с NULL и пустой строкой оказываются в разных категориях, хотя в данном случае по смыслу это одно и то же.
Аналогично с цифрами. Для защиты от неверных данных, обычно в скриптах делается intval floatval которые выдают 0, если передать им не цифру, в частности NULL. То есть с логической точки зрения во всех скриптах подразумевается, что никаких NULL быть не должно...

maxiim9

Я не говорю про случай, когда мне нужно использовать NULL как осмысленное значение.
Я понимаю, что NULL и 0 или NULL и пустая строка это не одно и то же.
Просто примеров, когда это нужно, очень мало.
Вопрос именно про мат.часть: сказывается ли на производительности или ещё на чем использование NOT NULL записей.

Marinavo_0507

производительность повышается вроде

evgen5555

Просто примеров, когда это нужно, очень мало.

Нда, кое-кому, видимо, приходится работать только с web-анкетами

durka82

Вообще NULL нужен, если предусмотрена возможность, что часть данных может не задаваться вообще (например, на позицию в анкете Высшее образование в случае отсутствия такового в соотв поле может быть просто NULL - и мне кажется, что это правильно).
Если в конкретной базе NULL считается недопустимым - его и не нужно использовать - практически любую задачу можно так решить - только вот нужно ли.
Короче, если ты не знаешь, зачем тебе NULL, - не используй его.
Но вот вводить ему замену не думаю, что разумно (особенно с точки зрения производительности).

maxiim9

Ты когда пишешь на Си, ты ведь числовые переменные нулём инициализируешь.
Или, может, я пиши не те программы?

durka82

А смысл?
Переменную надо инициализировать в то значение, какое в ней должно быть по условию задачи.
То есть если это накопительная переменная по сложению - тогда да - инициализировать нулем.
Какой смысл просто так инициализировать все подряд переменные нулем?
Если бы был - компилятор Си и так бы это делал.

evgen5555

Не, на самом деле, если и надо что-то инициализировать, то только -1
А вот, например, в ADO.NET есть у ячейки метод IsDbNull из которого сразу понятно, что почём

maxiim9

Ну в Mysql тоже можно делать SELECT ... WHERE num IS NULL, ну и что с того.
Чем именно инициализировать зависит от задачи.
Мне просто интересно, хоть кто-то делает в своих программах UPDATE ... SET num=NULL ?
Или всё-таки находится переменная-аналог NULL (будь то 0 или -1 или -2 - неважно которая ставится, если нужно сделать вид, что ячейка неинициализирована.

Marinavo_0507

Мне просто интересно, хоть кто-то делает в своих программах UPDATE ... SET num=NULL ?
Ну чё пристал?
В форуме есть пара мест подобных, только там INSERT.

durka82

Мне просто интересно, хоть кто-то делает в своих программах UPDATE ... SET num=NULL ?
Если значение поля - ссылка - БД делает это сама при удалении поля, на которое эты ссылка ссылается.
А вот если кто-то по ошибке ввел информацию о высшем образовании, а на самом деле у него его нет, как раз так и придется исправлять ситуацию.
Или всё-таки находится переменная-аналог NULL (будь то 0 или -1 или -2 - неважно)
На самом деле это уже сделано на уровне самой БД.
То есть есть некоторое число, при наличии которого в поле БД считает, что там NULL.
Какой смысл дублировать это еще раз самим?
Если придумать зачем - почему бы и нет...

maxiim9

Зачем это делать при INSERT'ах, могу придумать
Например, стоит значение в auto_increment, тогда вставим NULL, оно само увеличится.
Ну чё пристал?
Да просто переписываю пару скриптов и вижу, что с логической точки зрения в половине таблиц стоит поставить значения по умолчанию NOT NULL. Вот и решил поинтересоваться, насколько я не прав и почему

durka82

вижу, что с логической точки зрения в половине таблиц стоит поставить значения по умолчанию NOT NULL
Если видишь, что надо - так и ставь.
Это зависит от конкретного случая - и твой случай получается самым что ни на есть конкретным.

Marinavo_0507

Думаю, ты прав.
Если по логике программы значение NULL не нужно - надо ставить not null.

Dasar

Важно помнить, что в бизнес логике важно уметь различать три категории ответов:
1. "да" (положительный)
2. "нет" (отрицательный)
3. "не знаю" (нет информации или не имеет смысла в данной ситуации)
например:
вы уже пользовались нашими услугами?
1. "да" - true
2. "нет" - false
3. "не знаю" - null
какой у вас готовой доход?
1. "да" - хранится в виде числа больше 0
2. "нет" - хранится в виде числа 0
3. "не знаю" - хранится в виде null-я
вопрос: какие имена ваших детей?
1. "да" - будет хранится как заполненный массив строк
2. "нет" - будет хранится как пустой массив строк
3. "не знаю" - null
null (нет информации) может появляться и при расчетах, например, при расчете среднего:
так среднее от пустого множества чисел - есть null.
в ряде задач, можно считать, что не знаю и отрицательный ответ - идентичны, но бывают важные моменты, когда необходимо отличать одного от другого.
возьмем отчество - здесь важны все три ответа:
1. "да" - отчество есть: строка не нулевой длины
2. "нет" - отчества нет (например, для иностранца): строка нулевой длины
3. "не знаю" - отчество не указано: null
Соответственно, если мы начинаем заполнять официальные документы, где требуется полное ФИО, то
во втором случае, просто подставляется пустая строка, а в третьем случае - необходимо запросить отчество у пользователя.

durka82

Это все конечно хорошо, но в примерах с годовым доходом и со списком имен хранение отрицательного ответа в таком виде допустимо, но правильнее (мб и не с тз производительности) "да"/"нет"(а наверное и "не знаю" в виде NULL) хранить отдельно от самого значения.

Dasar

> но правильнее (мб и не с тз производительности) "да"/"нет"(а наверное и "не знаю" в виде NULL) хранить отдельно от самого значения.
чем более правильно?
есть два хороших стремления:
1. чтобы как можно более связанную информацию хранить как можно ближе к друг другу, а как можно более разнесенную - дальше друг от друга.
2. не дублировать информацию
твое предложение идет в разрез с обоими этими стремлениями

sinet

>сказывается ли на производительности или ещё на чем использование NOT NULL записей.
Конечно. NULL = "нет данных". Место под них не выделяется. И данных никаких не пишется.
Попробуй сделать на таблице с несколькими миллионами записей команды:
ALTER TABLE tab ADD col NUMBER
и
ALTER TABLE tab ADD col NUMBER NOT NULL DEFAULT 0
Вторая будет выполняться ощутимо дольше.

Dasar

> Вторая будет выполняться ощутимо дольше.
очень сильно зависит от реализации базы

sinet

Ну вряд ли быстрее.
Или есть примеры обратного?
Ещё и constraint на NOT NULL будет...

Dasar

если записи хранятся фиксированного размера, то и в том, и в другом случае будет идти раздвижка каждой записи, причем в одном случае (без null-я) на 4 байта, а с null-ом на 5.
> Ещё и constraint на NOT NULL будет...
так он наоборот полезен, т.к. если мы знаем, что null-евых записей не будет, то обрабатывать записи (хотя бы тоже самое чтение) становится намного проще.

bastii

с поддержкой NULL значений в БД связана полезная функциональность, которая выражается в спец арифметике, когда NULL + 1 дает NULL — в случае когда NULL-значение используется как "неизвестно", получает очень удобно

Hastya

ботать, ботать и ботать
100/0 = бесконечность, но 100/NULL = NULL
миллион примеров, когда это используется

durka82

есть два хороших стремления:
Этими стремлениями все не ограничивается.
Например, есть такое хорошее стремление - чтобы структура данных согласовывалась с функциональностью, и еще одно - чтобы все это минимизировало потенциальные ошибки.
какой у вас готовой доход?
...
2. "нет" - хранится в виде числа 0
а. Кто сказал, что годовой доход не может быть нулевым? То есть это предположение уже отсекает вариант. А если этот вариант таки понадобится - изменения, которые придется внести, будут велики.
б. По поводу стремления:
Твой вариант (если пользователь введет 0 - значит он не хочет указывать свой доход) способствует тому, что может появиться реализация, когда будет просто поле для числа. Еще не факт, что там будет написано, что ввод нуля означает отказ от указания своего дохода. И непонятно, как проверять, введен ли 0 сознательно или случайно. И тогда чтобы понять, какой вариант выбрал пользователь, придется что-то придумать: или таки сделать доп кнопку, или использовать строковое поле и парсить его.
Мой вариант подразумевает, что сначала пользователь явно выберет один из трех вариантов и введет сумму только в одном случае - криво реализовать это будет проблематично.
вопрос: какие имена ваших детей?
...
2. "нет" - будет хранится как пустой массив строк
И зачем хранить пустой массив строк?

Realist

Твое стремление использовать -1 вместо NULL, возможно, объясняется тем, что во многих языках значения NULL не предусмотрено. В том же Си я не могу явно сказать, что значение переменной не задано. Поэтому я должен выдумывать магию с отрицательными числами и интерпретировать их как отсутствие значения.
В БД есть прямой путь выразить "значение неизвестно/не задано" и моделировать его отрицательными резона нет.
Пример, когда реально нужен NULL. В базе концертов есть поле "Дата концерта". Иногда известно, что концерт будет, но когда — неизвестно.
Путаница с пустыми значениями — признак недоразвитости веб-форм, я думаю.

Dasar

ты точно понял, что такое "да", "нет", "не знаю"?

Dasar

> Кто сказал, что годовой доход не может быть нулевым?
0 годовой доход и означает, что годового дохода нет.

Dasar

> И зачем хранить пустой массив строк?
в чем проблема? это решение даже по памяти более выгодное, чем твое

Dasar

> И тогда чтобы понять, какой вариант выбрал пользователь, придется что-то придумать: или таки сделать доп кнопку, или использовать строковое поле и парсить его
во-первых, какое отношение ввод информации имеет к хранению информации?
во-вторых, чем для ввода плохо одно поле, в котором указывается либо произвольное число, либо пусто.

mysha

NULL очень сильный инструмент, только сейчас им не пользуются -
по причинам сложной семантики...
ботай Left join и Right join
сейчас эти операторы заменяются select, потому и теряют в выразительноси

ava3443

ботай Left join и Right join
сейчас эти операторы заменяются select, потому и теряют в выразительноси
тут ты что-то умное сказал
можешь чуть подробнее, а то непонятно?

ava3443

Попробуй сделать на таблице с несколькими миллионами записей команды:
ALTER TABLE tab ADD col NUMBER
и
ALTER TABLE tab ADD col NUMBER NOT NULL DEFAULT 0
Вторая будет выполняться ощутимо дольше.
и чего? это однократная задача администрирования базы,
к производительности приложения ну никакого отношения не имеющая

sinet

Рассмотри добавление столбцов как insert`ы в таблицу. Так просто наглядней.
Но похоже в мускуле как-то с NULL`ами совсем тухло.
Даже в мануале не рекоммендуют их использовать.

Marinavo_0507

afaik в mysql это пофиг
он просто перекопирует все данные заново
в этом его сущность - всё просто, понятно и предсказуемо *
* естественно, с добавлением всё новых фич эти достоинства постепенно стираются

sinet


Объявляйте везде, где возможно, столбцы как NOT NULL. Это позволяет ускорить все операции и сэкономить по одному биту для каждого столбца. Однако если для данного приложения действительно нужен NULL, то вы все-таки его (NULL) используйте. Нужно просто избегать наличия NULL во всех столбцах по умолчанию.

ava3443

afaik в mysql это пофиг
так я не о том. я утверждаю, что приведённый выше пример не имеет смысла на любой СУБД: добавление столбца производится лишь один раз, и сколько оно будет выполняться - никому не интересно

ava3443

по теме-то я согласен, раз в документации MySQL не рекомендуют использовать NULL, видимо неспроста
но вот это - лишь ничем не подкреплённая гипотеза
Рассмотри добавление столбцов как insert`ы в таблицу. Так просто наглядней.
пока в исходники MySQL не залезешь, как работает добавление столбца не узнаешь

Marinavo_0507

если при этом сервис простаивает, то не очень пофиг
в контексте веб-программирования - есть разница, 1 минута или несколько часов, например
Оставить комментарий
Имя или ник:
Комментарий: