Что такое default null
Ограничения в Microsoft SQL Server — что это такое и как их создать?
Сегодня мы с Вами затронем очень интересную, важную и, наверное, сложную для начинающих тему – это ограничения в Microsoft SQL Server. После прочтения статьи Вы узнаете, для чего нужны ограничения, какие типы ограничений бывают в SQL Server, а также научитесь создавать эти ограничения.
Начнем мы, конечно же, с рассмотрения вопроса, что такое ограничения и для чего они нужны в базе данных.
Что такое ограничения в Microsoft SQL Server?
Ограничения – это специальные объекты в Microsoft SQL Server, с помощью которых можно задать правила допустимости определенных значений в столбцах с целью обеспечения автоматической целостности базы данных. Другими словами, ограничения формируют некое условие на те данные, которые будут вводиться в таблицу и храниться в ней. Например, какие-то данные должны быть уникальными, какие-то данные из разных таблиц должны быть неразрывно связаны по общему ключу, а какие-то данные вообще хранить не стоит, т.е. в каком-нибудь столбце не должно быть определенных значений.
Ограничения, как я уже сказал, очень важные объекты в SQL сервере, так как в процессе планирования структуры таблицы Вы всегда должны продумывать допустимые значения, которые могут храниться в том или ином столбце. Вручную контролировать процесс добавления и хранения данных в корректном виде просто невозможно. Поэтому, SQL сервер предоставляет специальный механизм, с помощью которого мы можем установить жесткие правила на ввод и хранение данных, иными словами, автоматизировать процесс контроля корректности данных. Если Вы захотите обойтись без использования ограничений при проектировании и реализации базы данных, то в скором времени у Вас будет не база данных, а просто набор непонятной и несогласованной информации.
Типы ограничений в SQL Server
В Microsoft SQL Server реализовано несколько типов ограничений, каждое из которых предназначено для выполнения какой-то конкретной задачи, и сейчас мы с Вами рассмотрим эти типы.
Ограничение NOT NULL
Это ограничение, с помощью которого мы можем запретить или наоборот разрешить хранение в столбце значений NULL, т.е. неопределенных значений. Таким образом, мы можем сказать, что если у нас запрещены значения NULL в столбце, то этот столбец является обязательным к заполнению, а если у нас разрешены значения NULL, то столбец можно и не заполнять, т.е. данное ограничение поможет нам контролировать внесение и хранение обязательных характеристик той или иной сущности. И, конечно же, Вы должны знать, что наличие значений NULL в базе данных — это не очень хорошо, поэтому данное ограничение помогает исключить такие значения.
С этим ограничением Вы, наверное, уже сталкивалась, и неоднократно работали, так как при создании таблицы, или добавления нового столбца, мы практически всегда указываем возможность принятия столбцом значений NULL, для этого мы пишем NULL или NOT NULL в определении таблицы.
Ограничение PRIMARY KEY
PRIMARY KEY – ограничение первичного ключа. Первичный ключ – это столбец или комбинация столбцов, значения которых гарантируют уникальность каждой строки, что дает нам возможность идентифицировать каждую строку в таблице по данному ключу.
PRIMARY KEY должен быть практически в каждой таблице, и он должен быть у нее один. Обычно первичный ключ создают для столбца, который выполняет роль счетчика (IDENTITY), и он не может содержать значения NULL. Создав ограничение PRIMARY KEY, Вы можете не беспокоиться о том, что в Вашей таблице вдруг окажется две записи с одинаковым идентификатором.
Ограничение FOREIGN KEY
FOREIGN KEY – это ограничение внешнего ключа. Ограничение FOREIGN KEY предназначено для установления связи между данными в таблицах. Иными словами, если в таблице есть ключ (столбец, обычно идентификатор), который есть и в другой таблице, то эти таблицы должны быть связаны с помощью ограничения FOREIGN KEY. Таким образом, с помощью данного ограничения мы выстраиваем связь между таблицами в базе данных.
Ограничение FOREIGN KEY обеспечивает ссылочную целостность, оно позволяет исключить ситуации, когда, например, у Вас в одной таблице есть записи, которые ссылаются на отсутствующие записи в другой таблицы, т.е. этих записей нет, в итоге получаются некорректные данные.
Ограничение UNIQUE
UNIQUE – это ограничение, которое обеспечивает уникальность значений в столбце или комбинации столбцов. UNIQUE позволяет исключить повторяющиеся значения в столбце. В отличие от PRIMARY KEY, для таблицы можно задать несколько ограничений UNIQUE, и столбец, для которого определено данное ограничение, может содержать значение NULL (но, как Вы понимаете, такое значение может быть только одно в этом столбце). В случае если столбцы в таблице были определены без ограничения UNIQUE при создании таблицы, то для того чтобы добавить этого ограничения, в соответствующем столбце не должно быть повторяющихся значений.
Ограничение CHECK
CHECK – это проверочное ограничение. Данное ограничение проверяет данные, на предмет выполнения определенных условий, при вводе в таблицу. Иными словами, если Вам требуется, чтобы в столбце хранились только значения, которые отвечают определённым требованиям, то как раз с помощью ограничение CHECK Вы можете автоматизировать процесс контроля за вводом данных. Например, по бизнес требованию, цена товара не должна быть отрицательной, для этого в таблице для столбца, который хранит цену товара, мы можем определить проверочное ограничение CHECK, которое будет проверять все значения, вносимые в данный столбец. Таким образом, мы на уровне сервера задаем четкие правила допустимых значений определенных столбцов.
К одному столбцу в таблице мы можем применять несколько проверочных ограничений. Создать проверочное ограничение UNIQUE можно с любым логическим выражением, которое возвращает значение TRUE или FALSE.
Ограничение DEFAULT
DEFAULT – это значение по умолчанию. Мы уже говорили о том, что значение NULL — это не очень хорошо, поэтому еще одним способом избавления от данного значения, является возможность задать для столбца значение по умолчанию, которое будет сохранено, если при вводе данных мы не указали никакого значения. Например, если в столбец с ценой товара не указать цену, когда мы будет добавлять новый товар, то SQL сервер автоматически добавит значение по умолчанию, которое мы укажем при определении этого ограничения, к примеру, 0.
Примеры создания ограничений в Microsoft SQL Server
Сейчас давайте рассмотрим примеры создания и добавления ограничений на языке T-SQL. Все ограничения также можно создавать и с помощью графической среды SQL Server Management Studio.
Примечание! Все примеры ниже выполнены в Microsoft SQL Server 2016 Express. Также рекомендую Вам ознакомиться с основами языка T-SQL, так как все, что не касается ограничений в примерах ниже, подразумевается, что Вы уже знаете. Поэтому если Вам что-то не понятно можете найти ответы в следующих материалах:
Пример создания ограничения NOT NULL и DEFAULT
Сначала мы рассмотрим пример создавать ограничения NOT NULL и DEFAULT. Это можно сделать как при создании таблицы, так и после, т.е. добавить ограничение отдельной инструкцией.
В первом случае показано, как создаются ограничения NOT NULL и DEFAULT во время создания таблицы.
Для первого столбца мы просто указали NOT NULL, что говорит о том, что данный столбец не может содержать значения NULL.
Для второго столбца мы задали значение по умолчанию 0, с помощью ключевого слова DEFAULT, это сокращённая запись добавления данного ограничения.
Для третьего столбца мы также задали значение по умолчанию 0, но при этом использовали полное определение ограничения с применением ключевого слова CONSTRAINT (DF_C3 — это имя ограничения).
Во второй инструкции показано, как добавлять ограничение NOT NULL к существующей таблице. Как видите, это делается с помощью инструкции ALTER TABLE и команды ALTER COLUMN. Изначально столбец Column2 у нас мог принимать значение NULL, после выполнения этой инструкции не может. Однако стоит помнить о том, что, если в столбце уже будут значения NULL, инструкция не выполнится.
В третьей инструкции мы добавили к столбцу Column1 ограничение DEFAULT, для этого мы также использовали инструкцию ALTER COLUMN, а для добавления ограничения команду ADD CONSTRAINT, после которой мы написали имя ограничения (DF_C1), тип и с помощью ключевого слова FOR указали столбец, для которого мы хотим создать ограничение.
Пример создания ограничения PRIMARY KEY в Microsoft SQL Server
Ограничения первичного ключа PRIMARY KEY можно создать как во время создания таблицы (причем двумя разными способами), так и после с помощью отдельной инструкции.
Сначала давайте посмотрим, как создается первичный ключ во время создания таблицы.
Первый способ подразумевает определение PRIMARY KEY на уровне столбца, т.е. мы после всех характеристик написали ключевое слово CONSTRAINT, затем название ограничения и тип этого ограничения.
Второй способ заключается в определении ограничения на уровне таблицы, иными словами, после всех столбцов мы пишем ключевое слово CONSTRAINT, имя ограничения, тип и, в данном случае, мы еще указываем какой именно столбец будет у нас выполнять роль первичного ключа (в нашем случае Column1).
Для того чтобы добавить первичный ключ к уже существующей таблице нужно использовать инструкцию ALTER TABLE и команду ADD CONSTRAINT.
В данном случае мы добавили в таблицу TestTable ограничение первичного ключа с названием PK_TestTable, Column1- это столбец, который и будет первичным ключом.
Пример создания ограничения FOREIGN KEY в SQL Server
Ограничения FOREIGN KEY мы также можем определить, как во время создания самой таблицы, так и отдельной инструкцией применительно к уже существующей таблице.
Для примера давайте создадим две таблицы, первая будет содержать данные о категориях товара, а вторая перечень товаров со ссылкой на категорию, т.е. товар должен относиться к какой-нибудь категории.
В данном примере сначала мы создали таблицу, на которую будем ссылаться, т.е. таблицу с категориями, затем мы создали таблицу с товарами и при ее создании определили внешний ключ, т.е. создали ограничение FOREIGN KEY. Для этого мы так же, как и при создании первичного ключа, указали ключевое слово CONSTRAINT, имя ограничения, тип, столбец, который будет ссылаться на ключ в другой таблице. Далее мы написали ключевое слово REFERENCES, указали таблицу, которая содержит ключ, и в скобочках указали название столбца, который и будет ключом, в большинстве случаев данный столбец является первичном ключом, но необязательно.
В примере я также показал, что мы можем назначить некое действие в тех случаях, когда с ключом будет выполнена операция удаления или обновления. Например, категорию товара решили удалить, но это сделать не получится, если на эту запись ссылается записи из таблицы с товарами (к этой категории привязаны товары), иными словами, по умолчанию будет ошибка. Для того чтобы изменить действие по умолчанию мы можем указать в инструкции определения ограничения команды ON DELETE и ON UPDATE, т.е. соответственно действия, которые будут выполнены в случае удаления ключа, и действия, которые будут выполнены, если этот ключ будет обновлен. Возможно указать следующие значения:
Для того чтобы посмотреть, как создается ограничение FOREIGN KEY отдельной инструкцией, давайте удалим таблицу с товарами, затем создадим ее без внешнего ключа, а потом добавим ограничение FOREIGN KEY.
К существующей таблице ограничение FOREIGN KEY добавляется так же, как и другие ограничения, инструкцией ALTER TABLE и командой ADD CONSTRAINT. В этом примере, как видите, я не указал инструкции ON DELETE и ON UPDATE, т.е. действие при удалении или обновлении будет по умолчанию.
Пример создания проверочного ограничения CHECK в MS SQL Server
Ограничения CHECK можно также создать двумя способами, в момент создания самой таблицы и отдельной инструкцией ALTER TABLE.
В первом случае мы создали таблицу и сразу определили в нем проверочное ограничение CK_TestTable6_C1, которое подразумевает, что столбец Column1 не может содержать значение 0. Иными словами, если вдруг Вы или кто-то другой захочет вставить строку со значение Column1 = 0, SQL сервер не разрешит Вам это сделать, он выдаст ошибку.
Во втором случае, мы добавили проверочное ограничение и задействовали при этом два столбца, т.е. мы говорим, что в строках значение столбца Column2 всегда должно быть больше значения, которое в столбце Column1.
Пример создания ограничения UNIQUE
Ограничение уникальности UNIQUE мы можем создать нескольким способами. При создании таблицы на уровне столбца, при создании таблицы на уровне таблицы, и отдельной инструкцией ALTER TABLE ADD CONSTRAINT.
Давайте посмотрим, как это делается.
В итоге мы создали таблицу, в которой три столбца и ко всем этим столбцам мы применили ограничение уникальности UNIQUE разными способами.
Для первого столбца, на уровне самого столбца, для второго отдельной инструкцией, а для третьего на уровне таблицы. Вы можете использовать любой из этих способов, какой Вам удобней. Синтаксис добавления ограничений я думаю понятен.
Надеюсь, материал был Вам полезен, а у меня на этом все, пока!
Заметка про NULL
Основные положения
Для удобства сделаем процедуру, печатающую состояние булевого параметра:
и включим опцию печати сообщений на консоль:
Привычные операторы сравнения пасуют перед NULLом:
Сравнение с NULLом
Соответственно, IS NOT NULL действует наоборот: вернёт истину, если значение операнда отлично от NULLа и ложь, если он является NULLом:
DECODE идёт против системы:
Пример с составными индексами находится в параграфе про индексы.
Логические операции и NULL
В большинстве случаев неизвестный результат обрабатывается как ЛОЖЬ :
Отрицание неизвестности даёт неизвестность:
Операторы IN и NOT IN
Для начала сделаем несколько предварительных действий. Для тестов создадим таблицу T с одним числовым столбцом A и четырьмя строками: 1, 2, 3 и NULL
Включим трассировку запроса (для этого надо обладать ролью PLUSTRACE ).
В листингах от трассировки оставлена только часть filter, чтобы показать, во что разворачиваются указанные в запросе условия.
Предварительные действия закончены, давайте теперь поработаем с операторами. Попробуем выбрать все записи, которые входят в набор (1, 2, NULL) :
Попробуем теперь с NOT IN :
Вообще ни одной записи! Давайте разберёмся, почему тройка не попала в результаты запроса. Посчитаем вручную фильтр, который применила СУБД, для случая A=3 :
Из-за особенностей трёхзначной логики NOT IN вообще не дружит с NULLами: как только NULL попал в условия отбора, данных не ждите.
NULL и пустая строка
Здесь Oracle отходит от стандарта ANSI SQL и провозглашает эквивалентность NULLа и пустой строки. Это, пожалуй, одна из наиболее спорных фич, которая время от времени рождает многостраничные обсуждения с переходом на личности, поливанием друг друга фекалиями и прочими непременными атрибутами жёстких споров. Судя по документации, Oracle и сам бы не прочь изменить эту ситуацию (там сказано, что хоть сейчас пустая строка и обрабатывается как NULL, в будущих релизах это может измениться), но на сегодняшний день под эту СУБД написано такое колоссальное количество кода, что взять и поменять поведение системы вряд ли реально. Тем более, говорить об этом они начали как минимум с седьмой версии СУБД (1992-1996 годы), а сейчас уже двенадцатая на подходе.
NULL и пустая строка эквивалентны:
непременный атрибут жёсткого спора:
Длина пустой строки не определена:
Сравнение с пустой строкой невозможно:
Критики подхода, предлагаемого Ораклом, говорят о том, что пустая строка не обязательно обозначает неизвестность. Например, менеджер по продажам заполняет карточку клиента. Он может указать его контактный телефон (555-123456), может указать, что он неизвестен (NULL), а может и указать, что контактный телефон отсутствует (пустая строка). С оракловым способом хранения пустых строк реализовать последний вариант будет проблемно. С точки зрения семантики довод правильный, но у меня на него всегда возникает вопрос, полного ответа на который я так и не получил: как менеджер введёт в поле «телефон» пустую строку и как он в дальнейшем отличит его от NULLа? Варианты, конечно, есть, но всё-таки…
Вообще-то, если говорить про PL/SQL, то где-то глубоко внутри его движка пустая строка и NULL различаются. Один из способов увидеть это связан с тем, что ассоциативные коллекции позволяют сохранить элемент с индексом » (пустая строка), но не позволяют сохранить элемент с индексом NULL:
Использовать такие финты ушами на практике не стоит. Во избежание проблем лучше усвоить правило из доки: пустая строка и NULL в оракле неразличимы.
Математика NULLа
Этот маленький абзац писался пятничным вечером под пиво, на фоне пятничного РЕН-ТВшного фильма. Переписывать его лень, уж извините.
Очевидно, что мы ничем не сможем помочь Коле: неизвестное количество любовников Маши до замужества сводит все расчёты к одному значению — неизвестно. Oracle, хоть и назвался оракулом, в этом вопросе уходит не дальше, чем участники битвы экстрасенсов: он даёт очевидные ответы только на очевидные вопросы. Хотя, надо признать, что Oracle гораздо честнее: в случае с Колей он не будет заниматься психоанализом и сразу скажет: «я не знаю»:
С конкатенацией дела обстоят по другому: вы можете добавить NULL к строке и это её не изменит. Такая вот политика двойных стандартов.
NULL и агрегатные функции
Таблица с данными. Используется ниже много раз:
Пустые значения игнорируются агрегатами:
Набор данных только из NULLов:
Пустой набор данных:
NULL в OLAP
Удобная фишка sqlplus: при выводе данных заменяет NULL на указанную строку:
Проверяем дуализм NULLа в многомерном кубе:
NULL поля в MySQL
Вступление
Часто на форумах и даже в учебниках пишут о том, что лучше не использовать NULL поля в MySQL. В этих утверждениях смущает тот факт, что никто не удосуживается объяснить, почему NULL – это зло. Эта заметка призвана разобраться, что такое NULL в MySQL и так ли страшен чёрт, как его малюют.
Что такое NULL?
Наряду с множеством типов данных в БД, NULL стоит особняком. NULL означает отсутствие значения.
Зачем использовать особый тип данных для того, чтоб указать отсутствие значения, когда можно просто вставить пустую строку, например? Этот вопрос мне всегда казался глупым, и я удивляюсь тому, как в книгах и статьях уделяют ему достаточное количество внимания.
Чем опасен NULL?
Сравнение NULL с любым другим значением, даже с родственным (в большинстве языков программирования, в частности, в PHP null, 0, false это одно и то же, если не применять строгого сравнения, которое включает сравнение типов) ему FALSE вернёт NULL. Отсюда следует первая ловушка.
Допустим, у нас есть таблица:
Добавим в неё 2 записи:
INSERT INTO users (name, family) VALUES(‘Андрей’, ‘Романов’), (‘Иван’, NULL);
В случае, если вы захотите объединить имя и фамилию, получив ФИО одним полем, например, таким запросом:
SELECT CONCAT(name, ‘ ‘, family) FROM `users`
MySQL не оправдает ваших ожиданий. Вы получите NULL вместо Ивана.
Немного неожиданно, правда?
На деле же ничего неожиданного нет, если вы помните, что любая операция с NULL вернёт NULL, кроме специальных операций, предназначенных для работы с NULL: IS NULL, IS NOT NULL, IFNULL()
Сортировка по NULL
Всего лишь хочу опровергнуть некоторые фразы из русского мануала MySQL о том, что при сортировке по столбцу, содержащим NULL значения, эти самые NULL значиния всега оказываются наверху. Это не так.
SELECT name, family FROM `users` ORDER BY family ASC
SELECT name, family FROM `users` ORDER BY family DESC
Как видим, NULL считается наименьшим значением, и порядок сортировки на него действует.
Группировки и NULL
Все просто.
MySQL группирует по NULL так же как и по любому другому полю.
Добавим нашей таблице users столбец score INT UNSIGNED NULL;
Подсчитаем сколько всего пользователей набрали то или иное количество очков, т.е. сгруппируем выборку по полю score
SELECT COUNT(*), score FROM `users` GROUP BY score
Как видно, MySQL сгруппировала 2 строки с score = NULL
Индексы и NULL
Откуда-то ходит заблуждение о том, что MySQL не использует индексы, если столбец может принимать значения NULL.
Это не так!
Проведём несколько экспериментов.
Выберем все записи, где score = NULL. Не забываем, что мы для этого должны использовать конструкцию IS NULL
EXPLAIN SELECT * FROM `users` WHERE score IS NULL
Индекс используется.
Выберем все записи, где количество очков больше, например, пяти.
EXPLAIN SELECT * FROM `users` WHERE `score` > 5
Индекс используется.
Найдем пользователя, у которого ровно 7 очков
EXPLAIN SELECT * FROM `users` WHERE `score` = 7
Индекс используется.
Можно сделать вывод: заблуждение действительно таковым и оказалось.
Можно смело использовать NULL-поля при создании индекса и индекс будет работать.
Когда следует использовать NULL?
Ранее я привел пример таблицы сайтов, которая содержит поле PR.
PR – это целочисленное значение, которое может принимать значение 0, к тому же оно может быть в состоянии «не посчитано». Как реализовать хранение такого свойства в таблице?
Зачем отказываться от того, что язык предлагает тебе «из коробки»?
Значение NULL для такого поля подходит идеально. NULL – означает «нет значения», т.е. оно ещё не посчитано. Если значение равно нулю, значит оно действительно равно нулю. Все просто.
Второй пример подходящего случая для использования NULL – это поле-потомок.
Поле-потомок указывает на id записи из другой (или же этой же таблицы). Примером такого поля может быть parent_id.
Выводы
Нет причин бояться создания NULL полей. Надо хорошо понимать, что NULL в MySQL это не ноль и не false – это отсутствие значения. Надо знать, как MySQL работает с NULL: нюансы есть, но их не много. У MySQL нет проблем с индексацией NULL полей.
Разница между NULL DEFAULT NULL и DEFAULT NULL в MySQL?
Недавно я столкнулся с новой проблемой в MySQL. Я собирался создать новую таблицу с
col1 TIMESTAMP DEFAULT NULL
(т. е. столбец, имеющий значение по умолчанию NULL ), но при создании это дало мне ошибку:
Недопустимое значение по умолчанию для столбца
Я хочу знать, в чем разница между этими двумя синтаксисами. Я также столкнулся с этой проблемой раньше в некоторых значениях insert NULL в столбце.
Может ли кто-нибудь объяснить причину этой проблемы, например, это проблема конкретной версии или что-то еще с MySQL?
1 ответ
null=True blank=True default = 0 Какая разница? Когда вы используете что?
Если у вас есть только значение по умолчанию, но столбец отклоняет значения null, то это значение по умолчанию не может быть использовано.
Похожие вопросы:
Следующее определение таблицы SQL иллюстрируется одним из операторов create table из моей базы данных MYSQL, разработанной бывшим разработчиком моей компании. DROP TABLE IF EXISTS.
В чем разница между дефолтом NULL и CHECKBOX NULL mysql? Я могу установить значение по умолчанию как NULL или есть checkbox ниже которого я могу проверить, чтобы сказать NULL? Какая разница?
В чем разница между: t.boolean :test, :default => true и t.boolean :test, :null => true и t.boolean :test, :default => true, :null => true EDIT Имеет ли смысл следующее? t.boolean :test.
null=True blank=True default = 0 Какая разница? Когда вы используете что?
Есть ли разница между значениями столбца по умолчанию в PostgreSQL? Важно ли это? state character varying(255) DEFAULT NULL и state character varying(255) DEFAULT NULL::character varying
MySQL отклонить вставить значение NULL в столбец default null : (столбец: tid) Структура таблицы: CREATE TABLE `ww_uid_tid_qid_aid` ( `id` int(11) NOT NULL, `qzid` int(11) NOT NULL, `uid` int(32).
Есть ли какая-то разница в использовании default(int?) или (int?)null для назначения переменной? Это одно и то же? Или есть какие-то плюсы и минусы использования каждого способа?
Есть ли разница между этими двумя запросами? Если есть, то что будет быстрее? ALTER TABLE mytable ADD COLUMN newcolumn VARCHAR(64) DEFAULT NULL; ALTER TABLE mytable ADD COLUMN newcolumn VARCHAR(64).