Я знаю, что эта тема немного противоречива, и в Интернете много разных статей / мнений. К сожалению, большинство из них предполагают, что человек не знает, в чем разница между NULL и пустой строкой. Таким образом, они рассказывают истории об удивительных результатах с объединениями / агрегатами и обычно делают более продвинутые уроки SQL. Делая это, они абсолютно упускают из виду весь смысл и поэтому бесполезны для меня. Поэтому, надеюсь, этот вопрос и все ответы будут продвигать тему немного вперед.
Предположим, у меня есть таблица с личной информацией (имя, рождение и т. Д.), Где один из столбцов - это адрес электронной почты с типом varchar. Мы предполагаем, что по некоторым причинам некоторые люди могут не захотеть предоставлять адрес электронной почты. При вставке таких данных (без электронной почты) в таблицу доступны два варианта: установить для ячейки значение NULL или установить для нее пустую строку (''). Давайте предположим, что мне известны все технические последствия выбора одного решения вместо другого, и я могу создавать правильные запросы SQL для любого сценария. Проблема в том, что даже когда оба значения отличаются на техническом уровне, они одинаковы на логическом уровне. Посмотрев на NULL и «», я пришел к единственному выводу: я не знаю адреса электронной почты этого парня. Кроме того, как бы я ни старался, Я не смог отправить электронное письмо, используя NULL или пустую строку, поэтому, очевидно, большинство SMTP-серверов согласны с моей логикой. Поэтому я склонен использовать NULL там, где я не знаю значения и считаю пустую строку плохой вещью.
После нескольких интенсивных бесед с коллегами я пришел с двумя вопросами:
Прав ли я, полагая, что использование пустой строки для неизвестного значения приводит к тому, что база данных «лжет» о фактах? Чтобы быть более точным: используя представление SQL о том, что является ценностью, а что нет, я мог бы прийти к выводу: у нас есть адрес электронной почты, просто обнаружив, что он не является нулевым. Но потом, когда я попытаюсь отправить электронное письмо, я приду к противоречивому выводу: нет, у нас нет адреса электронной почты, потому что база данных @! # $ Должна была лгать!
Существует ли какой-либо логический сценарий, в котором пустая строка '' могла бы быть таким хорошим носителем важной информации (помимо значения и отсутствия значения), которую было бы проблематичным / неэффективным хранить любым другим способом (например, дополнительным столбцом). Я видел много постов, утверждающих, что иногда полезно использовать пустую строку вместе с реальными значениями и значениями NULL, но до сих пор не видел сценарий, который был бы логичным (с точки зрения дизайна SQL / DB).
PS У некоторых людей возникнет соблазн ответить, что это вопрос личного вкуса. Я не согласна Для меня это дизайнерское решение с важными последствиями. Поэтому я хотел бы увидеть ответы, в которых мнение об этом подкреплено какими-то логическими и / или техническими причинами.
''
даже в Oracle это не так, какNULL
. Например, присвоениеCHAR(1)
столбцу значения''
приведет к' '
(то есть к пробелу), а не кNULL
. Кроме того, если бы Яцек использовал Oracle, этот вопрос, вероятно, даже не поднимался бы :-)'' IS NULL
оцениваетсяtrue
в PL / SQL.Ответы:
Я бы сказал, что
NULL
это правильный выбор для «нет адреса электронной почты». Есть много «недействительных» адресов электронной почты, и «» (пустая строка) - только один. Например, «foo» не является действительным адресом электронной почты, «a @ b @ c» недопустим и так далее. Так что просто потому, что «» не является действительным адресом электронной почты, нет причин использовать его в качестве значения «нет адреса электронной почты».Я думаю, что вы правы, говоря, что «» - это неправильный способ сказать «у меня нет значения для этого столбца». «» Представляет значение.
Примером того, где "" может быть допустимым значением,
NULL
может быть отчество человека. Не у каждого есть отчество, поэтому нужно различать «без отчества» («» - пустая строка) и «я не знаю, есть у этого отчества второе имя» (NULL
). Вероятно, есть много других примеров, когда пустая строка все еще является допустимым значением для столбца.источник
NULL
это не означает, что адрес электронной почты отсутствует, я думаю, что это означает, что адрес электронной почты в настоящее время неизвестен, не существует или его невозможно заполнить по другим причинам. К счастью, вероятно, нет ситуации, когда кто-то хотел бы хранить в базе данных информацию о людях, которые действительно не имеют и не планируют иметь какой-либо адрес электронной почты, в противном случае, вероятно, потребуется отдельное логическое поле.Соглашаясь с приведенными выше комментариями, я бы добавил этот аргумент в качестве основной мотивации:
Для самодокументируемого интуитивного кодирования используйте NULL вместо пустых строк.
источник
В вашем примере, если это значение прямо из веб-поля - я бы использовал пустую строку. Если пользователь может указать, что он не хочет предоставлять электронную почту, или может удалить ее - тогда NULL.
Вот ссылка с точками, которые вы могли бы рассмотреть: https://stackoverflow.com/questions/405909/null-vs-empty-when-dealing-with-user-input/405945#405945
--- отредактировано (в ответ на комментарий Томаса) ---
Базы данных не живут без приложений, которые их используют. Определение NULL или '' не имеет значения, если приложение не может использовать его должным образом.
Рассмотрим один пример, когда пользователь заполняет форму LONG и нажимает Enter, которая отправляет постоянный запрос на сервер. Он может быть в середине ввода своего электронного письма. Скорее всего, вы хотите сохранить все, что он имеет в поле электронной почты, чтобы потом он мог закончить это. Что если он введет только один символ? Что если он введет один символ и затем удалит его? Когда электронная почта не требуется, иногда пользователи хотят ее удалить: самый простой способ просто очистить поле. Также в случае, когда электронная почта не требуется, стоит проверить ее перед отправкой.
Другой пример: пользователь предоставляет электронную почту как spamto @ [bigcompany] .com - в этом случае нет необходимости отправлять электронную почту, даже если она существует и действительна (и может даже существовать). Отправка одного такого может быть дешевой, но если для ежедневных подписок есть 10 000 пользователей с такими электронными письмами, то такая проверка может сэкономить много времени.
источник
Я думаю, что ответ Дина Хардингса охватывает это действительно хорошо. Тем не менее, я хотел бы отметить, что, говоря о пустых строках и пустых строках на уровне БД, вы должны подумать о других ваших типах данных. Будете ли вы хранить минимальную дату, когда дата не указана? или -1, когда int не указан? Сохранение значения, когда у вас нет значения, означает, что вам придется отслеживать весь диапазон не значений. По крайней мере один для каждого типа данных (возможно, больше, когда вы получаете случаи, когда -1 - фактическое значение, поэтому вам нужно иметь какую-то альтернативу и т. Д.). Если вам нужно / вы хотите сделать что-то «вычурное» на уровне приложений, это одно, но не нужно загрязнять ваши данные.
источник
К сожалению, Oracle перепутал представление строки VARCHAR нулевой длины с представлением NULL. Они оба представлены внутри одним байтом со значением ноль. Это делает обсуждение намного сложнее.
Большая путаница вокруг NULL сосредоточена вокруг трехзначной логики . Рассмотрим следующий псевдокод:
Вы не ожидаете третьего сообщения, но это то, что вы получите при трехзначной логике. Три ценная логика ведет людей к многочисленным ошибкам.
Еще одним источником путаницы является вывод из отсутствия данных, например вывод из собаки, которая не лаяла ночью. Часто эти выводы не были тем, что автор NULL намеревался cnvey.
Тем не менее, существует множество ситуаций, когда NULL отлично справляется с отсутствием данных и дает именно те результаты, которые вы хотите. Одним из примеров являются внешние ключи в необязательных отношениях. Если вы используете NULL, чтобы указать отсутствие связи в данной строке, эта строка выпадет из внутреннего соединения, как вы и ожидаете.
Также имейте в виду, что даже если вы полностью избегаете NULLS в хранимых данных (шестая нормальная форма), если вы делаете какие-либо внешние объединения, вам все равно придется справляться с NULLS.
источник
Используйте Null.
Нет никакого смысла хранить значение '', когда подойдет просто сделать поле в таблице nullable. Это делает запросы более очевидными.
Какой SQL-запрос более очевиден и удобочитаем, если вы хотите найти пользователей с адресом электронной почты?
SELECT * FROM Users WHERE email_address != ''
SELECT * FROM Users WHERE email_address IS NOT NULL
SELECT * FROM Users WHERE email_address != '' and email_address IS NOT NULL
Я бы сказал, 2 есть. Хотя 3 более надежна в тех случаях, когда хранятся плохие данные.
В случае адреса электронной почты в форме, который является необязательным, он также должен быть отражен в таблице. В SQL это пустое поле, что означает, что оно не известно.
Я не могу думать о какой-либо разумной коммерческой ценности для хранения пустой строки в таблице, кроме просто плохого дизайна. Это похоже на хранение строкового значения «NULL» или «BLANK», и когда разработчики предполагают, что это пустая или пустая строка. Для меня это плохой дизайн. Зачем хранить это, когда есть NULL?
Просто используйте NULL, и вы сделаете всех чуть более счастливыми.
БОЛЬШЕ ИНФОРМАЦИИ:
SQL использует трехзначную логическую систему: True, False и Unknown.
Для лучшего и более подробного объяснения я рекомендую разработчикам прочитать: SQL Queries - за пределами TRUE и FALSE .
источник
для конкретного технического вопроса проблема не пустая, а пустая строка, это ошибка проверки . Пустая строка не является действительным адресом электронной почты!
на философский вопрос ответ аналогичен: подтвердите свои данные. Если пустая строка является допустимым значением для рассматриваемого поля, то ожидайте его и код для него; если нет, используйте ноль.
Пустая строка будет правильным вводом для ответа на вопрос: что пантомима сказала жирафу?
источник
Я мог бы подумать о причине наличия NULL и пустой строки:
me@example.com
NULL
Empty String.
Однако я не рекомендовал бы это и использовал бы отдельное поле для того, чтобы спросить, знаете ли вы, что ни один не существует.
источник
Насколько я понимаю, вопрос в том, какие интерпретации NULL и пустой строки следует выбирать. Это зависит от того , сколько состояний particualar поле может быть.
Интерпретация зависит от того, как осуществляется доступ к базе данных. Если в коде есть слой, который полностью абстрагирует базу данных, то выбор любой политики (в том числе двухзначной), которая работает, вполне приемлем. (Очевидно, что документирование политики важно). Однако, если к базе данных обращаются в нескольких местах, вам следует использовать очень простую схему, поскольку поддерживать код будет сложнее и в этом случае может быть ошибочным.
источник
Ну, в принципе, на логическом уровне нет разницы между «недопустимым» значением и «отсутствием пользовательского ввода», в большинстве случаев это просто «особые случаи». Ошибка в случае.
Значение null занимает дополнительное пространство: ceil (columns_with_null / 8) в байтах на строку.
Пустая ячейка и ноль - оба способа пометить что-то не так / должны быть по умолчанию. Зачем вам нужно 2 "неправильных" состояния? Зачем использовать NULL, если они занимают дополнительное место и означают то же самое, что и пустые строки? Это просто внесет путаницу и избыточность, когда у вас есть две вещи, которые означают (что может означать) абсолютно одно и то же, легко забыть, что вы должны использовать NULL вместо пустых строк (если, например, пользователь пропустил некоторые поля).
И ваши данные могут стать беспорядком. В идеальном мире вы бы сказали, что «данные будут всегда правильными, и я буду помнить» ... но когда люди должны работать в команде, а не все точно на вашем уровне, нередко видеть ГДЕ (аа. xx <> '' И bb.zz НЕ НУЛЬ)
Поэтому вместо того, чтобы исправлять членов моей команды каждый день, я просто применяю простое правило. Нет нулевых значений, НИКОГДА!
Подсчет NON-NULL значений происходит быстрее ... простой вопрос: зачем вам это нужно?
источник
VARCHAR
столбцу потребуется не менее 1 байта для хранения длины строки, даже если она равна нулю.Я склонен рассматривать это не с точки зрения БД, а с точки зрения программы. Я знаю, что этот вопрос касается клика по SQL, но на самом деле, сколько пользователей больше обращаются к данным напрямую?
В программе мне не нравится нуль / ничего. Есть несколько исключений, но они только это. И эти исключения на самом деле просто плохие реализации.
Так что, если пользователь не вставил электронное письмо, должно быть что-то, что определяет, является ли это действительным или нет. Если пустое письмо в порядке, то оно отображает пустую строку. Если пользователь не вставил электронное письмо, и это нарушает правило, объект должен указать это.
Идея нулевого значения имеет смысл старой школы, и современные программисты должны ее обойти.
Даже в дизайне БД почему поле электронной почты не может содержать пустые значения, иметь строку нулевой длины и иметь другое поле, указывающее, вводит ли пользователь что-то? Стоит ли так много просить о СУБД? По моему мнению, БД не должна обрабатывать ни бизнес-логику, ни логику отображения. Он не был создан для этого и поэтому очень плохо справляется с этим.
источник
Я не думаю, что это имеет большое значение, но мне больше нравится, когда там NULL.
Когда я просматриваю данные, отображаемые в таблице (как в SQL Server Management Studio), я могу лучше различить отсутствующее значение, если оно говорит о NULL, а фон имеет другой цвет.
Если я вижу пустое пространство, мне всегда интересно, действительно ли оно пустое, или есть какие-то пробелы или какие-то невидимые символы. С NULL он гарантированно пуст с первого взгляда.
Я обычно не различаю значения в приложении, потому что это неожиданно и странно, что NULL и пустая строка означают что-то другое. И большую часть времени я придерживаюсь оборонительного подхода и просто имею дело с обоими государствами. Но для меня, как человека, NULL легче обрабатывать при просмотре данных.
источник