我是数据库设计的新手,据我所知,使用null
值表示没有现有数据并不是一个好主意,我现在遇到的问题是我不知道如何代表现有数据而不是null
。
例如,我有一个用户表和一个FavoritColor
表,用户有一个名为FC的列,它是FavoritColor表的ID的键。现在我给用户提供了不选择颜色的可能性,我怎么注意到,如果用户选择不选择颜色,FC列会被填充什么?
答案 0 :(得分:2)
NULL是" THE"在SQL中没有数据的表示,所以我建议你这样使用它。
你总是可以在列中插入NULL,没有理由不这样做。 如果你真的不想因为我无法理解的原因而使用NULL,我认为(下一个)最合乎逻辑的表示是"没有数据"将是一个空字符串('')
但同样,我会坚持标准...... NULL。
答案 1 :(得分:2)
NULL
是一个非常好的值。如果您担心默认值,请确保使用OUTER JOIN
和(对于SQL Server,无论如何),您可以执行以下操作:
SELECT user_table.name, COALESCE(preferences.color_preference, 'DEFAULT_VALUE') FROM user_table LEFT OUTER JOIN preferences ON user_table.id = preferences.id;
这种类型的查询将允许您设置默认值并将NULL
存储为首选颜色,如果color_preference为NULL
或者没有行,则您将获得此默认值偏好表。
你说"如果用户选择不选择颜色,FC列会填充什么?"。我问,你为什么关心?它们要么具有指定的颜色,要么具有指定颜色。你是否关心他们是否可以选择指定喜欢的颜色但没有告诉你?
答案 2 :(得分:1)
NULL
通常用于表示“未知”,这就是'Ellen' <> NULL
不会导致TRUE
,而是导致NULL
的原因。 不知道我们仍然不知道的价值是否是'Ellen'。一个例子是中间名;只要该字段为空,我们不知道Mary的中间名是否是Ellen。
但是,我们常常将NULL
用于“不适用”,例如产品表中的建议零售价 - 有些产品根本没有。所以我们知道没有RRP,它不是“未知”,但我们仍然使用NULL
。我们还能做些什么?使用0代替 - 然后错误地在我们的网上商店显示建议零售价为零美元?或者添加标志has_rrp?一列内容有两列? NULL
通常是更简单的解决方案。
然后,我们可以使用NULL
来表示“没有价值”。在用户表中说出图像。有些用户在我们的数据库中没有照片,因此值仍为空。对于二进制数据,没有其他值NULL
为空。我们不能在那里放零,因为该列应该包含图像数据,比如jpeg数据等。
还有一些其他方法可以表示单个字段的“无数据”。在图像示例中,我们可以添加一个具有1:1关系的user_image表,并且记录是否存在。对于字符串,我们使用''和数字我们有时可以 - 并非总是 - 使用零。对于日期,例如在包含from_date和to_date的过去和未来价格的价格表中,人们有时会置于极端日期(0001-01-01,9999-12-31)以避免复杂的查询。
对于您的ID,我们还有一个选项:拥有“无值”的ID和另一个表中的相应条目。只要我们不想要“无价值”的任何特殊处理,这是一个很好的解决方案。在您的示例中,您可以在GUI中显示组合框,其中包含“黑色”,“红色”,“蓝色”,......和“无颜色”,您可以选择“无颜色”,就像选择“蓝色”一样容易”。但是如果你想要特殊待遇,那么你会有and color_id <> (select id from colors where value = 'no color')
之类的查询,这可能很烦人。
顺便说一下,有时人们会使用NULL
甚至“所有价值”。假设您有一张每个商店的产品价格表。 make shop_id为NULL,你有一个所有商店的默认价格,填写shop_id然后你有一个特定商店的价格。
NULL通常需要特殊处理,如IS
而不是=
,外连接和COALESCE(color, 'no color')
等构造。这本身既不好也不坏。如果您想在用户表中计算不同的喜欢颜色,那就很好了。 “没有喜欢的颜色”的NULL不会被COUNT(DISTINCT color)
计算在内,您只会计算喜欢的颜色。
毕竟这是一个决定。您是否需要区分“尚未知”和“知道没有价值适用”?你想对待“红色”以外的“无色”吗? NULL
代表“无价值” 是一个选项,通常会使用它。决定你的情况是否合适。没有规则说永远不能用NULL
来表示“没有价值”。
答案 3 :(得分:0)
建议:
1)从users表中删除FC
列并添加关系表以模拟用户与他们喜欢的颜色之间的关系,例如UsersFavoritColor
。现在应用closed world assumption,假设未出现在UsersFavoritColor
表中的用户实际上没有喜欢的颜色。
2)添加另一个表UsersWhoHaveNoFavoritColor
只包含人员标识符,确保两个表中不能有同一个人。如果您需要建模更多关系,请添加更多表格,例如UsersWhoAreKnownToHaveNoFavoritColor
,UsersWhoAreKnownToHaveAFavoritColorButRefusedToTellUs
等
3)使用合适的默认值表示“无颜色”(如果有的话)。
答案 4 :(得分:0)
这是一个概念性问题,详情见lot places个SO。这取决于企业如何看待您的数据。
假设您对问卷或用户偏好提出了与用户相关的喜欢颜色的问题。您的数据库表包含user_id和特定颜色的十六进制。数据库设计者使用NULL作为值来表明用户尚未表达对其喜欢的颜色的任何想法。假设用户选择一种颜色,然后有一个重置按钮。在这种情况下,您可能希望有一个空字符串而不是NULL值,通过这标记不具有所有首选项和删除现有首选项之间的差异。
答案 5 :(得分:0)
OP发现“...使用null
值表示没有现有数据不是一个好主意,...”
(这可能是基于意见的。)
我完全不同意这种说法。 NULL值具有一些显着的优点。使用SQL为NULL值提供的内置本机支持是一个非常好的主意。
通常,NULL值被描述为表示“未知”值。
是的,在处理需要注意的NULL值时有一些怪癖。与NULL值进行相等或不等式比较将返回NULL,而不是TRUE或FALSE。我们只需要知道在SQL中,布尔逻辑是三值的,而NULL 从不等于TRUE而从不等于FALSE。
这些怪癖实际上是使NULL值非常强大的原因。
如果要使用除NULL之外的某种机制来表示“无数据”,则需要...
存储表示“无数据”条件的非NULL“特殊”值,以及检查和操作“特殊”值的附加逻辑。
在第二列中存储非NULL“无数据”指示符/标志,以及用于处理第二列的填充,检查和操作的附加逻辑,以及第一列。
然后你还需要在外键引用的表中提出虚拟的“无数据”行,因此外键列中的非NULL“无数据”值有一行要引用。这就是我在想你问的问题......
如果要声明外键列NOT NULL,并且在没有提供值时具有默认值,则该默认值将需要引用引用表中的行。
作为这种方法的演示...注意:我 NOT 提倡将其作为一种合适的设计......仅仅是使用NULL值来表示“解决” “没有数据”。
create table favcolor
( id int not null primary key
, favcolor_name varchar(30) not null
);
create table user
( id int not null primary key
, favcolor_id int not null default '1' comment 'fk, ref favcolor.id'
, constraint FK_user_favcolor foreign key (favcolor_id) references favcolor(id)
);
insert into favcolor (id, favcolor_name) values (1, 'not chosen');
完成所有这些后,您将发现与旧设计师一样的事情。将这种“未知”,“无数据”,“未选择”的处理作为SQL的本机内置函数将是非常非常有用的。这就是为什么首先引入NULL值,作为解决这类问题的原因。