V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
kindjeff
V2EX  ›  MySQL

数据库设计一定要满足第一范式吗?满足第一范式的好处是什么?

  •  
  •   kindjeff ·
    sljeff · 2016-06-28 10:02:38 +08:00 · 8528 次点击
    这是一个创建于 3078 天前的主题,其中的信息可能已经有所发展或是发生改变。

    不满足第一范式的例子:

    比如我的课程设计“学生成绩管理系统”里,学生的成绩没有单独作为一张表,而是作为一个字段储存在学生表里,这个字段是一个 json 字符串(保存所有的 科目( key ):成绩( value ),是多个值,不满足第一范式)。

    我认为这样查询很方便,学生只需要一次性取到自己的所有成绩,管理员也只需要一次性查到一个班级所有人的所有成绩作为一张列表;修改和录入成绩相对于查询来说是很少量的操作,做一些 json 的 decode 和 encode 也不是很费功夫。

    那么这个时候满足第一范式的好处是什么呢?

    34 条回复    2016-06-29 09:01:25 +08:00
    jarlyyn
        1
    jarlyyn  
       2016-06-28 10:04:50 +08:00
    管理员要查询所有不及格学生怎么办。
    robertlyc
        2
    robertlyc  
       2016-06-28 10:05:22 +08:00
    you just need NoSQL
    kindjeff
        3
    kindjeff  
    OP
       2016-06-28 10:06:33 +08:00
    @jarlyyn 查完了在前端筛选……我想的是学生查询自己的成绩是最大量的操作,那么这个结构会比较方便
    qiayue
        4
    qiayue  
       2016-06-28 10:07:35 +08:00
    同一楼,很多查询你做不到,比如查询所有只挂了一科的人
    stcasshern
        5
    stcasshern  
       2016-06-28 10:08:04 +08:00
    用 nosql 吧
    qiayue
        6
    qiayue  
       2016-06-28 10:08:46 +08:00
    几十个学生你这样做没问题,几千个几万个学生呢?也是一次性把所有数据都查出来?
    jarlyyn
        7
    jarlyyn  
       2016-06-28 10:09:42 +08:00   ❤️ 2
    @kindjeff

    方便在哪?

    如果有 5w 条数据,也是差完了再在前端筛选?

    再比如要联合查询呢?

    如果不考虑数据量很大,直接做个一个 json,前台修改不久得了。

    的确有很多需求会把数据存为 json 压在数据库里,但我觉得不是你这样用的。
    tomczhen
        8
    tomczhen  
       2016-06-28 10:10:18 +08:00
    OLTP 数据库下遵循范式有很多好处的,毕竟都是经过时间沉淀和总结的, OLAP 数据库就不一定了。
    写入上来说,遵循范式的写入量是最少的,并且查询粒度很小的情况下,响应速度也是完全可以保障的。
    但是在用于分析的数据库下,做 join 查询是需要消耗很多计算性能的,违反范式可以用空间换取时间。

    另外,数据库如果支持直接存储 jsnon 对象, 1 楼说的需求也是能做的。
    domty
        9
    domty  
       2016-06-28 10:12:12 +08:00
    json 数据在关系数据库里更适合读写,不适合查询。
    好处就是同一个字段存储的 json 对于序列化的数据结构没一致要求。

    最简单的就是只保留主键编号和序列化后的数据内容,这就是比较典型的 nosql 存储方法了。
    kindjeff
        10
    kindjeff  
    OP
       2016-06-28 10:12:15 +08:00
    @qiayue 了解了。但是通常情况是小范围的,比如取出**一个班**所有语文不及格的学生。
    iyaozhen
        11
    iyaozhen  
       2016-06-28 10:17:48 +08:00 via Android   ❤️ 1
    小数据量怎么搞都可以。数据量打了还是按照标准来的好
    starcraft
        12
    starcraft  
       2016-06-28 10:18:53 +08:00 via iPhone
    你这是看书不看关系数据理论的节奏?
    kindjeff
        13
    kindjeff  
    OP
       2016-06-28 10:20:53 +08:00
    @starcraft 做之前确实没看过,今天看书发现了这些东西就来问了。
    techme
        14
    techme  
       2016-06-28 10:29:58 +08:00
    要是完成作业的话,那就没问题
    mcone
        15
    mcone  
       2016-06-28 10:31:45 +08:00
    说句实在话,如果你是科班的,只能说读书太少想得太多,书上的例子应该已经够了 (我们当时用的是那本英文砖头书,很多学校都用的那个)

    如果你只是自己刚好用到这个了,那就不用在意这个了,小数据,或者玩具程序,怎么弄都行,前端处理也完全来得及;大数据的话,那就按照公司规范来吧,能用到这么多数据的公司,这种规范早就成型了
    lzhd24
        16
    lzhd24  
       2016-06-28 10:32:11 +08:00 via Android   ❤️ 1
    关系数据库必须满足第一范式。
    1NF 第一范式可以理解为一张二维表,因为字段不可再分
    kindjeff
        17
    kindjeff  
    OP
       2016-06-28 10:32:34 +08:00
    @techme 看了大家的回复我决定还是改一下……虽然明天就要交
    lzhd24
        18
    lzhd24  
       2016-06-28 10:33:09 +08:00 via Android   ❤️ 1
    数据库的范式可以理解为表结构的优化程度吧
    kindjeff
        19
    kindjeff  
    OP
       2016-06-28 10:34:28 +08:00
    @mcone 被说中了,是读书太少,今天第一次看,没买课本,照着目录查的维基
    mcone
        20
    mcone  
       2016-06-28 10:35:43 +08:00   ❤️ 1
    @kindjeff 别看维基,课本真的是最全的,即使教材很差,也很可能比维基强

    Ps ,如果非得参考维基百科的话,请看英文版,这种词条的英文版往往比中文详细得多得多
    helloSwift
        21
    helloSwift  
       2016-06-28 10:38:35 +08:00 via iPhone
    满足第一范式是基本要求,
    gyteng
        22
    gyteng  
       2016-06-28 10:40:40 +08:00
    按楼主的说法,出成绩前如何查询学生人数?
    yueyoum
        23
    yueyoum  
       2016-06-28 10:44:20 +08:00   ❤️ 1
    @mcone LZ 不是 书读的少,想的太多, 而是 想的也太少。

    随便举个几个例子, LZ 就知道 为啥要 分开存储了。

    1 , 查询所有 选修了 A 课程,并且成绩在 80 分以上的
    2 , 查询 高数,大物,英语总分在 300 以上的
    3 , 查询 所有科目全部 挂科的
    ... ...

    例子太多, 不再举例了


    按照范式设计, 才能利用 数据库给你提供的各种功能。

    还有, 上面还有人说要 NOSQL , NOSQL 也不是这么用的。


    比如 客户端程序员看了下 mysql 和 mongodb 后,说 mongodb 真好, 符合 OO 思想, 把所有东西全部放在一起。

    像 LZ 这样的数据库新手 一般都有 这样的想法。



    做到后面 你才发现, 范式 只是一个指导
    具体情况具体分析, 到底哪里要范式, 哪里要 抛弃范式。

    LZ 多做几个大项目就明白了。
    wdrsam
        24
    wdrsam  
       2016-06-28 10:52:36 +08:00   ❤️ 1
    感觉开发做多了,建数据库的时候直接写出来就自带第一范式的 buff 。。。
    felixglow
        25
    felixglow  
       2016-06-28 10:54:53 +08:00
    没听过反范式吗,过于范式是不行的,根据场景,适时的结合起来用。
    slixurd
        26
    slixurd  
       2016-06-28 11:09:51 +08:00
    同楼上,真的做业务开发没见过多少遵守范式的。
    大量冗余都是为了提高性能
    不然是不是该把外键也加上,还有 view , procedure
    wsxyeah
        27
    wsxyeah  
       2016-06-28 11:54:52 +08:00
    正巧课设也是做成绩管理,不过不用考虑课程多次开课等问题。

    要求是 一个学生在一门课下的成绩 分为多个部分,且不同部分的成绩按一定权重决定总成绩,
    主要分了四张表:学生,课程,选课,成绩
    为方便查询,为「选课」表增加了一个「总成绩」字段,更新成绩时计算并更新该字段
    WhoMercy
        28
    WhoMercy  
       2016-06-28 12:24:03 +08:00 via Android
    第一范式只是最基本要求
    hantsy
        29
    hantsy  
       2016-06-28 12:34:27 +08:00
    过于在于范式会导致数据库的设计与程序设计上的矛盾,比如, Hibernate 中的继承支持,必须打破范式。
    cjyang1128
        30
    cjyang1128  
       2016-06-28 13:11:28 +08:00
    一直觉得数据库设计是哲学问题
    changwei
        31
    changwei  
       2016-06-28 16:03:01 +08:00
    首先,不满足第一范式,连目前的关系数据库都无法存储你这种格式的数据,其次,用了第一范式,查询就会很灵活,而不是每次几个数据捆绑在一起查
    HypoChen
        32
    HypoChen  
       2016-06-28 22:43:20 +08:00
    @kindjeff 能让数据库实现的逻辑就别自己写,比如取总成绩前 n 名的学生,比你自己把表全跑出来再排序不知性能好多少,还有更强的鲁棒性。类似的情况还很多。
    sundev
        33
    sundev  
       2016-06-28 22:52:56 +08:00
    你可以 google 一下:反范式设计
    darasion
        34
    darasion  
       2016-06-29 09:01:25 +08:00
    范式是用来解决一般的通用的问题的。一开始可以先按照范式来做,这样能解决大多数问题;
    当出现比较特殊的问题时,再考虑用特殊的办法解决,而特殊办法很可能就是反范式的,因为有问题驱动,反什么都无所谓了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2395 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 02:02 · PVG 10:02 · LAX 18:02 · JFK 21:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.