刚来一家新公司注意到数据库里新建的表有一堆 null 值的字段,想数据量大会影响索引,项目也刚开我就改了下,然后就被训了,就说别动数据库,非不非空让前端去判断(我就想是前端判断啊,但后端不也要校验,数据库只是优化查询)但我没之声 而且好多字段都是中英混用,可难受死我这强迫症了 比如父 id fid 组织类型 orglx 行政区划代码 xzqh 行政区域编码却是 adcode [捂脸.jpg]
1
linvon 2021-04-15 11:10:31 +08:00 3
快跑
|
2
kkkkkrua 2021-04-15 11:11:44 +08:00
快跑
|
3
adjusted 2021-04-15 11:13:15 +08:00
rails 默认一堆 allow null
|
4
thiscat 2021-04-15 11:14:32 +08:00
跑
|
5
s0nnse 2021-04-15 11:15:39 +08:00
决定不能信任前端的数据,跑,快跑
|
6
WilliamYang 2021-04-15 12:42:41 +08:00 via iPhone
快跑,我说一句腊鸡
|
7
dallaslu 2021-04-15 12:49:17 +08:00
很多很多年前,接触过一个产品,字段名是 a1, a2, a3 ... an 。使用的时候,比如价格字段就是 a200 ;优惠价格 a201 ;商品名 a60……
|
8
raaaaaar 2021-04-15 12:55:22 +08:00 via Android
中英配合的一看就不标准啊,可以走了
|
9
cjw1115 2021-04-15 12:58:02 +08:00 2
“比如父 id fid 组织类型 orglx 行政区划代码 xzqh 行政区域编码却是 adcode”
这尼玛可太优秀了,面向自己编程 |
10
jonathanshi 2021-04-15 13:12:50 +08:00
跑吧
|
11
lyoume 2021-04-15 13:19:01 +08:00 via iPhone 1
org lx 哈哈哈 秀
|
12
timethinker 2021-04-15 13:31:23 +08:00
NULL 值会影响索引?关于这一点我觉得还是要看场景,如果仅仅只是用空字符串或者 0 来替代 NULL 值,我觉得是没有必要的。也取决于用的什么数据库 /存储引擎。
|
13
dyxLike 2021-04-15 13:45:43 +08:00
null 字段没那么严重吧, 不过这个命名方式确实...
|
14
javapythongo 2021-04-15 13:54:13 +08:00
改数据库之前没有跟 learder 讨论吗?
|
15
GGGG430 2021-04-15 13:54:23 +08:00
@qwe520liao
@dyxLike 大量 null 值相比于空字符值会占用大量空间, 导致 b+树单个叶子节点(页)能存储的方式行数减少, 一方面会增加树高导致 io 次数增加, 也就增加了 mysql 查询耗时; 另一方面会导致 buffer pool 在有限的内存中缓存的行数减少, 降低缓存命中率; 最后, null 对 count 也不友好 当然, 以上是我最近面试需要, 看了一些八股文瞎猜的 |
16
timethinker 2021-04-15 14:08:34 +08:00 26
@GGGG430
1 、NULL 值并没有比空字符串占用更多的空间,反倒是如果一个列本身用 NULL 是很自然的选择,但是强行给了一个默认值,那么这个默认值反而比 NULL 值所占用的空间更大。 2 、关于索引,如果索引的值本身就很稀疏,那么使用默认值来替代 NULL 并不会有什么帮助( b-tree )。 3 、还是那句话,取决于使用场景和数据库 /存储引擎,如果明确告诉你使用 NULL 就会有问题,那么这个时候才应该考虑是不是要做此类优化,提前优化是万恶之源,而且此类优化效果也是微乎其微的,只是它的不利影响被放大了。 数据库 /存储引擎有很多选择,版本也有很多,很多网上的奇淫技巧只针对于特定的版本有效,没有必要纠结在这些小问题上,国内很多公众号、技术文章现在基本上都是广告居多,颇有点中医理论的味道。 |
17
Mac 2021-04-15 14:14:44 +08:00
我对 NULL 值没这种执念,我觉得 null 挺好的,is null 和 is not null 比 empty 判断要好多了,而且我买的几家国外商业项目,也是把 null 当默认的空值在用,也没什么计较的.
|
18
GGGG430 2021-04-15 14:25:25 +08:00
@qwe520liao
首先 NULL 需要一个额外字节作为判断是否为 NULL 的标志位, 其次您应该没接触过 mysql 规范吧, 有正规 dba 的地方, 建表时都是强制 NOT NULL DEFAULT '' 或 0 的 |
20
wuyazuofeiji 2021-04-15 14:32:05 +08:00 16
我觉得你的工作方法有问题,改库这种不是应该先沟通,不管公司烂不烂
|
21
AhogeK OP null 只是导火索 只是自己以前很少用 is null / is not null 公司里带 null 字段的有的是空串有的却是 null 的问题 就是不统一 null 是否影响索引是看场景 主要就是规范上比较难受 命名只是其中之一 公司所有的接口也不是按 RESTful 风格 统一 POST 明明用了 @RestController 却还要加个 @ResponseBody 还能在 Mapper 上看到 select * 跟大量内查询 感觉太随意了 不过看项目规模也确实没啥影响 嘿嘿
|
22
fiypig 2021-04-15 14:35:19 +08:00
不要随便动已上线的数据库 , 这个你要先沟通下 ,还有一般字段创建的时候就不应该有 null 存在...
|
23
AhogeK OP @wuyazuofeiji 哈哈哈 是的 主要是项目初 一开始让我建我建一半 结果他们又自己建好了 我又自做聪明改了 怪 哈哈哈
|
24
AhogeK OP @fiypig 没上线,上线肯定不能的乱动,我也动不了,就是刚开始的项目 会也都没开过 字段怎么定啥的,公司直接 copy 了老项目结构吧应该
|
26
bk201 2021-04-15 14:48:53 +08:00
你这种人容易惹出事情,不要手贱。
|
28
imn1 2021-04-15 15:12:52 +08:00 5
我不担心你在这公司如何(事已至此),只担心你以后会如何
一句话、一个动作,让全体改代码,不管对不对,这情况能活着就很好了,你要明白你不是老大啊…… |
29
enderftt 2021-04-15 16:48:23 +08:00
@dallaslu 。。。我现在就是,某 ERP 产品,库里表就是 AAAAA AAAAB ACTLE 这种, 字段统一都是表后 2 位+001
比如 AA001 AA002 LE001 LE002 |
30
securityCoding 2021-04-15 16:48:32 +08:00
随便搞数据库字段容易被打哦
|
31
IGJacklove 2021-04-15 16:54:30 +08:00 via Android
不管怎么样改之前都得先和大家说一声吧,万一你这改了线上出了问题算谁的?
|
33
wakzz 2021-04-15 17:01:03 +08:00 5
@GGGG430 Null 值需要一个比特位做标识位,也就是说 8 个 Null 才用一个字节,而 int 类型一个 0 占用 4 字节,char 类型一个空值需要 1 字节的长度位表示,Null 值才是最省空间的方案。
另外你说的 mysql 规范,规范是人定的,很多场景下,Null 、空字符串是两种含义,技术是为了业务服务的,不能为了符合规范反而让业务更加复杂。 |
34
telung 2021-04-15 17:02:44 +08:00
新公司上班,不要总觉得自己比别的同事聪明
|
35
Rwing 2021-04-15 17:07:52 +08:00
这代码 走人吧
|
36
fkdtz 2021-04-15 17:16:32 +08:00 3
公司没规范是公司的问题,你不沟通直接改就是你的问题了。
|
37
Lemeng 2021-04-15 17:18:30 +08:00
好心办坏事,还是不懂的话,除非发需求
|
39
iloveayu 2021-04-15 17:20:00 +08:00
不是你的屎,为什么要强吃
|
40
zengming00 2021-04-15 17:20:36 +08:00
@wakzz 我觉得从程序效率的角度看 int 类型应该是预先分配了空间的,因为一个表结构如果存储的数据长度不一致会导致查找效率降低,因此实际的情况大概率是一个 int 类型和一个 bool 类型标识同时存在,共同组成来表示 int 字段的 null
|
41
AhogeK OP 不过改得是没数据的表 而且也不用动代码 也没有代码只有 mpg 生成的简单 crud 被说的话就像大家说我的那样 呜呜呜 别骂了别骂了 代码的话提议了阿里规范扫描倒是接受了 数据库改善还有待商讨,固定的几个字段上一家公司就是阿里规范的,比如表达是与否概念的字段,必须使用 is_xxx 的方式命名,但这家公司比如删除 deleted 不过也接受 创建时间跟更新时间用的 create_date 跟 udpate_date 也没事,创建者用的 creator 也没事,更新者直接来了个 updator ?数据库里字段类型我可啥都没改 比如时间用 datetime 不用 timetimestamp
|
42
eric96 2021-04-15 17:46:32 +08:00
这个数据库字段命名,真的,快跑
|
43
ashuai 2021-04-15 18:11:09 +08:00
这谁顶得住?赶紧跑
被同化后你想找下份工作就难了 |
44
isnullstring 2021-04-15 18:19:55 +08:00
弄默认值 其实很正常,也很应该
但是之前没整,那就不要多手去加,吃力不讨好 V2 和知乎也经常看到问,为什么上一任程序员看到垃圾代码不去优化 有些代码是用时间、用钱逐个坑填上,你看到的只是最终结果 |
45
GGGG430 2021-04-15 18:20:01 +08:00
@wakzz 空字符串占用空间? 你是百度的吗?
另外, 你说规范是人定的, 我们就可以随意更改规范, 然后跟着自己的感觉来, 然后公司里面员工 A 用 null, 员工 B 用'', 这是你说的让业务更简单了? |
46
optional 2021-04-15 18:27:36 +08:00 via Android
人云亦云的孩子
|
47
chrosing 2021-04-15 18:31:04 +08:00
跑~
|
48
redtea 2021-04-15 18:31:51 +08:00 2
性能和程序运行正常哪个重要?项目还没吃透就敢动手?改了以后有没有回归测试?最关键的是为什么改之前不问一声?
|
49
joesonw 2021-04-15 18:35:19 +08:00
run forest, run
|
50
Tumblr 2021-04-15 18:42:30 +08:00 4
首先不管别的,单是你这行为,如果是在我的团队,第一我会赶紧让人把数据库密码改了,并且不能让你知道;第二把你手上的关键任务转给其他人,给你些不那么重要的东西。。。
|
53
Narcissu5 2021-04-15 18:54:01 +08:00
@wakzz 但是对于非空的字段而言,这个 1bit 就是完全多余的。如果列大部分值都是非空,NULL 就是更费空间。如果大部分字段都是 NULL,那么这个表的设计很可能有点问题
|
54
limuyan44 2021-04-15 18:54:09 +08:00 2
良心劝告一下,就算之前的设计是一坨屎,你这行为也是大忌,可能严重到想开除的地步。
|
55
Fule 2021-04-15 19:20:59 +08:00 3
对于是否设置为可空,我觉得关键不在于是否浪费空间,是否影响索引,使用是否方便。关键在于这个字段的**语义是否可以有、“未知”、“未设置”的含义**。
比如“生日”这个字段,如果是在一个存放“出生婴儿”的表里,那么这个字段就应该是不可空的,因为出生婴儿必然有个出生日期(生日)这个逻辑没问题吧。 再比如“成绩"字段, 0 和 空 是不同的概念,空代表“未知”、“未设置”,0 代表有成绩,就是 0 分。所以如果表里的成绩允许有“未知”、“未设置”这个概念的话,应该设置为可空类型。而不应设置为不可空类型,默认值 -1 之类的。 此例中如果设置不可空默认值-1 的问题在于,数据必须在某个层级将 -1 转化为 “空”才能展示到界面,而用户在界面上未显式设置时又要将“空”设置为 -1 再保存,繁琐而现实意义不大。 |
56
wakzz 2021-04-15 19:31:37 +08:00
@zengming00 不用觉得,我看过底层数据实现结构,允许 null 值的列,都有一个比特位值来表示该列的值当前是否是 null 。
|
57
wakzz 2021-04-15 19:37:20 +08:00 2
@GGGG430 我看过 innodb 的底层文件结构,空字符串的值本身不占用空间。但例如 varchar 等变长字段,都需要一个字符长度值来让程序知道该变长字段的字节长度。这个字符长度值本身占 1 到 2 个字节,而空字符串的字符长度值占用 1 个字节。
另外,我指的规范是人定的意思,不是说完全不用遵守规范,别非黑即白。而是按照实际的业务情况和历史原因,定义符合自己实际情况的规范。你这所指的完全没有规范就离谱了 |
59
wakzz 2021-04-15 19:40:56 +08:00 1
@Narcissu5 1bit 真的可以忽略不计,与其讨论空间浪费,不如更关注 null 值、0 值和空字符串会不会引起业务歧义的问题。
|
60
nthhdy 2021-04-15 19:47:37 +08:00
我觉得吧,只要不改完一上线都挂了,都有讨论的余地
|
61
xupefei 2021-04-15 20:02:37 +08:00 via iPhone 1
团队精神不足是一个大 behavioural flag,在面试中能直接枪毙了。
|
62
AEDaydreamer 2021-04-15 20:14:08 +08:00
这个变量名我看着血压都已经升高了,要是我在 design table 里看到一定会找建表的人说道说道
|
63
killergun 2021-04-15 20:23:23 +08:00
我上家公司单表接近一个亿的字段也是设置成 null
|
64
Seanfuck 2021-04-15 20:35:10 +08:00 1
我记得 null 和空值也是有区别的,null 不 null 是字段设计(程序)的逻辑,空不空是数据(用户)的逻辑,这样对不对?比如一个字段既要判断用户有没有改过,同时也给用户设置为空的权力。
|
65
makdon 2021-04-15 20:47:53 +08:00 2
新版本的 Mysql 的 null 用就是了
如果业务上面一个字段是可空且,那就应该设置为 nullable 的列 举个例子,有一列是采集用户的某个数据,假设是今天使用的电量吧 那未采集的状态就是 null,采集了一度电都没有用过就是 0,这里就需要显式区分没有采集的状态 当然你可以引入其它额外的标记位,或者引入 -1 类似的默认值 但是这样又会在求和求平均等场景引入额外的判断条件( where cost != -1) 最自然的做法我觉得还是让列为 nullable 就可以了 reference: https://dev.mysql.com/doc/refman/5.7/en/innodb-row-format.html |
66
wupher 2021-04-15 20:58:21 +08:00
同意 @makdon 的意见。
过早优化常常会带来其它的问题。除非这是张大表,有复杂的索引等等。 从设计本身角度,更推荐该空即空。 此外变更前与同事取得一致也是一种尊重。 但是,汉语拼音不能忍……估计我看到也会很难受。 |
67
xuanbg 2021-04-15 21:25:50 +08:00 4
null 都给改成非 null,然后给个默认值?换我也要破口大骂。我一个数值 null 表示无,你给我来个什么默认值? 0 还是-1 ?我告诉你,无论是 0 还是负数,在业务里面都是合法且正常的值。你给我把 null 搞成 0,实际上数据就被你破坏掉了,而且无法恢复。你说要不要骂你?
|
68
ReysC 2021-04-15 21:35:54 +08:00
如果是后端来和你讨论用不用 NULL,没啥问题,只是小公司没任何文档和说明就让你开始,他们的问题;
如果是前端和你讨论要不要用 NULL,建议立即跑路,估计这公司 CTO 都换了 N 个。 |
69
domodomo 2021-04-15 22:24:32 +08:00
还不赶紧换一家,作坊式的开发公司别呆太久
|
70
GGGG430 2021-04-15 22:36:14 +08:00
@wakzz 上一个回答说 char, 这个回答说 var char, 你在说啥呢, 知道"例如 varchar 等变长字段,都需要一个字符长度值来让程序知道该变长字段的字节长度"这就是看过 innodb 底层文件结构? 哪个版本的底层文件? 这和底层文件结构有啥关系, 你这不就是搜的八股文吗? 需要我给你加上 var char 的其他八股文吗, 比如 var char 还会保留末尾空格什么的吗
|
71
ajaxfunction 2021-04-15 22:36:56 +08:00
如果人家程序里有很多 sql 是 is null 或 not null ,你这一改,不就导致系统奔溃了吗?
无论代码质量咋样,起码目前已经是在跑业务的,你这一改就是人为制造 BUG 。 |
72
h82258652 2021-04-15 22:37:43 +08:00
虽然楼主改表字段为非 null 确实是不妥当,但是楼主描述的其它问题更严重,没有项目文档,全是口头沟通。
我以前就碰过一家,同一个需求,每次对方说都不一样的。这些东西应该形成文档固定下来的。 |
73
ihipop 2021-04-15 22:39:36 +08:00 via Android
是否允许 null 也应该看业务需求 /数据库特性而定,,null 和非 null 的默认值的业务区别一般也是是有的,一般引擎 null 也只是不参与索引,不影响非 null 索引。
|
74
wakzz 2021-04-15 22:46:36 +08:00
@GGGG430 基于的版本是 MySQL5.7 的 innodb,数据落盘后的 idb 文件。毫无实际应用价值的知识才是八股文,上面说 char 那是打快了
|
75
GGGG430 2021-04-15 22:54:53 +08:00
@wakzz 反手就是一句打快了? 算了看了很多层的回答, 都是跟着感觉走, 我行我素, 以遵守规范为耻, 真是服了, 我猜很多层都不知道 b+树是什么东西, 就在这根据自己的野路子经验乱回答
|
76
wakzz 2021-04-15 23:06:09 +08:00
@GGGG430 不是,建议你别把别人当傻子。网上非实名制所以吧友们想到啥说啥,论点碰撞什么的日常情况了,但这年头出来混的谁没有点东西,你猜很多层不知道 b+树就离谱了。。。笑
|
77
billlee 2021-04-15 23:11:34 +08:00
不要什么都不想就禁用 NULL. 有些字段就没有合适的值来表示空值,比如用 32 位整数存 IPv4 地址,那么显然每个数值都是有意义的,显然不能用 -1 或者 0 来做空值。
影响索引也不知道是哪来的以讹传讹的说法 |
78
MengiNo 2021-04-15 23:50:13 +08:00
如果 mysql 做了几十年连 null 都要用所谓的 “规范” ban 掉的话。哪里还要去考虑什么技术、底层、原理、实现,作为一个自然人最直观的印象和感觉难道不是,要么 mysql 项目组就应该当场解散、作者出来谢罪,要么他们立刻马上连夜光速出一个 patch 把 nullable 拿掉。既然这两种情况一直都没有发生,那么至少 mysql 官方对自己的 nullable 做的还挺满意的,那既然这个 feature 没有问题,有什么不用的理由。
|
79
littlewing 2021-04-16 00:03:06 +08:00 1
线上数据库是你能随便动的?动之前都不打个招呼!
有时候你觉得是错的东西,或者说确实是错的,但人家写代码已经将错就错了,你一改,影响到下游多少调用方你知道吗? |
81
msg7086 2021-04-16 01:04:04 +08:00
NULL 有 NULL 的用处,空值就空值的用处,本来就是不能随便替换的。
至于你遇到的问题,这我也不太好说,但是数据库结构更改还是要做 Code review 的吧。 Review 的时候说清楚就行了。被骂不应该。 |
82
fuermosi777 2021-04-16 01:04:46 +08:00
@wuyazuofeiji 同意 20 楼的意见。
|
83
msg7086 2021-04-16 01:05:11 +08:00
为避免歧义:上述空值指的是空白的默认值,比如空字符串,数字 0 等。
|
84
stabc 2021-04-16 01:33:22 +08:00
问题不是改不改默认值,而是你有没有事先和团队沟通。
|
85
iseki 2021-04-16 07:28:41 +08:00 via Android
数据库给你留了 null 这个功能就是拿来用的,不能不分青红皂白一律 not null 也不能全都 null
|
86
JerryV2 2021-04-16 08:12:46 +08:00 1
别手欠,你觉得需要修改也得找负责人沟通好再改,自己直接改了这不找骂么
|
87
2379920898 2021-04-16 08:48:48 +08:00
被骂是怎么嘛?我是接受不了。大家好歹都是大学毕业
|
88
2379920898 2021-04-16 08:50:02 +08:00
他判断 not null 出错。。应该和你去沟通啊? 为什么会被骂呢??你们沟通就是挨骂?? 那以后业务问题,不更得挨骂了。赶紧跑路吧。。好的上司也很重要。这垃圾上司不要也罢
|
89
penll 2021-04-16 09:03:20 +08:00
为了省这点空间,还不如不要。
当统一数据库设计不为 null 的规范后,可以给开发人员方便许多 |
90
dongtingyue 2021-04-16 09:08:29 +08:00
半桶水晃荡的典型例子,吸取经验不要不讨论就做会影响别的决定。
|
91
RangerWolf 2021-04-16 09:27:52 +08:00
自作孽
|
92
Narcissu5 2021-04-16 09:33:30 +08:00
|
93
jinhan13789991 2021-04-16 09:47:40 +08:00
我们都是前端做输入校验,出了问题后台都怪我们前端,谁让他是领导呢。
就当是磨练自己了 |
94
lsdvincent 2021-04-16 09:52:45 +08:00
我以前也是全部不允许为 null 必须要有默认值,空字符串也行,但是这样验证就很麻烦,字段变化大,很蛋疼,后来不确定的东西全部允许 null,好极了
|
95
tairan2006 2021-04-16 09:56:46 +08:00
null 对性能其实没啥影响,null 主要是有坑
楼主你的问题在于没和别人讨论就改已有的东西,这样不太好 |
96
Actrace 2021-04-16 09:58:10 +08:00
@tairan2006 赞同,看来楼主还不适应团队开发。需要多多磨合。
|
97
no1xsyzy 2021-04-16 10:17:43 +08:00
NULL 和 NOT NULL 不是拿来表示字段的必须性的吗?
咋还跟性能扯上了? 段子: > 文艺程序员尝试把代码写得别人看起来方便,普通程序员尝试把代码写得自己看起来方便,二逼程序员尝试把代码写得机器看起来方便。 > 半年以后,文艺程序员看自己代码,看不出是自己写的,但看得懂;普通程序员看自己代码,看得出是自己写的,但看不懂;二逼程序员看自己代码看了半天,破口大骂 “这是哪个 XX 写的代码?”。 |
98
AhogeK OP @tairan2006 是的,这点昨天也有跟同事沟通。坑有,因为现在代码上直接拿数据库实体类让前端传,而前端没有统一规范,有的人也许没传 后端保存了 null 也许又传了''(意思一样却数据类型不同) 这时后台这写 sql count 不注意 null 数据就会有问题,类似还有拿 null 直接 = <> 查询的 至于说我没大家想的那么重,就说数据库不要去校验不为 null 让前端去判断(这点我挺疑惑的),不要加 not null 这个东西,不要改固定的字段名,就让我有意见先提,以后一定注意 前一家公司的数据库编写习惯确实影响了自己,不知道这家呆久了也会不会同化,现在任务也不重,还能抽空写自己的项目
|
99
lusi1990 2021-04-16 10:28:28 +08:00
改没问题,提前沟通好了
|
100
AhogeK OP |