Gen*_*нин 19 database database-design terminology relational-database
继我的问题"为什么在TSQL中使用'not null primary key'?" ...
正如我从其他讨论中所理解的,一些RDBMS(例如SQLite, MySQL的)允许主键中的"唯一"NULL.
为什么允许这样做以及它有何用处?
背景:我认为与同事和数据库专业人员进行沟通有助于了解不同DBMS中基本概念,方法及其实现的差异.
为了确定主键值的唯一性,NULL值被认为与所有其他值不同,包括其他NULL.
如果INSERT或UPDATE语句尝试修改表内容,以便两个或多个行具有相同的主键值,则会违反约束.根据SQL标准,PRIMARY KEY应始终表示NOT NULL.不幸的是,由于长期的编码监督,在SQLite中并非如此.
除非列是INTEGER PRIMARY KEY,否则SQLite允许在PRIMARY KEY列中使用NULL值.我们可以改变SQLite以符合标准(我们将来可能会这样做),但是当发现疏忽时,SQLite的使用范围很广,如果我们解决问题,我们担心会破坏遗留代码.
所以现在我们已经选择在PRIMARY KEY列中继续允许NULL.但是,开发人员应该意识到,我们可能会在未来更改SQLite以符合SQL标准,并应相应地设计新程序.
Erw*_*out 26
假设您有一个包含可空列Kn的主键.
如果你想让第二行被拒绝,那么在第二行中Kn是null并且表已经包含一个Kn null的行,那么你实际上是要求系统将对待比较"row1.Kn = row2 .Kn"赋予TRUE(因为你不知何故希望系统检测到那些行中的键值确实相等).但是,这种比较归结为比较"null = null",并且标准已经明确指定null不比较等于任何东西,包括它自己.
为了满足你的需要,因此SQL会偏离自己关于null处理的原则.SQL中存在无数的不一致,但这个特殊的一个从未超越委员会.
就关系数据库理论而言:
根据要建模的数据,可以使用“弥补”值代替NULL。我使用了0,“ N / A”,“ 1980年1月1日”和类似的值来表示虚拟“已知丢失”数据。
大多数(如果不是全部)数据库引擎都允许UNIQUE约束或索引,但确实允许NULL列值,尽管(理想情况下)只可以为一行分配空值(否则它将不是唯一值)。这可以用来支持那些不适用于关系理论的恼人的,务实的(但有时是必要的)情况。
我不知道MySQL的旧版本是否与此不同,但是从现代版本开始,主键必须在非空的列上.请参阅手册页CREATE TABLE:"A PRIMARY KEY是一个唯一索引,其中必须将所有键列定义为NOT NULL.如果未明确NOT NULL声明它们,MySQL会如此隐式地(并且默默地)声明它们."