(转载)数据库范式及宽表窄表理解
1、数据库设计的三大范式,转载地址:http://www.cnblogs.com/linjiqin/archive/2012/04/01/2428695.html
为了建立冗余较小、结构合理的数据库,设计数据库时必须遵循一定的规则。在关系型数据库中这种规则就称为范式。范式是符合某一种设计要求的总结。要想设计一个结构合理的关系型数据库,必须满足一定的范式。
在实际开发中最为常见的设计范式有三个:
1.第一范式(确保每列保持原子性)
第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式。
第一范式的合理遵循需要根据系统的实际需求来定。比如某些数据库系统中需要用到“地址”这个属性,本来直接将“地址”属性设计成一个数据库表的字段就行。但是如果系统经常会访问“地址”属性中的“城市”部分,那么就非要将“地址”这个属性重新拆分为省份、城市、详细地址等多个部分进行存储,这样在对地址中某一部分操作的时候将非常方便。这样设计才算满足了数据库的第一范式,如下表所示。
上表所示的用户信息遵循了第一范式的要求,这样在对用户使用城市进行分类的时候就非常方便,也提高了数据库的性能。
2.第二范式(确保表中的每列都和主键相关)
第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。
比如要设计一个订单信息表,因为订单中可能会有多种商品,所以要将订单编号和商品编号作为数据库表的联合主键,如下表所示。
订单信息表
这样就产生一个问题:这个表中是以订单编号和商品编号作为联合主键。这样在该表中商品名称、单位、商品价格等信息不与该表的主键相关,而仅仅是与商品编号相关。所以在这里违反了第二范式的设计原则。
而如果把这个订单信息表进行拆分,把商品信息分离到另一个表中,把订单项目表也分离到另一个表中,就非常完美了。如下所示。
这样设计,在很大程度上减小了数据库的冗余。如果要获取订单的商品信息,使用商品编号到商品信息表中查询即可。
3.第三范式(确保每列都和主键列直接相关,而不是间接相关)
第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。
比如在设计一个订单数据表的时候,可以将客户编号作为一个外键和订单表建立相应的关系。而不可以在订单表中添加关于客户其它信息(比如姓名、所属公司等)的字段。如下面这两个表所示的设计就是一个满足第三范式的数据库表。
这样在查询订单信息的时候,就可以使用客户编号来引用客户信息表中的记录,也不必在订单信息表中多次输入客户信息的内容,减小了数据冗余。
2、宽表窄表理解,转载地址:http://www.cnblogs.com/super-d2/p/3384938.html
宽表和窄表的建设该如何选择?
这个问题相信纠结了很多从是数据库开发、数据仓库开发和后台开发人员;单单考虑这个问题,难给出一个绝对的答案;本人从事数据仓库开发工作到现在已经有一年半时间了,对于这个问题,我也曾经纠结过,但是是否有绝对的答案呢?事实上任何东西都没有绝对的说法。
考虑这样的一个问题,一个公司有这样的一个需求:
设计销售领域的订单事实表,该事实表应该包含哪些维度和度量?事实表和维表该分别如何去设计?
好了,我们把关键信息拿出来,首先我们要有维度包括:销售员、销售员所属部门、下订单的时间;度量:销售量;
那么,订单事实表,其实就是一个商品销售的清单;
依照这个思路,我们建立的第一个模型可能是以下这样的:
单单看上去,貌似是符合我们的问题的需要,而且符合数据库的范式设计:没有冗余字段;但是情况真的就是这样吗?
答案是否定的,确实对于一般的OLTP系统而言这样的表设计确实减少了冗余和,增删改查等操作也很方便,但是往往对于我们的统计系统、OLAP、数据挖掘而言,情况却并非如此,举个例子:我们要统计每个部门各自的销售量为多少?那么对于上表,sql是这样的:
select a.*,b.sid into #dep_saleser from department a,saleser_dim b on a.dep_id = b.dep_id;
select count(1),a.dep_name from #dep_saleser a,order_fact b on a.sid=b.sid group by a.dep_name;
对于这么一个简单的需求已经要写两了sql去实现了,其实数据库表模型的的设计是灵活的,我们完全可以根据我们的业务去设计我们的数据表;考虑到部门和销售员可以是同属于销售者这个维度,只是他们是有上下级别关系的那么依照这个思路,我们的模型可以建立为下面这样:
那么统计每个部门各自的销售量,可以用如下sql去实现:
select count(1),a.dep_name from saleser_dim a,order_fact b
on a.sid=b.sid group by a.dep_name;
确实对于这个模型而言,有些情况下会出现冗余(填写用户,没有填写部门;填写部门没填写用户);但是对于提取数统计的逻辑又相对来说要简单了好多;
考虑到要实现取数简单,我们还可以想出另外一种方法:
看上去好像不错哦~~,取数据也就一句sql就搞掂了,但是却是最最槽糕的情况,有可能一个销售员,前几天登记的部门是a,但是其实他的所属于的部门为b,那么对于上面这个模型,我们得改动销售员和订单表;而对于上面的其他两个模型都仅仅需要改动一张表就行了,造成查询数据部一致往往也就是这种数据模型所造成的。
所谓的宽表就是字段比较多的表,包含的维度层次比较多,造成冗余也比较多,毁范式设计,但是利于取数统计,而窄表往往对于OLTP比较合适,符合范式设计原则;
3、从这两篇文章的说明,个人理解为宽表还是倾向于破坏第二范式,而实际上冗余既取决于设计,也取决于实际数据的管理。
(转载)数据库范式及宽表窄表理解相关推荐
- 宽表, 窄表, 维度表, 事实表的区别
在数据开发里, 会涉及到一些概念: 宽表, 窄表, 维度表, 事实表 宽表: 把多个维度的字段都放在一张表存储, 增加数据冗余是为了减少关联, 便于查询. 查询一张表就可以查出不同维度的多个字段 窄表 ...
- 维度表和事实表以及明细表和宽表和窄表的区别
简单解释: 事实表就是交易表. 维度表就是基础表. 二者的区别: 维度表的冗余很大,主要是因为维度一般不大(相对于事实表来说的),而维度表的冗余可以使事实表节省很多空间. 事实表一般都很大,如果以普通 ...
- 【数仓设计】宽表和窄表
宽表: 从字面意义上讲就是字段比较多的数据库表.通常是指业务主题相关的指标.维度.属性关联在一起的一张数据库表.由于把不同的内容都放在同一张表存储,宽表已经不符合三范式的模型设计规范,随之带来的主要坏 ...
- 数据库设计--大宽表
宽表的概念 基本概念 宽表从字面意义上讲就是字段比较多的数据库表.通常是指业务主题相关的指标.维度.属性关联在一起的一张数据库表. 由于把不同的内容都放在同一张表存储,宽表已经不符合三范式的模型设计规 ...
- 宽表和窄表概念和优缺点
宽表和窄表概念和优缺点 宽表: 从字面意义上讲就是字段比较多的数据库表.通常是指业务主题相关的指标.维度.属性关联在一起的一张数据库表.由于把不同的内容都放在同一张表存储,宽表已经不符合三范式的模型设 ...
- python长表转换宽表_pandas使用之宽表变窄表的实现
我就废话不多说了,还是直接看代码吧! import pandas as pd # 伪造一些数据 fake_data = {'subject':['math', 'english'], 'A': [88 ...
- R语言tidyr包spread()函数实战详解:数据裂变、从窄表到宽表
R语言tidyr包spread()函数实战详解:数据裂变.从窄表到宽表 目录 R语言tidyr包spread()函数实战详解:数据裂变.从窄表到宽表
- pandas使用melt函数将宽表变换为窄表、id_vars参数指定原宽表聚合数据列、value_vars参数指定需要被压缩的数据列(单个、多个)、var_name指定压缩后数据列的名称
pandas使用melt函数将宽表变换为窄表.id_vars参数指定原宽表聚合数据列.value_vars参数指定需要被压缩的数据列(单个.多个).var_name指定压缩后数据列的名称.value_ ...
- Z05 - 025、明细表、宽表、窄表 - 实现
初学耗时:0.5h 注:CSDN手机端暂不支持章节内链跳转,但外链可用,更好体验还请上电脑端. 一.明细表.宽表.窄表 - 实现 1.1 建明细表:dw_weblog_detail. 1.2 ...
最新文章
- ACMNO.9求Sn=a+aa+aaa+…+aa…aaa(有n个a)之值,其中a是一个数字。 例如:2+22+222+2222+22222(n=5),n由键盘输入。 输入 n 输出 a=2 时
- 【BZOJ3994】[SDOI2015]约数个数和 莫比乌斯反演
- treeset java_Java TreeSet Higher()方法与示例
- Linux 迎来 29 岁:从个人爱好到统治世界的操作系统内核
- 自动控制原理:一阶系统的时域分析
- 在知网下载硕士的论文PDF格式无需安装CAJ软件
- 漫画 | 前端发展史的江湖恩怨情仇
- 【电商】电商后台设计—订单中心
- 网课python程序设计答案_中国大学MOOCPython程序设计网课答案
- Windows环境下安装OpenCV-Python 完美解决:找不到指定模块(dll缺失)
- 2020最新天猫双十一自动获取喵币
- 透明度百分和六进制对比表
- Rust:Trait 详解
- 无需安装任何软件即可在个人电脑中创建隐私空间的方法
- 鲁大师显卡跑分测试软件,鲁大师跑分测试 鲁大师跑分零分怎么办
- 李国庆是一匹野马,但俞渝不是草原!
- 戴维营教育-Swift语言中文教程和配套视频教程更新中
- 色度副载波和声音载频
- linux 内核代码分析1 TI am335x
- python调用百度地图画轨迹图_百度地图 API 绘制路线
热门文章
- Java高并发编程(三):Java内存模型
- vc c语言图片处理,大佬们,小菜鸟想问一问用vc编译器做简易画图软件
- Javascript高级调试——console.table()
- (转载)彻底理解浏览器的缓存机制
- 180217_JAVA学习_TreeSet中存放含多个String的类并设置排序规则
- GIT 源码管理-简介
- delphi的dbgrid控件点击title排序
- gradle编译出错:Execution failed for task #39;:app:compileTestDebugJava#39;.
- Android dialog 全屏
- MySQL 数据备份与同步