Подтвердить что ты не робот

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

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

Например, BING дает 630 000 результатов ((только на английском языке), если для поиска по "не null" NEAR "первичный ключ" "sql-сервер":
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" для создания первичного ключа даже в быстрых (коротких) иллюстрациях?


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

Мой вопрос также подразумевал подзапросы:
если для PK определить "NOT NULL" , почему тогда UNIQUE не указан?
И каково определение ПК. Это УНИКАЛЬНЫЙ КОНСТРАКЦИЯ + НЕ НУЛЬНЫЙ или УНИКАЛЬНЫЙ ИНДЕКС (тогда почему НЕ НУЛЛ)?
Plz дайте мне ссылку на msdn docs на нем.

Обновление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 Data Provider.  Сообщение об ошибке: Невозможно вставить значение NULL в столбец "PK", таблицу "TestData.dbo.T3"; столбец не допускает нулей. INSERT не работает.

    Оператор завершен.

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


    Справка OK


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

Я забыл сказать, что NULL написано SSMS для ПК!

4b9b3361

Ответ 1

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

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

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

Ответ 2

Следующее:

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.

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

создает точно такую ​​же таблицу, что и предыдущий образец кода. Явное указание "не null" -устойчивости столбца является более явным признанием результата, а не требованием.

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

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

Самое забавное в 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, вставка в поле PRIMARY KEY с NULL завершится с ошибкой, потому что PRIMARY KEY не может быть нулевой, это ошибка. Таким образом, NOT NULL на PRIMARY KEY NOT NULL неявно подразумевается в MySQL.

Ответ 6

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

Ответ 7

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

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

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

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

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

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

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