不满足第一范式的例子:
比如我的课程设计“学生成绩管理系统”里,学生的成绩没有单独作为一张表,而是作为一个字段储存在学生表里,这个字段是一个 json 字符串(保存所有的 科目( key ):成绩( value ),是多个值,不满足第一范式)。
我认为这样查询很方便,学生只需要一次性取到自己的所有成绩,管理员也只需要一次性查到一个班级所有人的所有成绩作为一张列表;修改和录入成绩相对于查询来说是很少量的操作,做一些 json 的 decode 和 encode 也不是很费功夫。
那么这个时候满足第一范式的好处是什么呢?
![]() | 1 jarlyyn 2016-06-28 10:04:50 +08:00 管理员要查询所有不及格学生怎么办。 |
2 robertlyc 2016-06-28 10:05:22 +08:00 you just need NoSQL |
![]() | 4 qiayue PRO 同一楼,很多查询你做不到,比如查询所有只挂了一科的人 |
![]() | 5 stcasshern 2016-06-28 10:08:04 +08:00 用 nosql 吧 |
![]() | 6 qiayue PRO 几十个学生你这样做没问题,几千个几万个学生呢?也是一次性把所有数据都查出来? |
![]() | 7 jarlyyn 2016-06-28 10:09:42 +08:00 ![]() @kindjeff 方便在哪? 如果有 5w 条数据,也是差完了再在前端筛选? 再比如要联合查询呢? 如果不考虑数据量很大,直接做个一个 json,前台修改不久得了。 的确有很多需求会把数据存为 json 压在数据库里,但我觉得不是你这样用的。 |
![]() | 8 tomczhen 2016-06-28 10:10:18 +08:00 OLTP 数据库下遵循范式有很多好处的,毕竟都是经过时间沉淀和总结的, OLAP 数据库就不一定了。 写入上来说,遵循范式的写入量是最少的,并且查询粒度很小的情况下,响应速度也是完全可以保障的。 但是在用于分析的数据库下,做 join 查询是需要消耗很多计算性能的,违反范式可以用空间换取时间。 另外,数据库如果支持直接存储 jsnon 对象, 1 楼说的需求也是能做的。 |
![]() | 9 json 数据在关系数据库里更适合读写,不适合查询。 好处就是同一个字段存储的 json 对于序列化的数据结构没一致要求。 最简单的就是只保留主键编号和序列化后的数据内容,这就是比较典型的 nosql 存储方法了。 |
![]() | 11 iyaozhen 2016-06-28 10:17:48 +08:00 via Android ![]() 小数据量怎么搞都可以。数据量打了还是按照标准来的好 |
![]() | 12 starcraft 2016-06-28 10:18:53 +08:00 via iPhone 你这是看书不看关系数据理论的节奏? |
![]() | 14 techme 2016-06-28 10:29:58 +08:00 要是完成作业的话,那就没问题 |
![]() | 15 mcone 2016-06-28 10:31:45 +08:00 说句实在话,如果你是科班的,只能说读书太少想得太多,书上的例子应该已经够了 (我们当时用的是那本英文砖头书,很多学校都用的那个) 如果你只是自己刚好用到这个了,那就不用在意这个了,小数据,或者玩具程序,怎么弄都行,前端处理也完全来得及;大数据的话,那就按照公司规范来吧,能用到这么多数据的公司,这种规范早就成型了 |
16 lzhd24 2016-06-28 10:32:11 +08:00 via Android ![]() 关系数据库必须满足第一范式。 1NF 第一范式可以理解为一张二维表,因为字段不可再分 |
18 lzhd24 2016-06-28 10:33:09 +08:00 via Android ![]() 数据库的范式可以理解为表结构的优化程度吧 |
![]() | 20 mcone 2016-06-28 10:35:43 +08:00 ![]() |
![]() | 21 helloSwift 2016-06-28 10:38:35 +08:00 via iPhone 满足第一范式是基本要求, |
![]() | 22 gyteng 2016-06-28 10:40:40 +08:00 按楼主的说法,出成绩前如何查询学生人数? |
![]() | 23 yueyoum 2016-06-28 10:44:20 +08:00 ![]() @mcone LZ 不是 书读的少,想的太多, 而是 想的也太少。 随便举个几个例子, LZ 就知道 为啥要 分开存储了。 1 , 查询所有 选修了 A 课程,并且成绩在 80 分以上的 2 , 查询 高数,大物,英语总分在 300 以上的 3 , 查询 所有科目全部 挂科的 ... ... 例子太多, 不再举例了 照范式设计, 才能利用 数据库给你提供的各种功能。 还有, 上面还有人说要 NOSQL , NOSQL 也不是这么用的。 比如 客户端程序员看了下 mysql 和 mongodb 后,说 mongodb 真好, 符合 OO 思想, 把所有东西全部放在一起。 像 LZ 这样的数据库新手 一般都有 这样的想法。 做到后面 你才发现, 范式 只是一个指导 具体情况具体分析, 到底哪里要范式, 哪里要 抛弃范式。 LZ 多做几个大项目就明白了。 |
24 wdrsam 2016-06-28 10:52:36 +08:00 ![]() 感觉开发做多了,建数据库的时候直接写出来就自带第一范式的 buff 。。。 |
25 felixglow 2016-06-28 10:54:53 +08:00 没听过反范式吗,过于范式是不行的,根据场景,适时的结合起来用。 |
![]() | 26 slixurd 2016-06-28 11:09:51 +08:00 同楼上,真的做业务开发没见过多少遵守范式的。 大量冗余都是为了提高性能 不然是不是该把外键也加上,还有 view , procedure |
![]() | 27 wsxyeah 2016-06-28 11:54:52 +08:00 正巧课设也是做成绩管理,不过不用考虑课程多次开课等问题。 要求是 一个学生在一门课下的成绩 分为多个部分,且不同部分的成绩按一定权重决定总成绩, 主要分了四张表:学生,课程,选课,成绩 为方便查询,为「选课」表增加了一个「总成绩」字段,更新成绩时计算并更新该字段 |
28 WhoMercy 2016-06-28 12:24:03 +08:00 via Android 第一范式只是最基本要求 |
29 hantsy 2016-06-28 12:34:27 +08:00 过于在于范式会导致数据库的设计与程序设计上的矛盾,比如, Hibernate 中的继承支持,必须打破范式。 |
![]() | 30 cjyang1128 2016-06-28 13:11:28 +08:00 一直觉得数据库设计是哲学问题 |
![]() | 31 changwei 2016-06-28 16:03:01 +08:00 首先,不满足第一范式,连目前的关系数据库都无法存储你这种格式的数据,其次,用了第一范式,查询就会很灵活,而不是每次几个数据捆绑在一起查 |
![]() | 32 HypoChen 2016-06-28 22:43:20 +08:00 @kindjeff 能让数据库实现的逻辑就别自己写,比如取总成绩前 n 名的学生,比你自己把表全跑出来再排序不知性能好多少,还有更强的鲁棒性。类似的情况还很多。 |
33 sundev 2016-06-28 22:52:56 +08:00 你可以 google 一下:反范式设计 |
![]() | 34 darasion 2016-06-29 09:01:25 +08:00 范式是用来解决一般的通用的问题的。一开始可以先按照范式来做,这样能解决大多数问题; 当出现比较特殊的问题时,再考虑用特殊的办法解决,而特殊办法很可能就是反范式的,因为有问题驱动,反什么都无所谓了。 |