sql 表设计问题:需索引的可选字段应该允许 null 吗?

2022-12-29 10:16:35 +08:00
 1800x

比如一个用户表,中间一个字段,表示用户所属的企业。

用户可能不属于任何企业。

那么有两种解决方案:

  1. 企业字段允许为 null 。用户不属于企业时,企业字段为 null 。
  2. 企业字段不允许为 null ,默认 0 。用户不属于企业时,企业字段为 0 。

再叠加一个需求,用户表的企业字段需要加索引。

那么,应该选择哪个方案?或者有没有更好的方案?

4367 次点击
所在节点    数据库
42 条回复
Konys
2022-12-29 13:26:04 +08:00
null 是可以走索引的
cokar
2022-12-29 13:28:53 +08:00
使用空字符串不是更好吗?
zhangtest
2022-12-29 14:26:04 +08:00
@Xhack 大哥们,你们了解下 mysql 不同版本的区别吧,别总把古董版本的特性带到目前常用的版本。
BQsummer
2022-12-29 15:48:10 +08:00
有些业务场景 0 和 null 就是有区别的, 咋办
CodeCodeStudy
2022-12-29 16:28:13 +08:00
@cpstar #16 是啊,应该设为设置型,默认值为 0 ,用 0 来表示特殊的含义,而不是 null
Soler
2022-12-29 16:47:12 +08:00
null 是 null, 0 是 0 ,概念首先不要乱用!!!

假设设置成 0 , 0 多了不一样走不了索引吗。
IvanLi127
2022-12-29 17:24:00 +08:00
@CodeCodeStudy 其实这个不好,我觉得更好的方案是:

创建一个缺省公司,用来给那些不属于任何企业的用户挂名的;
然后直接不允许这个字段为 NULL 就好了。

这个方案就是前几年讨论 NULL 有没有必要时,一种比较优雅的方案。

不过要是我的话,如果业务不要求对这类用户做什么操作,我肯定直接设 NULL 了 哈哈
CodeCodeStudy
2022-12-29 17:33:08 +08:00
@IvanLi127 #27 不用创建缺省公司来挂名,这样反而会搞复杂,企业字段直接用 0 来表示就好了
IvanLi127
2022-12-29 17:42:10 +08:00
@CodeCodeStudy 其实有个问题。。。你们用 0 的前提是不用外键约束吗?如果用的话应该势必创建一个缺省公司
JKeita
2022-12-29 17:43:51 +08:00
基本都不允许 null ,能不 null 就不 null
CodeCodeStudy
2022-12-29 17:43:59 +08:00
用 0 或者-1 来表示该值不存在更好的理由是保持一致的数据类型,避免 null 造成 NPE ,比如 Java 和 JavaScript 的字符串的 indexOf 的返回值是 int ,用-1 来表示找不到,而不是返回 null
CodeCodeStudy
2022-12-29 17:44:31 +08:00
@IvanLi127 #29 不需要外键
CodeCodeStudy
2022-12-29 17:52:26 +08:00
@CodeCodeStudy #9 补充一下第 4 点,如果某列允许为 null 的话,那么语句 where column_name > 10 ,where column_name < 10 ,where column_name = 10 均不能把实际值为 null 的行过滤掉,因为要用 where column_name is null ,这样就会带来不必要的麻烦
xuanbg
2022-12-29 18:06:16 +08:00
@seth19960929 也许他们的版本还停留在 5.5 或更早吧。。。反正我知道的 5.6 版本就已经支持 is null 走索引了。
r4aAi04Uk2gYWU89
2022-12-29 18:39:45 +08:00
按逻辑来说,null 是 null ,0 是 0 ,最好是按语意来使用。
至于 select ... where x<y ,本来就不该带上 null 的数据。
NoKey
2022-12-29 19:00:43 +08:00
如果公司都是用数字的话,就给一个默认公司的数字例如 0 ;如果是文字的话,就创建一个默认公司名,如:NoCompany 之类的,这样也不用纠结你这个问题了,查询起来也简单
wiix
2022-12-29 19:08:59 +08:00
null 是 null ,0 是 0 ,两者的语义完全不同,该是什么就是什么。
把 null 用 0 表示一是使数据缺少一种表达能力,二是实际并没有减少做判断的心智负担。
很多人讨厌 null 是因为 null pointer exception ,但有错却不能 fail fast ,带病运行更可怕。
Outshine
2022-12-29 21:30:06 +08:00
@CodeCodeStudy #9 你这些理由对于遵循数据库设计范式的来说,完全不是问题。
比如你说的文章点击量、需要比较大小或者参与计算的列,我找不到为 null 的场景。

另外,mysql 早就支持 null 走索引了,知识要及时更新啊。
iseki
2022-12-29 22:45:57 +08:00
不要用 0 来表达没有,更不要自己搞出个 -1 来,这是在挖大坑;
数据库该用 NULL 就用 NULL ,数据库不好处理,就换数据库;
tairan2006
2022-12-30 08:54:15 +08:00
如果大部分用户都有企业,那用啥都可以。
如果大部分用户都没有企业,可以考虑搞个关联表,数据比较少。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/905289

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX