为什么在TSQL中使用"not null primary key"?

Gen*_*нин 17 t-sql sql-server database-design primary-key

我在博客,文章,书籍,论坛,SO中等在TSQL中创建表的脚本中经常看到"not null primary key".

例如,如果要搜索"非空"NEAR"主键""sql server",BING会给出630,000个结果((仅用英语):http://www.bing.com/search? q =%22not + null%
22 + NEAR +%22primary +密钥%22 +%22sql +服务器%22&去=&形式= QBRE&FILT = LF

我总是认为"NOT NULL"是PRIMARY KEY定义不可分割的一部分,至少在SQL Server中是这样.
我尝试在SQL Server中使用和不使用"NOT NULL"的主键创建表,但无法掌握可能的差异.

为什么即使在快速(简短)插图中,所有人都使用"NOT NULL"来创建主键?


更新:
NULL如何识别任何内容或是唯一的(以及如果允许多个NULL,则阻止多个NULL)?它是未指定的,缺失的,不适用的值

我的问题也暗示了子问题:
如果为PK定义"NOT NULL",为什么不指定UNIQUE?
PK的定义是什么?它是UNIQUE CONSTRAINT + NOT NULL还是UNIQUE INDEX(那么为什么NOT NULL)?
Plz给我链接到msdn docs.

Update2: @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]
) 
Run Code Online (Sandbox Code Playgroud)

仍然不允许NULL给出:


  • Microsoft SQL Server Management Studio


    没有更新行.

    第2行中的数据未提交.错误来源:.Net SqlClient数据提供程序.错误消息:无法将值NULL插入列'PK',表'TestData.dbo.T3'; 列不允许空值.INSERT失败.

    该语句已终止.

    更正错误并重试,或按ESC取消更改.


    好的帮助


Update3:
这个概念和术语定义可能看起来是不切实际的麻烦.
事实并非如此(在沟通/讨论期间其他人认为)基本概念上的一些错误陈述足以被视为白痴并在专业互动和沟通中制造障碍.

我忘了告诉,NOT NULL是由SSMS为PK编写的!

Pau*_*eld 16

编辑清晰

根据SQL规范,主键不能包含NULL.这意味着用"NOT NULL PRIMARY KEY"或"PRIMARY KEY"装饰一个列应该做同样的事情.但是,您正依赖SQL标准正确地依赖SQL引擎.作为一个例子,由于早期的错误,SQL Lite没有正确实现标准,并允许非整数主键中的空值(请参阅sqlite.org/lang_createtable.html).这意味着(至少)SQLLite这两个语句做两件事.

由于"NOT NULL PRIMARY KEY"清楚地表明意图并且即使主键被删除也继续提供非空值,这应该是首选语法.


Dam*_*ver 8

下列:

CREATE TABLE T1 (
    T1ID int not null primary key
)
Run Code Online (Sandbox Code Playgroud)

是以下的简写:

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

列定义实际上与约束定义完全分开.只是速记隐藏了这两个独立定义的事实.(当然,如果使用长手形式,则可以执行跨多个列定义主键的操作).

编辑,以响应更新.不,您仍然无法在主键中拥有可为空的列.但是考虑到在create table语句中指定每列的可为空性是正常的,省略它就感觉很奇怪(即使它是PRIMARY KEY约束暗示/要求的).

CREATE TABLE T1 (
    T1ID int,
    constraint <system generated name> PRIMARY KEY (T1ID) on [PRIMARY]
)
Run Code Online (Sandbox Code Playgroud)

创建与上一代码示例完全相同的表.因此,明确指定列的"非空"能力是对结果的明确确认,而不是要求.

最后,你会发现它经常出现在示例代码中,因为人们已经开发了他们的数据库,然后使用内置的SQL工具从他们的数据库生成脚本 - 脚本工具总是明确地放置所有内容.