如何自我应该和不NULL columns?
-
19-08-2019 - |
题
我设计一个数据库模式,并且我想知道什么标准我应该用于决定是否每个柱应该是 nullable
或者不是。
我应该记为NOT NULL只有那些列绝对 必须 填写一行为有任何意义,在所有应用程序?
或者我应该记所有列,我打算从来没有空?
什么是业绩的影响的小vs大量的不NULL columns?
我猜很多不NULL列会慢下来,插入一个点,但它实际上可能加快选择,因为查询执行计划生有更多的信息,列..
有人可以有更多的知识比我给我低下吗?
解决方案
老实说,我一直认为NOT NULL应该是默认的。 NULL是奇特殊情况,你应该做的情况下,它只要你使用它。再加上它更容易从NOT NULL更改列可空比它走另外一条路。
其他提示
有没有显著的性能影响。甚至不要去想考虑这是一个问题。这样做是一个巨大的早期优化反模式。
“我应该只标记为NOT NULL只有绝对必须将行任何意义可言我的应用程序填写这些列?”
是。就这么简单。你好多了与一空列没有任何NULL值,比需要空值和有捏造事实。不管怎样,任何不确定的情况下更好地在业务规则过滤掉。
编辑:
有可能为空的领域,我认为最终是最引人注目的,这是用例论点的另一个理由。我们都经过了需要对一些字段的值数据输入表格;而我们都放弃了,我们不得不为必填字段没有合理的价值形式。最后,如果它们反映了用户需求的应用程序,表格,数据库设计是唯一可以辩护的;而很显然,有,用户可没有价值很多很多的数据库列 - 有时在经营过程中给点意见,有时过
在NOT NULL的侧ERR。你会的,在某些时候,必须决定什么NULL“的意思是”在你的应用程序 - 更可能,这将是不同的列不同的事情。一些常见的情况是“未指定”,“未知”,“不适用”,“还没有发生”,等你会知道什么时候你需要这些值中的一个,然后你就可以适当地允许为空的列和围绕它的代码的逻辑。
允许随机的事情是NULL是,早晚,总是一个恶梦IME。仔细和谨慎使用空 - 和知道这意味着什么在你的逻辑
编辑:似乎是我主张的 NO 的空列的想法,永远。这是荒谬的。空的是的有用的,但只有当它的预期。
勒Dorfier的DateOfDeath例子是一个很好的例子。一个NULL DateOfDeath将指示“没有发生”。现在,我可以写一个视图LivingPersons WHERE DateOfDeath IS NULL
。
但是,什么是一个NULL订购日期是什么意思?该订单没有下达了吗?即使有在订单表中的记录?怎么样一个空地址?这些都是应该通过你的头,你让之前NULL是价值的思考。
返回DateOfDeath - 人WHERE DateOfDeath > '1/1/1999'
的查询将不会返回NULL记录 - 尽管我们逻辑上知道他们的必须在1999年以后死的。那是你要的吗?如果没有,那么你最好包括在该查询OR DateOfDeath IS NULL
。如果允许的所有列的是NULL,你要想想的你写一个查询每一次的。 IME,这是太多了10%左右,实际上有当他们NULL合法的意义列的精神税。
我发现标志着列作为NOT NULL通常是一个好主意,除非你有在列NULL一个有用的意义。否则,你可能会意外地在那里找到空后,当你意识到你不想要它,改变是很难。
我尽量避免使用空的在该数据库尽可能多的。这意味着角色的领域总是不null。同样的,为数领域,尤其是任何东西表示的金钱或类似(股票的单位,等)。
我有2个例外:
- 冰箱里的日期可能不知道(例如。DivorcedOn)
- 可选的外部关键的关系(MarriedToPersonId).虽然上次我使用的"空白"行在外国的关键表,并提出了relatonship强制性(例如。JobDescriptionCode)
我们还有时使用明确的位域对于"未知的"/"不设定"(eg.JobDescriptionCode和IsEmployeed).
我有几个核心原因:
- 空值总是会造成问题在数字领域。总是如此。总是如此。总是如此。不论如何小心你是在somepoint选择X+Y因为总是会发生的,它会回NULL。
- 零容易造成的问题串的领域,通常的地址领域(例如。选择AddrLine1+AddrLine2从地址)。
- 防止空中业务逻辑层是一个繁琐的废物的努力...只是不要让他们在数据库和可以节省100行代码。
我的首选默认:
- 串->"",又名空字符串
- 号码->0
- 有空->今天或NULL(见的例外#1)
- 位>假
你可以找到克里斯的日期 数据库在深度 一个有用的资源用于这些种类的问题。你可以得到的味道他的想法在这 采访, ,他说,除其他事项外:
所以,是的,我认为SQL是非常糟糕。但你明确要求其主要什么 缺陷。好了,这里有几个:
- 重复行
- Null
- 从左到右栏的排序
- 未命名列和重复的列名
- 故障来支持"="正常
- 指针
- 高冗余度
在我自己的经验,几乎所有"计划null"表示可以更好地与儿童表,有一个外国的关键基表。参加儿童表是任选的,并在那里的空/not null区分实际上是作出。
这地图及解释的关系作为第一阶逻辑的提议。这也是常识。当一个人不知道鲍勃的地址,没有一个写在一个人的关系网:
Bob. ____
或者不仅仅是一个避免填写的地址卡鲍勃,直到一个具有实际地址给他吗?
编辑:日期的说法出现在第53-55页的数据库中的深度,根据部分的标题"为什么空是被禁止的."
我朝NOT NULL瘦,除非我明白了一个道理,否则 - 就像别人说的,不管你喜欢与否,NULL是怪异的特殊情况
我的一个在问候NULL收藏是:
SELECT F1 FROM T WHERE F2 <> 'OK'
...其中(在DB2至少)将不包括任何行,其中f2是空 - 因为在关系术语,(NULL <> 'OK')IS NULL。但是,你的目的是为了返回所有不-OK行。你需要一个额外的或谓词,或写F2不同于“OK”,而不是(这是特殊情况下,摆在首位的编码)。
IMO,NULL只是那些程序员的工具之一,像指针运算或运算符重载,需要尽可能多的现有技术随着科学
乔·塞科写关于这在SQL对于聪明豆 - 在应用中使用NULL的陷阱是其含义是,很好,未定义。这可能意味着未知的,未初始化的,不完整的,不适用 - ?或者如上述哑例如,它意味着行或不确定
感谢所有伟大的回答,伙计们。你给了我很多值得思考,并且帮助我形成自己的意见/战略,该战略归结为:
允许零如果--并仅-如果一个在空 列将有一个具体 意思您的应用程序。
几个共同的含义,对于空:
- 任何东西,直接来自用户
- 这里空手段"用户没有进入"
- 对于这些列,它最好允许空值,或者你只是得到 asdasd@asd.com 类型的输入。
- 外键为"0或1"关系
- 空装置"没有相关的行"
- 所以允许使用空值用于这些列
- 这个人是 有争议的, 但这是我的意见。
在一般情况下,如果你不能认为一个有用的意义null在一个柱,它应该是 NOT NULL
.你总是可以改变它nullable后。
例之类的事情我结束了:
create table SalesOrderLine (
Id int identity primary key,
-- a line must have exactly one header:
IdHeader int not null foreign key references SalesOrderHeader,
LineNumber int not null, -- a line must have a line number
IdItem int not null, -- cannot have null item
Quantity decimal not null, -- maybe could sell 0, but not null
UnitPrice decimal not null, -- price can be 0, but not null
-- a null delivery address means not for delivery:
IdDeliveryAddress int foreign key references Address,
Comment varchar(100), -- null means user skipped it
Cancelled bit not null default (0) -- true boolean, not three-state!
Delivered datetime, -- null means not yet delivered
Logged datetime not null default (GetDate()) -- must be filled out
)
我会倾向于与dorfier同意。
在你的有关接收数据库NULL值时,是灵活的,把它们当作空值应用严重,你给自己很大的灵活性,让空的get插入你不指定值。
有可能是很多,你需要一些非常严重的数据完整性的情况下(和/或禁止NULL字段的激烈速度优化),但我认为,这些问题是针对需要确保每个领域都有额外的努力锻炼一个默认值和/或获取设置为一个合理的值。
与一切NOT NULL坚持,直到有人用它的痛苦尖叫声。然后在同一时间将其删除的一列,如勉强地。避免在DB空就像你可以,只要你能。
我个人认为你应该标记列作为NULL或NOT NULL根据它们包含什么样的数据,如果该数据总是存在的真正需求,以及是否将数据在时间总是知道输入。标记列不空当用户没有数据将迫使然后来弥补,这使得所有的数据的数据没用(这个你怎么收场用垃圾数据,如含有“的电子邮件字段thisissilly@Ihatethisaplication.com “)。未按规定要求的东西,一定是那里的处理工作(比如键字段显示什么客户作出的命令)同样愚蠢。空副NOT NULL是在心脏数据完整性问题,做什么是最有意义的对让您的数据可用。
如果你能想到长远来看,在一列中的零位会影响您如何设计你的查询。无论您使用CASE语句,COALESCE,或必须明确地测试NULL值可以决定适合你。
从性能的角度来看,它的速度更快不必担心空值。从设计角度来看,使用NULL是知道的项目从未填写一个简单的方法。有用的例子包括“UpdatedDateTime”栏目。 NULL表示一个项目从未更新。
我个人允许空值在大多数情况下。
什么是小的性能影响VS大量NOT NULL列?
这可以说明明显,但,当一个列可以为空,每个记录将需要存储的1额外位。所以一个的 BIT 强>柱将消耗更多的100%的存储时,它可以为空,而在<强> UNIQUEIDENTIFIER 强>将消耗更多的仅0.8%的存储时,它可为空。
在病理情况下,如果你的数据库有一个表由单个BIT列,决定把该列可为空将减少一半你的数据库的性能。然而,绝大多数的实际场景下,为空将不会有一个可衡量的业绩的影响。
使用'Not Null'或'Null'应主要驱动通过你的特别是坚持不懈的要求。
具有的价值是可空意味着有两个或三个国家(三国带点领域)
例如;如果我有一点点领域,其中被称为'是'和价值是设定在较后阶段插入。然后有三个国家:
- '是'不回答
- '是'被批准
- '是'不批准
因此,如果一个领域可以legitimently认为不回答没有的默认值是合适的。这些领域应该考虑在可空的
任何空的列是违反第三范式。
不过,这不是一个答案。
这也许是:有在数据库中两种类型的列 - 保存数据的结构的,并保存数据的含量的。键结构的,用户可输入字段是数据。其他的事情 - 嗯 - 这是一个主观判断。
东西,这结构中,用于在连接子句,典型地是不为空。东西,这数据通常可为空的。
当你持有的选择,或者为空(没有选择制造)列表中的一个列,它通常是有“造别无选择”,而不是一个空列一个特定的值是一个好主意。这些类型的列的经常参与连接。