第一范式( 1NF )要求数据库表中的每个列都是不可再分的原子值,即每个列都不能包含多个值或值的列表。
现在使用 pg 的时候经常用 json 格式了,是不是违反了第一范式?
第一范式( 1NF )要求数据库表中的每个列都是不可再分的原子值,即每个列都不能包含多个值或值的列表。
现在使用 pg 的时候经常用 json 格式了,是不是违反了第一范式?
1
fingerxie May 22
我也要软考了,我还一天没学 😭
|
2
aes114514gcm May 22
注意适用范围
pg 的定位是(Object-Relational Database Management System, ORDBMS) 不是纯粹的关系型数据库 |
3
dushixiang OP @fingerxie 明天别去受罪了,在家睡觉吧
|
4
dushixiang OP @aes114514gcm mysql/sqlite 也有 json 格式的
|
5
happyhou May 22
是的,违反了 1NF 。
|
6
Bigstupidcat May 22 没事,考了也没啥用,除了进了个人才库,屁用没有,有这精力,准备准备考公吧
|
7
Aethyr May 22
json 格式看场景
互联网中第三范式才是人均不遵守 |
8
momocraft May 22
这是没人会 100%遵守的理论规则 比如用这个范式怎么存储地址
|
9
Rickkkkkkk May 22
这种东西比接口的 RESTful 规范还没用一点
感觉会把这种东西不断传播作为正确的人都是从来没有长期开发过任何一个复杂的商业系统。 统一认定为没真正上过班 |
10
adoal May 22
你都用 JSON 了,还想什么范不范式的
|
11
foxhunt May 22
你最好想想为什么违背范式,能带来哪些好处
明天要考 |
12
beautyplus May 22
json 就是原子值,如果你存的 json 都是同字段的,那确实违反了,应该拆成原子
|
13
cowcomic May 22 是的,现在很多系统数据库的设计都是反范式的
三范式并不是一定要遵守,只是遵守但是能够帮你避免一些问题,但是可能会降低查询效率之类的 可以根据自己的需求来打破范式,但每打破一个范式,就要增加对应的处理方案,避免引入新的问题,比如数据结构教研,数据同步更新等等 |
14
huangsijun17 May 22
@aes114514gcm #2 但是,MySQL 存 JSON 的场景也不少了。是个 SQL ,甚至 NoSQL ,只要能存长字符串的,都会有人存 JSON 。
|
15
zhuangzhuang1988 May 22
pg 还有 array
|
16
airqj May 22
居然有人说数据库范式没啥用
PS: 1981 的图灵奖就是颁发给研究数据库的,而数据库范式是其中很重要的一部分 |
17
TataJiang May 22
三范式并不是不能违反的
|
18
catning May 22
范式没有万能的,具体还要根据你自己业务和上下游去决定。
但是你不能不学,不能不了解这些范式是为了解决什么问题产生的。试想一下,一张表里只有 id 和 data 俩字段,做业务时候一把 data select 出来,然后在程序中用代码逻辑组织数据结构或者进行过滤,光想想就灾难。 |
20
shiny PRO 先懂得规则,然后才能知道何时打破规则,代价是什么,收益是什么
|
21
xxyzf May 22
是不是应该有个约束条件:在多大程度上是原子的,这就取决于业务需求了。
|
22
shyrock2026 May 22
范式是思维模型,依据模型你就能知道你的设计如何取舍:应用便利、性能、扩展性等等。
没人说按照范式执行一定更好,都是权衡和取舍。 |
23
chendy May 22
三范式属于用了不会错,但是不一定好
反范式一定是是有什么好处,但是可能会犯错,特别是为了偷懒反范式 只能说具体情况具体分析 |
24
dandel1on May 22
纸上谈兵不代表兵法书籍是无用的
|
25
killva4624 May 22
|
26
piecezzz May 22
实践和理论不冲突啊
|
27
adoal May 22
@huangsijun17 当长字符串存跟用原生 JSON 支持是两码事。后者可以直接对 JSON 内容做检索和解析。
|
28
fredweili May 22
你在说啥,考试该怎么复习准备?
|
29
dacapoday May 22
现代数据库 json 列提供了按 json path 更新值,甚至按 json path 索引,把 json 列当 join 表,其中的每个 json path 当作真正的列值就行了。
如果用字符串类型的列,强行存 json 序列化值,而不提供局部更新能力,才是违反范式。 |
30
526326991 May 22
原则 > 范式 = 风格
|
31
leoJiu May 22
钱都交了,明天去裸考了,我是一道题都没刷
|
32
dushixiang OP @dacapoday 有道理,但是 json 作为字段通常都是全部覆盖更新这个字段的吧(数据库层面),需要存储 json 字段的通常是一些配置项
|
34
dacapoday May 22
@dushixiang 这是一种场景,而且该场景下,该列不参与索引和进入过滤条件,也就是非关系的 blob 附件,那自然也不受范式约束了。
|
35
635925926 May 22
@Bigstupidcat 补贴了解下
|
36
hongye May 22
@Rickkkkkkk
这种看法片面了,也低估了范式与 REST 规范在复杂商业系统里的底层价值。 数据库三范式从来不是死板教条,而是帮开发者规避数据冗余、更新异常、删除错乱的基础设计准则,真正长期做商业系统的人都清楚,前期不守范式,后期多表联查、数据同步、业务迭代、对账统计都会频繁出隐性 BUG ,维护成本会成倍飙升。 RESTful 也同理,规范统一的接口设计,能降低跨团队协作、前后端对接、服务拆分重构的沟通损耗。 规范本身不是束缚,而是工业级开发的通用共识,只会觉得规范无用,大概率只做过小体量单体项目,没经历过业务膨胀、数据迭代、多人协作、系统拆分的真实场景,自然体会不到底层规范规避风险、降本增效的实际作用。 |
37
luoshuimumu May 22
后天考,明儿还能突击一天
|
38
Rickkkkkkk May 22
|
39
FlashEcho May 22
因为业务需求或者性能考虑不遵守某些范式很正常,可以看下 DDIA 相关章节: https://ddia.vonng.com/ch3/#sec_datamodels_normalization
|
40
BeiChuanAlex May 22
|
41
shellj May 22
突然想起来我也报名了,一点没学
|
42
hongye May 22
@Rickkkkkkk #38 恰巧我在交易中心工作过一段时间,应该是比较核心的系统了。方案评审的审核还是很关注库表设计的,DBA 会耳提面命的。
|
43
wysnxzm May 22
RESTFul JWT 中台 DDD 数据库三范式 有勇士凑齐了吗
|
44
Rickkkkkkk May 22
@hongye 当然会注重 db 字段的设计,接口的设计也会考虑。
我的意思是,但这里并不会去通过范式、restful 这种规范来考虑。你会有印象在讨论设计合理性上,有人提过 db 范式吗?说实话我工作这么多年,几个大厂也呆过,从来没听过。 |
45
ntedshen May 22
说到底远古时期算力和 io 都严重不足,只有遵守范式你这个系统才不会三天两头卡出屎,没有其他路可以走。。。
现在这年头处理器核心数跟个不要钱一样,存储的 io 和容量起码都翻了几万倍。。。 时代变了,现在遵守这东西和进机房要穿鞋套有啥两样。。。 真要考究到这些,那你也不会问这个了 |
46
Plutooo May 22
不是过时了,是还有个相应的概念叫“反范式”,但更多实践上来说大概率是二者都沾一点,从“没有银弹”的角度来说,软件工程还是符合国人的“折中”的习性的
|
47
garyalen May 22 via iPhone
没看题 去年差 3 分 今年再试
|
48
alading11 May 23
看到你这个帖子我才发现忘记报名了
|
49
frayesshi1 PRO 。。。。第一题就是这个
|
50
PopRain May 24
突然很忙,没有时间突击,准考证都没有打,贡献 190
|
51
ijustdo May 26
关键字: mysql ,json 类型,虚拟字段
CREATE TABLE user_profile ( id INT PRIMARY KEY AUTO_INCREMENT, info JSON NOT NULL, -- 原始 JSON 字段 -- 从 JSON 中提取字符串字段(虚拟列) username VARCHAR(50) GENERATED ALWAYS AS (info->>'$.username') VIRTUAL, -- 从 JSON 中提取数值字段(存储列) age INT GENERATED ALWAYS AS (JSON_UNQUOTE(JSON_EXTRACT(info, '$.age'))) STORED, -- 基于 JSON 数组的计算字段 hobby_count INT GENERATED ALWAYS AS (JSON_LENGTH(info->>'$.hobbies')) VIRTUAL ); -- 为虚拟字段创建普通索引 CREATE INDEX idx_username ON user_profile(username); -- 为存储字段创建唯一索引 CREATE UNIQUE INDEX idx_age_unique ON user_profile(age); INSERT INTO user_profile(info) VALUES ('{"username":"zhangsan", "age":25, "hobbies":["reading", "coding"]}'), ('{"username":"lisi", "age":30, "hobbies":["travel", "photography"]}') -- 直接查询虚拟字段,无需手动解析 JSON SELECT id, username, age, hobby_count FROM user_profile; -- 结合虚拟字段进行条件查询 SELECT * FROM user_profile WHERE age > 28; 神奇吧, 用了好几年乐,都用上瘾了, 上面的例子,大模型生成 |