22丨反范式设计:3NF有什么不足,为什么有时候需要反范式设计?
22丨反范式设计:3NF有什么不足,为什么有时候需要反范式设计?
讲述:陈旸
时长09:26大小8.65M
BCNF(巴斯范式)
反范式设计
实验数据:模拟两张百万量级的数据表
反范式优化实验对比
反范式存在的问题 & 适用场景
总结
赞 14
提建议
精选留言(26)
- DZ置顶2019-07-31一言以蔽之:反范式无处不在。😃 最近正在基于Hadoop建设某国企的数据集市项目(地域性非全网),恰如老师所言,我们就是在遵循反范式的设计。 简要来说,我们把数据加工链路分为四层,从下到上依次为:ODS贴源层、DWD明细层、DWS汇总层和ADS应用层。 多源异构的业务数据被源源不断ETL到ODS贴源层之后,经过清洗、规范、转换、拼接等,生成各类宽表存储在DWD明细层;再根据业务模型设计,以这些宽表为基础,生成各类标准的指标数据存储在DWS汇总层;ADS层则基于DWS层的汇总指标再度组合,计算得出应用层数据,直接面向业务需求。 在这样的系统设计中,反范式不仅体现在“宽表”的设计中,更体现在数据加工链路的完整生命周期中——上层都是对下层的冗余。展开
作者回复: 总结的不错
共 5 条评论48 - leslie2019-07-31个人对于反范式的理解是:它会造成数据的冗余甚至是表与表之间的冗余;不过它最大的好处是减少了许多跨表查询从而大幅减少了查询时间。早期的设计其实一直强调范式化设计,可是当memcache出现后-其实就反向在揭示范式的不足。 互联网行业和传统行业最大的区别是要求相应时间的短暂:这就造成了效率优先,这其实也是为何互联网行业的技术更新和使用走在最前面。曾经经历过设计表的过程中尽力追求范式,可是最终发现带来的问题就是性能的不足;范式其实就是规范,可是完完全全的规范-碰到特殊场景就不能那样使用。10年前接触到非关系型数据库时就引发了这种思考,sql server和mysql的机制和查询特长的不同更加引发了自己对于范式的反思。 其实不同数据库对于范式的操作应当是不同的不同行业对于效率的要求是不同的:我觉得范式与反范式的关系可能有点像现在关系型数据库和非关系型数据库的使用一样,已经不再是单一化,如何让二者合理结合最大发挥数据库的查询效率才是关键-只有最合适的没有最好的;当我们过度的追求标准化时反而会忽视了产品真实的功能者作用,如何充分合理发挥产品性能其实才是我们所追求的。 老师觉得呢:没有最标准的,任何方式都有缺陷,没有最好的只有最合适的;就像Google 的SRE中有句经典的话“没有问题的程序是程序的特殊状态”。展开
作者回复: 总结和阐述的很好,大家都可以看下 “没有问题的程序是程序的特殊状态” 这个赞一下
共 2 条评论53 - Yuhui2019-09-19这个数据集都是百万条记录的,如果直接导入MySQL比较慢。如果先做以下设置会大大提高导入的速度: SET GLOBAL unique_checks=0; SET GLOBAL innodb_flush_log_at_trx_commit=0; SET GLOBAL sync_binlog=0; 当然这不是SQL的问题,是数据库工作方式的问题,不在本课讨论范围内,只是提供大家参考,节省准备的时间。 导入完成以后记得把所有设置都改回1。展开
作者回复: 赞下Yuhui同学的分享
31 - 丁丁历险记2019-12-28反范式注意好同步。
作者回复: 同意
8 - 董俊俊2019-11-12请问老师,冗余字段的更新有哪些方式啊?文中只是提到存储过程更新冗余字段
作者回复: 使用触发器,存储过程,或者自己写脚本自动执行更新都可以
7 - 夜路破晓2019-07-31范式与反范式,正如传统与解构,规则与务实,稳定与突破,守成与创新,是阴阳动静的矛盾关系,两者一而二,二而一,即和而不同、求同存异,落脚点是务实,也就是应用场景和业务需求。 所以说,这已经不单是数据库设计的问题,而中国哲学体系在互联网商业中实践指导。 数据库设计提出范式的同时存在反范式的要求,符合否定之否定的螺旋上升轨迹,是数据库也是SQL语言保持强壮生命力而经久不衰的重要原因,是现实生存逻辑的映射。展开
作者回复: 是的,很多设计思维都是相通的。不仅是正反两方面,有时候我们还会遇到 Exploit & Explore的问题,这个在探索未知世界,比如深度学习的收敛算法中会应用。
6 - 川杰2019-08-01老师您好,想问个问题;假设我在存储过程中,用到了一个临时表(作用就是保存中间数据以便后续做其他操作),先对临时表进行数据删除操作,然后对临时表进行插入操作。假设现在有两个人A,B同时调用该存储过程,是否存在如下风险,即:A执行存储过程时,正在删除数据,同一时刻,B执行存储过程时,新增数据?
作者回复: 感谢提问,这种情况下会用到事务的隔离级别,MySQL的默认隔离级别是可重复读(Repeatable Read),数据同时删除,新增是不会有问题的。
共 3 条评论5 - 梁2019-11-18olap可以用反范式,但oltp就不适合了,实时的交易和数据变化,反范式的空间换时间不适合
作者回复: 反范式在OLAP场景比较常见
3 - Cookie1234562020-03-27“”“在这里,主属性是包含在任一候选键中的属性,也就是仓库名,管理员和物品名。非主属性是数量这个属性。” 老师你你说的这句话我有点问题,按理说我们如果默认仓库名和物品名是候选键的话,那管理员就是非主属性, 候选键的一部分,也就是说仓库名可以推导出管理员,这不就存在局部依赖么。
作者回复: 感谢提问,不包含在任何一个候选键中的属性称为非主属性,所以管理员还不能算是非主属性,而属于候选键。
2 - 博弈2020-03-25老师讲的浅显易懂,学完本章节,又重新温故了一下三范式。
作者回复: 哈哈 谢谢博弈同学
2 - grey9272019-11-08比如用户每次更改昵称的时候,都需要执行存储过程来更新,如果昵称更改频繁,会非常消耗系统资源。 > 其实不是不是不去同步更新昵称会比较好,就像微博的设计 ,当初我被人@的是A这个昵称,后续我改了昵称,变成了C,之前@A的这个链接就找不到我的信息了,这样是不是会好一点。
作者回复: 你说的有一定道理,这种链接的方式,如果不更新,对于原有链接依然有效(链接相当于ID的作用) 不过如果是名称的话,他确实已经发生了修改,这种情况下,如果不更新的话,名称就会产生错误
2 - 习惯沉淀2019-08-06MySQL8.0执行存储过程语句报错?[Err] 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 3
作者回复: 看下delimiter 是否定义了,如果是用的Navicat 可以不用定义
共 3 条评论2 - Demon.Lee2021-04-16“冗余字段的更新有哪些方式啊?文中只是提到存储过程更新冗余字段”。 老师的回复是:使用触发器,存储过程,或者自己写脚本自动执行更新都可以。 这个是从数据库层面给出的回答吧,我理解,平时的业务操作,针对冗余字段的更新,应该通过业务服务的更新接口来处理,否则数据库里面写很多触发器或存储过程,一方面给数据库带来压力,二是业务开发人员可能都不知道这些(主要负责代码开发,不涉及数据库维护),(当然,一个人维护的小项目或数据量很小,这么做也没啥问题),想听听老师的理解。 另外,再请教一下,平时我很少用外键了,这也算一个反范式,我把外键约束放在业务层来处理了,我个人觉得这是趋势,想听听老师的看法,谢谢。展开
- 靠人品去赢2020-11-05很正常,有的业务关系复杂,可能涉及到很多信息,比如说消息,有升级通知,有库存警告,有审批通知,订单通知,你要是真的不整点冗余强行三范式,你回头根据不同的情况回填消息数据,你就别指望效率了,你能把SQL写明白就相当不错了。
- LIKE2020-08-07前期范式,后期适当反范式,有点木桶效应的意思。 前期受硬件限制,内存、硬盘资源相对稀缺,如何能最大程度减少数据存库空间是第一要务; 随着硬件发展,内存、硬盘不再稀缺,而如何提高用户体验、数据实时响应变成了第一要务,(适当)反范式也就自然来了。
- Geek_Song2020-06-09老师,巴斯范式中说消除了主属性对于候选键的部分依赖,意思是说主属性和候选键之间要完全依赖是吗?
- Cookie1234562020-03-27怎么有一种任何事务都没有自己完美的一面,万事互补,这是中庸之道么
作者回复: 可以这么理解,确实万事万物都有它互补的一面
1 - 刘凯2020-03-18某任务再A时间被指派,要求在B时间完成,任务列表中有一列用于提醒该任务快到期了。条件是距离B时间一个工作日内。计算工作日用的自定义函数加工作日期表。用到计算感觉很耗时间,这样的字段用冗余存储会好些吗?数据量一天1000条
作者回复: 感谢提问,这种需求下不一定要采用RDBMS,可以使用缓存Redis,尤其是计算时间是否到期这种,redis可以很方便的设置键的生存时间或过期时间
1 - 咕咕咕2020-01-02老师,请教个问题:淘宝不让修改会员名称是不是有可能更新特别麻烦?比如采用反范式设计?瞎猜的哈哈。
作者回复: 有一定道理,毕竟数据量太大,另外从实用角度来看,这个修改名称对于购物体验帮助不大,毕竟不是社交网站。反而有可能希望会员名称更稳定,方便商家后台管理
1 - 峻铭2019-09-09反范式优化之前 实验结果是0.038秒,使用反范式添加user_name之后实验结果为0.002秒。怎么和老师的结果差别这么大呢
作者回复: 不同的设备和运行环境 处理的时间不同,只要能证明这种情况下 反范式优化效率更高即可。
1