Зачем использовать "ненулевой первичный ключ" в TSQL? - PullRequest
17 голосов

Я часто вижу "ненулевой первичный ключ" в сценариях создания таблиц на TSQL в блогах, статьях, книгах, форумах, здесь, в SO и т. Д.

Например, BING выдает 630 000 результатов ((только на английском языке), если выполнить поиск по первичному ключу "not null" NEAR "" sql server ":
http://www.bing.com/search?q=%22not+null%22+NEAR+%22primary+key%22+%22sql+server%22&go=&form=QBRE&filt=lf

Я всегда воспринимал "NOT NULL" как неотъемлемую часть определения PRIMARY KEY, по крайней мере, в SQL Server.
Я пытался создать таблицы с основными ключами с и без «NOT NULL» в SQL Server, но не смог понять возможную разницу.

Почему все используют «NOT NULL» для создания первичного ключа даже в быстрых (коротких) иллюстрациях?


Обновление:
Как NULL может идентифицировать что-либо или быть уникальным (а также предотвращать множественные NULL, если один разрешен)? Не указано, отсутствует, не применимо значение

Мой вопрос также подразумевал подвопросы:
если для PK определено «NOT NULL», почему тогда UNIQUE не указывается?
И каково определение ПК. Это УНИКАЛЬНОЕ ОГРАНИЧЕНИЕ + НЕ NULL или УНИКАЛЬНЫЙ ИНДЕКС (тогда почему НЕ NULL)?
Пожалуйста, дайте мне ссылку на документацию MSDN.

Обновление2: @ Damien_The_Unbeliever

Почему не синоним без "NOT NULL"?

CREATE TABLE T3 
(
    PK int -- NOT NULL commented out
    , nonPK int -- to double-check my sanity 
    , constraint PK_vgv8 PRIMARY KEY (PK) on [PRIMARY]
) 

все еще не разрешает давать NULL:


  • Microsoft SQL Server Management Studio


    Строка не обновлена.

    Данные в строке 2 не были зафиксированы. Источник ошибки: поставщик данных .Net SqlClient. Сообщение об ошибке: невозможно вставить значение NULL в столбец «PK», таблица «TestData.dbo.T3»; столбец не допускает пустых значений. Вставить не удается.

    Заявление прекращено.

    Исправьте ошибки и повторите попытку или нажмите ESC, чтобы отменить изменения.


    OK Справка


Update3:
Это определение понятий и терминов может показаться непрактичным неудобством.
Это не так, какое-то неправильное утверждение (по мнению других лиц) во время общения / обсуждения) относительно базового понятия достаточно, чтобы считаться идиотом и создавать барьеры в профессиональном взаимодействии и общении.

Я забыл сказать, что сценарий NOT NULL создается SSMS для PK!

Ответы [ 7 ]

16 голосов
/ 11 октября 2010

Отредактировано для ясности

Согласно спецификации SQL, первичный ключ не может содержать NULL. Это означает, что оформление столбца с помощью «NOT NULL PRIMARY KEY» или просто «PRIMARY KEY» должно делать то же самое. Но вы полагаетесь на соответствующий движок SQL, соответствующий стандарту SQL. Например, из-за ранней ошибки SQL Lite неправильно реализует стандарт и допускает нулевые значения в нецелых первичных ключах (см. sqlite.org / lang_createtable.html ). Это означает, что для (по крайней мере) SQLLite два оператора делают две разные вещи.

Поскольку «NOT NULL PRIMARY KEY» четко указывает намерение и продолжает указывать ненулевые значения, даже если первичный ключ удален, это должно быть предпочтительным синтаксисом.

8 голосов
/ 11 октября 2010

Следующее:

CREATE TABLE T1 (
    T1ID int not null primary key
)

действительно является сокращением для следующего:

CREATE TABLE T1 (
    T1ID int not null,
    constraint <system generated name> PRIMARY KEY (T1ID) on [PRIMARY]
)

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

Изменить в ответ на обновление.Нет, в первичном ключе все еще не может быть пустого столбца.Но, учитывая, что нормально указывать обнуляемость каждого столбца в операторе create table, просто странно опускать его (даже если это подразумевается / требуется ограничением PRIMARY KEY).та же таблица, что и в предыдущем примере кода.Явное указание «не нулевой» возможности столбца является, следовательно, скорее явным подтверждением результата, чем требованием.

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

2 голосов
/ 12 октября 2010

Я не знаю ни одной СУБД, которая разрешает использование обнуляемого столбца в ограничении PRIMARY KEY.Стандарт SQL устанавливает, что столбцы в ограничении PRIMARY KEY не могут иметь значение NULL.

В реляционной модели ключи-кандидаты состоят из уникальных значений, а не из нулей.Особенностью SQL является то, что необязательные столбцы могут использоваться в ограничениях UNIQUE.Эта функция, вероятно, является причиной многих проблем с качеством данных.Я настоятельно рекомендую вам избегать использования обнуляемых столбцов в ограничениях UNIQUE.При необходимости создайте новую таблицу для значений, не допускающих значения NULL, и установите для нее ограничение UNIQUE.

1 голос
/ 12 апреля 2013

Самое смешное в MYSQL - это поведение, которое хорошо подходит для передачи значения NULL (или 0) в поле primary key auto_increment.

Скажем, у вас есть

create table Users(

  userId int primary key auto_increment

) ;

insert into users( userId ) values ( null ) ; -- insert OK
select * from Users ;  -- Shows 1

Поэтому, если вы передаете 0 или NULL в поле auto_increment, оно просто выбирает следующее доступное значение.

Если вы снимаете с свойства auto_increment, вставка в ПЕРВИЧНЫЙ КЛЮЧполе с NULL завершается неудачно, потому что PRIMARY KEY не может быть нулевым, является ошибкой.Таким образом, NOT NULL на PRIMARY KEY NOT NULL подразумевается в MySQL по крайней мере.

1 голос
/ 11 октября 2010

Синтаксически не требуется, так как в любом случае это будет значение по умолчанию, если оно не указано для столбцов первичного ключа, независимо от значения по умолчанию для других столбцов.

SET ANSI_NULL_DFLT_ON ON /*Set default for columns to allow NULL if not specified*/

CREATE TABLE #t
(
i INT PRIMARY KEY,
j INT
)

SELECT name,is_nullable
FROM tempdb.sys.columns 
WHERE object_id=object_id('tempdb..#t')


INSERT INTO #t VALUES (1,NULL) /*Succeeds as j allows NULL*/

INSERT INTO #t VALUES (NULL, 1)/*Won't succeed as column doesn't allow nulls*/

DROP TABLE #t
0 голосов
/ 23 августа 2015

Мне кажется, что я иду в другом направлении, чтобы объяснить, почему ноль и первичный ключ также принимаются в поле, когда сам первичный ключ неявно содержит не ноль.

Допустим, у нас есть таблица table1, что означает, что она будет хранить свое значение для хранения двухмерных данных. Если я создаю таблицу только с одним полем, это приемлемо, но каково ее использование в реальном времени в реальном объектном мире? Я думаю, это будет одномерная таблица, в которой будут храниться данные только одного поля. И сохранять это поле для принятия значений Null бессмысленно.

Теперь давайте предположим, что мы определили таблицу с 2 полями, что означает, что мы можем извлечь хорошую информацию из каждой строки при заполнении соответствующими данными.

Принятие этими двумя полями значения Null не имеет смысла ожидать, если мы хотим вытолкнуть мусор или ожидаемое количество (*) должно привести к появлению дополнительной строки.

Итак, мое мнение таково, что указание «не ноль» является обязательным по крайней мере для двух полей, если мы хотим использовать нормализованные таблицы с хорошими фундаментальными концепциями СУБД. Прежде чем подумать, нужен ли таблице первичный ключ в качестве ограничения, мы всегда определяем поле, не равное нулю. Кроме того, при необходимости используйте первичный ключ и обратите внимание, что вы можете удалить его в любое время, но не «not null»

И если мы уверены, что не будем отбрасывать первичный ключ, используйте только первичный ключ, в противном случае не нулевой, а первичный ключ.

Все зависит от использования, и, как я уже сказал, базовые определения таблиц и правила Кодда должны быть достигнуты для достижения хорошей базы данных.

0 голосов
/ 11 октября 2010

Все первичные ключи означают, что это идентификатор таблицы и, следовательно, уникальный по определению. Уникальный не означает не ноль, поэтому, если у вас есть требование, чтобы первичный ключ не мог быть нулевым, вы должны указать это явно. Если вы разрешите null, вы просто скажете, что в столбце можно иметь нулевое значение, но вы можете иметь только одно, поскольку оно должно быть уникальным.

...