比如一个用户表,中间一个字段,表示用户所属的企业。
用户可能不属于任何企业。
那么有两种解决方案:
再叠加一个需求,用户表的企业字段需要加索引。
那么,应该选择哪个方案?或者有没有更好的方案?
1
root000 2022-12-29 10:20:40 +08:00
2
|
2
Xhack 2022-12-29 10:22:37 +08:00
is null And is not null 是不会走索引的
|
4
iseki 2022-12-29 10:25:54 +08:00 via Android
依业务需求而定,数据库不能好好处理就说明该换数据库了
|
6
imv2er 2022-12-29 10:33:19 +08:00
业务逻辑设计上选 1
有查询需求的 选 2 |
7
securityCoding 2022-12-29 10:34:16 +08:00
2
|
8
lambdaq 2022-12-29 10:50:27 +08:00
mysql 还是别用 null 了。
|
9
CodeCodeStudy 2022-12-29 10:59:06 +08:00 8
mysql 字段不使用 null 的理由
1 、比如文章点击量加 1 ,column_name = column_name + 1 ,如果把字段设成 null ,并且插入数据时没指明 column_name = 0 ,那么+1 操作不起作用; 2 、count(column_name)时,null 的列不包含在内,count(*)则包含 null 的列在里面 3 、计算多列时,如 SELECT id, click1+click2 as click FROM `foo` 如果两个点击量有一个为 null ,那么相加结果就是 null 4 、如果有比较条件,比如 where < 10 ,如果为 null 的话则不包含在内 5 、min(column_name), max(column_name)如果字段有值,则用值比较,如果字段没有值,都是 null 的时候,则为 null 总结:不能运算,不能比较,慢 |
10
jarvanluo 2022-12-29 11:06:10 +08:00
mysql 我一般都是有默认值,不允许 null 的。text 除外。
|
11
bthulu 2022-12-29 11:11:24 +08:00
我反正是这么来的, 所有表字段都必须设置不允许为 null.
这样在 java 里会减少很多 NPE. |
12
aichunya 2022-12-29 11:29:31 +08:00
现在项目里面,除了类似'收货时间'这种具有业务意义的 date 类型的字段允许为 null 以外,其它类型字段都会设置默认值
|
13
makelove 2022-12-29 11:41:47 +08:00 2
别听楼上的瞎 bb ,这种情况明显用 null
|
14
oneisall8955 2022-12-29 11:43:32 +08:00
某些 datetime 含业务含义和 text 类型的允许 null ,其余都 not null 了
|
15
clockwork1122 2022-12-29 12:18:21 +08:00
@oneisall8955 datetime 是真让我最讨厌的玩意,一般查询的场景都只需要 date 就行,数据库用 datetime 给自己增加查询难度。
|
16
cpstar 2022-12-29 12:37:34 +08:00
|
17
meshell 2022-12-29 13:09:21 +08:00
我说个其它的,在使用 ORM 的 one many 的时候 null 和 0 区别对待的。0 是找不到企业报错,null 没有企业
|
18
yfwl 2022-12-29 13:16:08 +08:00
如果你要给这个列创建索引,那就不能 null ,因为 null 不走索引的,正常的列是允许 null 的
|
19
seth19960929 2022-12-29 13:23:28 +08:00 4
楼上的是不是都要更新知识了? MySQL null 列可以走索引.
我的建议还是你用 null, 毕竟 null 和 0 还是不一样的. 至于加不加索引和 null 不 null 无关, 取决于你的用户是否大多数有企业. 比如你一百万用户就一百个有企业, 别加了. 如果大多数都有, 那就加 |
20
seth19960929 2022-12-29 13:24:55 +08:00
再补充一个, 取决于你的业务需求, 如果你业务代码都是.
1. 先去查找用户 -> 然后在通过用户的企业主键去查找企业 = 不用加索引 2. 找用户 -> join 企业 = 加索引 3. 找这个企业下的用户 = 加索引 |
21
Konys 2022-12-29 13:26:04 +08:00
null 是可以走索引的
|
22
cokar 2022-12-29 13:28:53 +08:00
使用空字符串不是更好吗?
|
24
BQsummer 2022-12-29 15:48:10 +08:00
有些业务场景 0 和 null 就是有区别的, 咋办
|
25
CodeCodeStudy 2022-12-29 16:28:13 +08:00
@cpstar #16 是啊,应该设为设置型,默认值为 0 ,用 0 来表示特殊的含义,而不是 null
|
26
Soler 2022-12-29 16:47:12 +08:00 1
null 是 null, 0 是 0 ,概念首先不要乱用!!!
假设设置成 0 , 0 多了不一样走不了索引吗。 |
27
IvanLi127 2022-12-29 17:24:00 +08:00 1
@CodeCodeStudy 其实这个不好,我觉得更好的方案是:
创建一个缺省公司,用来给那些不属于任何企业的用户挂名的; 然后直接不允许这个字段为 NULL 就好了。 这个方案就是前几年讨论 NULL 有没有必要时,一种比较优雅的方案。 不过要是我的话,如果业务不要求对这类用户做什么操作,我肯定直接设 NULL 了 哈哈 |
28
CodeCodeStudy 2022-12-29 17:33:08 +08:00
@IvanLi127 #27 不用创建缺省公司来挂名,这样反而会搞复杂,企业字段直接用 0 来表示就好了
|
29
IvanLi127 2022-12-29 17:42:10 +08:00
@CodeCodeStudy 其实有个问题。。。你们用 0 的前提是不用外键约束吗?如果用的话应该势必创建一个缺省公司
|
30
JKeita 2022-12-29 17:43:51 +08:00
基本都不允许 null ,能不 null 就不 null
|
31
CodeCodeStudy 2022-12-29 17:43:59 +08:00 1
用 0 或者-1 来表示该值不存在更好的理由是保持一致的数据类型,避免 null 造成 NPE ,比如 Java 和 JavaScript 的字符串的 indexOf 的返回值是 int ,用-1 来表示找不到,而不是返回 null
|
32
CodeCodeStudy 2022-12-29 17:44:31 +08:00
@IvanLi127 #29 不需要外键
|
33
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 ,这样就会带来不必要的麻烦
|
34
xuanbg 2022-12-29 18:06:16 +08:00
@seth19960929 也许他们的版本还停留在 5.5 或更早吧。。。反正我知道的 5.6 版本就已经支持 is null 走索引了。
|
35
wtfedc 2022-12-29 18:39:45 +08:00 2
按逻辑来说,null 是 null ,0 是 0 ,最好是按语意来使用。
至于 select ... where x<y ,本来就不该带上 null 的数据。 |
36
NoKey 2022-12-29 19:00:43 +08:00
如果公司都是用数字的话,就给一个默认公司的数字例如 0 ;如果是文字的话,就创建一个默认公司名,如:NoCompany 之类的,这样也不用纠结你这个问题了,查询起来也简单
|
37
wiix 2022-12-29 19:08:59 +08:00
null 是 null ,0 是 0 ,两者的语义完全不同,该是什么就是什么。
把 null 用 0 表示一是使数据缺少一种表达能力,二是实际并没有减少做判断的心智负担。 很多人讨厌 null 是因为 null pointer exception ,但有错却不能 fail fast ,带病运行更可怕。 |
38
Outshine 2022-12-29 21:30:06 +08:00 1
@CodeCodeStudy #9 你这些理由对于遵循数据库设计范式的来说,完全不是问题。
比如你说的文章点击量、需要比较大小或者参与计算的列,我找不到为 null 的场景。 另外,mysql 早就支持 null 走索引了,知识要及时更新啊。 |
39
iseki 2022-12-29 22:45:57 +08:00 1
不要用 0 来表达没有,更不要自己搞出个 -1 来,这是在挖大坑;
数据库该用 NULL 就用 NULL ,数据库不好处理,就换数据库; |
40
tairan2006 2022-12-30 08:54:15 +08:00
如果大部分用户都有企业,那用啥都可以。
如果大部分用户都没有企业,可以考虑搞个关联表,数据比较少。 |
41
co2fe 2022-12-30 09:04:59 +08:00 1
为什么企业 id 要放在用户表里面,为什么不用关系表存储?
万一你业务以后允许一个用户待在多个企业,你怎么搞。 而且使用中间表,我觉得可以解决你这个纠结 null 还是 0 的问题。 |
42
wi666 2023-04-11 14:29:45 +08:00
选 1 ,并将企业名称字段加索引
|