最近在设计数据库,我基本全部数据都不允许 null,然后可能为 null 的,我都给了默认值“无”用的中文,,请问这样的操作会不会无意中给自己挖了坑呢?
1
codingadog 2018-12-28 15:39:13 +08:00 via iPhone 1
你这字段全是 varchar ?
真有个值就是“无”进来你咋办 |
2
night98 2018-12-28 15:41:06 +08:00 via Android 3
很多人分不清楚“”和 null 的区别也就算了。。。还有人设置为无的。。。
|
3
l00t 2018-12-28 15:41:54 +08:00
你不如问什么时候不允许数据为 null。当你想不出什么理由不允许的时候,那就允许为 null
|
4
mahone3297 2018-12-28 15:43:12 +08:00
我觉得会
|
5
luosuosile OP @codingadog 好像有道理
|
6
libook 2018-12-28 15:52:24 +08:00 1
1. 以后不会把“无”当做非 null 的情况来用。
2. 不需要判断是不是“无”值。 业务符合上述条件的话,我觉得这么做也挺好的,前端不需要再判断是不是 null 然后重写成“无”展示出来。 但如果前端需要判断“无”的情况,比如有个按钮,如果字段为“无”就把按钮禁用,这样用 null 可能更好一点。 |
7
sun1991 2018-12-28 15:56:18 +08:00 1
一般能非 null 就不要允许 null. 随意允许 null 会给以后带来麻烦.
null 就相当于一个缺省值. 如果什么值都不合适做缺省值的情况下, 那也只能允许 null 了. |
8
luosuosile OP @codingadog 我这里是在微信号和班级,这两个字段设置了,默认无,因为不是所有人都有微信号。暂时应该不会发生你说的情况,但是你说的情况是值得考虑的
|
9
luosuosile OP @sun1991 对,我就是这么想的,所以基本都不想允许 null,但是有的字段我认为业务会出现空值的情况,我就想给个默认值,看看能不能避免掉允许 null。感觉英文和中文也没什么所谓,因为开发我肯定全是中国人,就默认了'无'
|
10
luosuosile OP @libook 你说的很有用,应该不会出现这种情况,我还需要再考虑考虑
|
11
mxalbert1996 2018-12-28 16:06:14 +08:00 via Android
@l00t 我觉得如果没有特别的需要 null 的理由的话就不要允许 null,毕竟对性能也是有影响的,用空值就好
|
12
luosuosile OP @mxalbert1996 嗯,允许 null 好像每行多占用一个字节,而且对这个值建索引也要多一个字节。并且有 null 值的列走索引好像更不舒服。所以数据量大了,感觉影响还是比较大
|
13
l00t 2018-12-28 18:40:49 +08:00
@mxalbert1996 #11 什么性能问题?
|
14
l00t 2018-12-28 18:45:45 +08:00 1
@luosuosile #12 你在说什么鬼……不同数据库有不同的处理方式,就是同一个数据库比如 MySQL,不同的引擎也有不同的做法。因为性能调优之类的原因而做取舍不是不可以,但要建立在你确定知道你在做什么的前提下。如果不清楚不知道,那就不要想太多,尽量使用和发挥特性来满足业务需求才是优先。
|
15
mmdsun 2018-12-28 18:54:10 +08:00 via Android
我对网上传闻表示质疑。一直以来都有说 MySQL 不适合用 null 用“”来代替。
mysql 文档上有写对 is null 查询有额外的优化。 那么 where 字段=“”这样真的比 where 字段 is null 查询要快?? 如果一个表的字段,有 10%数据的可能是空的。用“”还是 null 好?,如果 80%都为空:是用“”还是用 null 好? |
16
mmdsun 2018-12-28 18:56:19 +08:00 via Android
如果是数值呢?楼主是默认返回 0 么?
假如字段是考试成绩。 0=0 分 null 等于没有考试 还是有区别的 |
17
msg7086 2018-12-28 19:00:33 +08:00 1
@luosuosile NULL 和'NULL'是两回事啊。
微信号不允许中文这也就算了,如果某个字段里「无」是合法值怎么办。 而且假如你的业务要求微信号需要唯一索引怎么办?你给每个无都加上小尾巴吗。 真要说性能调优,请拿实际性能测试说话。这个索引会产生多大的性能损失,修改后是否有性能改善,改善有多大,是否值得牺牲数据正确性来换取这个性能调节。 NULL 原本的用途是表示一个值未提供。对于微信号这种字段,如果用户没有填写,那么 NULL 就是最适合的表达了。空字符串、默认值等实现方法一样有上面的唯一索引冲突问题。 如果理解上有困难,可以换个思路去理解:NULL 不是一个值,NULL 是没有值,NULL 不是缺省值。 |
18
momocraft 2018-12-28 19:03:24 +08:00 1
"无" 还不够坑,还可以根据用户 locale 返回 "冒得" "nil" "某" 等
|
20
passerbytiny 2018-12-28 19:26:50 +08:00 via Android
Boolean.true, Boolean.false, <Boolean>null,是 Boolean 变量可能有的三个值,请问楼主此时怎么表示第三个值。
再来个贴近现实的,楼主准备怎么表示一个人一次考试是否及格的全部情况—及格、不及格、没考试 |
21
rogwan 2018-12-28 19:47:28 +08:00 via iPhone 1
没有必要矫枉过正。这个值本来可能有,可能没有,不用找一个符号去代表没有,Null 自己代表没有完全没有问题。
|
22
Leigg 2018-12-29 09:04:56 +08:00 via iPhone
一般可以用空串表示 null,除非场景特殊,我认为你的场景是可以这么做的,微信号为空串不就代表没有提供吗。
|
23
luosuosile OP 昨天直到下班都没多少回复,今天一上班看到 16 条很是高兴,V2 确实给了我一个解惑的平台,这么热心的 v 友,百度是找不到的,google 又太吃力了。
|
24
luosuosile OP 前提还是说明一下吧,我是个一年菜鸡,这是我第一次主力设计数据库,虽然产品要求其实不是很高,但我认为是个宝贵经验,想要尽量做到尽善尽美。
那么我先来解释一下我为什么会这么做,又为什么会产生疑问,事先说明一下,我这个做法不是百度得来的,也不知道有人用“”来代替 null,这种做法快或者不快。“”,和 null 我的理解仅止于空字符串和没有插入数据,能听到大家的理解我也很开心。 我会这么做,是因为对《高性能 mysql 》这本书稍微认真的读了一遍,于是参考这本书进行数据库设计。但是苦于没有经验,理解仅止于表面,而不知道实际是怎样的, 我并不是想拿书名,背书来反驳各位,只是想解释一下我为什么这么做,不想大家觉得我是个百度就完了的 boy。 里面有一个简单的原则: “尽量避免 null ”,实际上内容不翻书我也记不得,只记得作者确实很强调,如果不是真的需要 null,就不要允许 null。 刚好之前帮朋友进行了下数据库优化,虽然是菜鸡互啄,但效果还是有的,从 4 分钟变成了 3 分钟,大概设计的人是个更大的菜鸡,因为他的公司是个外包公司。。这里主要时看到他的语句中有大量的 isNull,和对“”的判断。觉得很难受,在想自己能不能尽量避免这种情况。 刚好业务就来了,未必能传值进来,与其放着 null,我在想放一个别的可能会更好,所以就有了这个问题。至于唯一索引 我确实没有想到,学习到了。 还有,对于这种优化有没有必要的疑问,诚然,为了提升那么一点性能而牺牲业务是很愚蠢的,而且我也不认为自己的数据量可能大到需要如此刁钻的优化,甚至随便搞搞都够用,只是我想做到尽量都能考虑到,,因为问题就在那里,放着我觉得不舒服。 |
25
luosuosile OP 还有对于上来就嘲讽的,我就是不懂才来提问的,你嘲笑一个本来就不懂的人不懂他的问题,我不知道有什么意思。
回复框右下角不是有“请尽量让自己的回复能够对别人有帮助吗”。 |
26
luosuosile OP @msg7086 你说的有道理,我觉得很有帮助。
不如说,我想知道如果一个表非常大,性能要求高的时候,设计表对这个是否允许 null 是怎么处理的。 我的确知道自己的业务没有必要这么做。 确实如果对多种数据类型想表达这种思想,找不到一个统一的符号,分别给一个符号又太蠢,允许 null 确实是很好的做法。 |
27
msg7086 2018-12-29 11:07:34 +08:00
@luosuosile 如果是我来设计的话,语义正确性我是会放在首位的。
如果语义正确导致性能下降,那么我宁愿考虑从其他地方对数据库进行优化。 比如你已知某个查询会花掉三五分钟,那么首先这个查询本身能不能优化?能不能拆分成多句简单句?能不能把负载压力从数据库转嫁到应用程序端(以方便横向扩展)?能不能把查询的结果缓存进 Memcache / Redis ? 而且一个简单的 NULL (旗标)变成一个复杂的值(字符串),到底对性能有正面影响还是负面影响?直觉告诉我,这样的索引效率可能会更低。我一时想不出有哪个查询在这样修改以后会变快的。如果你有合适的查询语句的话,不妨贴出来大家一起研究一下。 |
28
micean 2018-12-29 13:21:09 +08:00
肯定挖坑,只要空字符串就行了
|
29
l00t 2018-12-29 23:18:03 +08:00
@luosuosile #26 说到性能就要说明具体的操作环境了。比如你用的是什么数据库(从你不经意的透露我推测是 MySQL ),什么引擎,表的数据量大小,查询的数据量一般在多少,需求的响应时间大概是什么级别。《高性能 mysql 》那本书我记得它紧接着就说把 NULL 列改为 NOT NULL 带来的性能提升很小吧? 另外说实话,它的这段描述到底对不对我都是很怀疑的…… 要考虑它的时代背景。你比如你说允许为 NULL 的记录占用空间真的会多些? InnoDb 里明显不成立嘛。假如你编码为 UTF8,一个“无” 占 4 个字节(3 + 1),一个 null 只占一字节,而且还能和其他 7 个 null 共享。
带 null 的列,我见过的主要顾虑大多是出于开发时对 null 判断的处理上的。很多人写着写着会忘了 is not null, is null 这种事,而一律用 大于小于等于,以至于踩到坑。另外就是玄学,“我也不知道为什么,反正不要用就是了”。 |