mysql 表设计规范讨论

2021-06-10 10:30:12 +08:00
 brader
CREATE TABLE `test` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int NOT NULL DEFAULT 0,
  `name` varchar(255) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  UNIQUE KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

有这样一张表,我知道的设计表规范其中一条就是字段尽量不要设为 null 。

现在这个表业务背景是这样的,会先录入数据,但是没有 user_id,user_id 是后续更新进去的,但是要保证 user_id 是唯一的。

如果不设置 user_id 为 null 的话,user_id 是没办法弄唯一键的。

那么这种背景下,有没有必要打破表设计规范约束?

我的想法:本场景可以打破字段不为 Null 的约束,把 user_id 设为 Null,这样从数据库层面设置唯一键,不仅安全,而且业务层,也能少一次查询,数据是否唯一。 我觉得规范不是绝对的,就好像我们某些表多几个字段做数据冗余,不也是打破三范式的吗?

你们的看法呢?

3818 次点击
所在节点    MySQL
36 条回复
lyusantu
2021-06-10 10:31:32 +08:00
规矩是人定的
cyril4free
2021-06-10 10:34:40 +08:00
单论 user_id 这个感觉可以代码层面做保证,不依赖数据库的唯一索引
T0m008
2021-06-10 10:36:45 +08:00
你知道为什么尽量不要设为 null 吗?如果知道了可能你也有答案了
devinww
2021-06-10 10:40:29 +08:00
业务需求多种多样,所以有的时候不会完全按照规范。
另外,尽量不要让数据库抛出异常,而在程序里就处理了。
ericls
2021-06-10 10:42:43 +08:00
解决什么问题
你有没有遇到同样的问题
DinnyXu
2021-06-10 10:44:35 +08:00
一个表设置 2 个唯一字段,你这不是多余么, 你 id 都是自增唯一的了,为什么 user_id 也要求唯一
SuperXRay
2021-06-10 10:55:03 +08:00
@DinnyXu user_id 在该表中不允许重复,这种需求不是很正常

@brader 可以再挂一张表,user_id 放到那张表上。
SuperXRay
2021-06-10 10:56:12 +08:00
@brader 不要设唯一索引,程序判段是否重复,略过 Null
fatcube404
2021-06-10 10:58:32 +08:00
同意 DinnyXu 的说法
我建议 直接拿 user_id 做主键 自增 唯一 not null unsigned
查询就直接用这个为 where 条件 这不更能减少开销
limuyan44
2021-06-10 11:28:36 +08:00
字段不能设为 null,mysql 闲的搞个 null 出来,符合业务就行,哪有那么多硬要求。
DinnyXu
2021-06-10 11:35:29 +08:00
@SuperXRay 从你发表这个问题的时候就已经进入一个误区了,你说你的需求是 user_id 必须要唯一,然后你又说唯一的话不能为 null,很明显只有你勾选了该字段为主键,那么才会设定该字段不能为 null,一个表是可以有多个主键的,但是你能设置的主键就一个,其余的字段我们自己称之为主键,实质上也就是不重复而已,如果不重复的话,何必要采用 MySQL 的主键策略呢,可以通过代码层面去 set user_id 为 UUID,或者分布式 id,不也是达到了唯一的效果吗
xiaomingVTEX
2021-06-10 11:43:25 +08:00
直接默认插入一个 UUID 可以吗
xiaomingVTEX
2021-06-10 11:45:04 +08:00
后续更新的时候再更新为新的 user_id,如果有需要识别新录入的数据,加个状态字段
brader
2021-06-10 11:47:23 +08:00
@SuperXRay 那这样做的话,其实会多出一次查询,意思就是,这个场景下,多一次查询是值得的?
saulshao
2021-06-10 11:49:33 +08:00
是否允许为空是一个约束,不是所有的情况都不允许为空的,一般说的是尽量。
具体到你这个例子,最简单的办法显然就是允许为空就好。
liuhuansir
2021-06-10 12:39:02 +08:00
设计规范是尽量遵守,否则太教条了吧
xuanbg
2021-06-10 12:50:12 +08:00
为啥不能为空?你创建记录时没有的数据怎么就能够不为空?别理会那些破规则,该怎样就怎样。
leonme
2021-06-10 12:52:54 +08:00
@T0m008 可以简单说一说
raaaaaar
2021-06-10 13:00:13 +08:00
@xuanbg 不是不要理这“破规则”,“破规则”提出来有人遵守肯定有道理的,问题是你知不知道这个东西背后的原理是什么,为什么大家要这么做
Dragonphy
2021-06-10 13:05:32 +08:00
如果用户和密码都相同咋分辨用户,如果用户名唯一,这不是和 user_id 作用重复了吗,还是因为 user_id 做索引效率更好?

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

https://www.v2ex.com/t/782576

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

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

© 2021 V2EX