比如一个用户表,中间一个字段,表示用户所属的企业。
用户可能不属于任何企业。
那么有两种解决方案:
再叠加一个需求,用户表的企业字段需要加索引。
那么,应该选择哪个方案?或者有没有更好的方案?![]() | 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 ![]() 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 ![]() 别听楼上的瞎 bb ,这种情况明显用 null |
![]() | 14 itechify PRO 某些 datetime 含业务含义和 text 类型的允许 null ,其余都 not null 了 |
![]() |
![]() | 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 SethShi 2022-12-29 13:23:28 +08:00 ![]() 楼上的是不是都要更新知识了? MySQL null 列可以走索引. 我的建议还是你用 null, 毕竟 null 和 0 还是不一样的. 至于加不加索引和 null 不 null 无关, 取决于你的用户是否大多数有企业. 比如你一百万用户就一百个有企业, 别加了. 如果大多数都有, 那就加 |
![]() | 20 SethShi 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:5 +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 ![]() null 是 null, 0 是 0 ,概念首先不要乱用!!! 假设设置成 0 , 0 多了不一样走不了索引吗。 |
![]() | 27 IvanLi127 2022-12-29 17:24:00 +08:00 ![]() @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 ![]() 用 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 r4aAi04Uk2gYWU89 2022-12-29 18:39:45 +08:00 ![]() 按逻辑来说,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 ![]() @CodeCodeStudy #9 你这些理由对于遵循数据库设计范式的来说,完全不是问题。 比如你说的文章点击量、需要比较大小或者参与计算的列,我找不到为 null 的场景。 另外,mysql 早就支持 null 走索引了,知识要及时更新啊。 |
39 iseki 2022-12-29 22:45:57 +08:00 ![]() 不要用 0 来表达没有,更不要自己搞出个 -1 来,这是在挖大坑; 数据库该用 NULL 就用 NULL ,数据库不好处理,就换数据库; |
40 tairan2006 2022-12-30 08:54:15 +08:00 如果大部分用户都有企业,那用啥都可以。 如果大部分用户都没有企业,可以考虑搞个关联表,数据比较少。 |
![]() | 41 co2fe 2022-12-30 09:04:59 +08:00 ![]() 为什么企业 id 要放在用户表里面,为什么不用关系表存储? 万一你业务以后允许一个用户待在多个企业,你怎么搞。 而且使用中间表,我觉得可以解决你这个纠结 null 还是 0 的问题。 |
42 wi666 2023-04-11 14:29:45 +08:00 选 1 ,并将企业名称字段加索引 |