参考的优秀文章

数据库(第一范式,第二范式,第三范式)

数据库设计是件严肃、关键的事儿,一毕业,加入一个大型的行业项目,那儿的前辈资深工程师,就给我灌输数据库如何关键、神圣、深不可测的观念,所以,我一直怀着崇拜的眼神。

几年前,项目经理把一个小项目的数据库设计工作交给我,我除了花费晚上和周末去完成。后来,更由于第一次负责整个系统的数据库设计,更请教了以前公司的架构师哥们,帮我把把关,看自己有哪些木有想到的。

后来,将设计方案通过了评审,甚是高兴,毕竟自己第一次设计一个系统的表结构,尽管,是一个小系统。

那么,有了几次数据库表结构设计经验,如何描述你设计表所遵循的原则呢?这时候,回归到大学课本,就是范式(Normal Form)。

第一范式:原子性,不可再分

原子性,即,字段应该是不可再分的。

是否为原子性

如,一个系统的地址用于邮寄商品,那么下表的ADDRESS是符合第一范式的。

ID USER_NAME AGE PHONE ADDRESS
1 Nick Huang 18 12345678 深圳市罗湖区地王大厦1003室

而如何判断是否原子性,这需要根据实际的业务判断。

比如一些系统仅根据地址作送货服务的,则使用上述的结构即满足第一范式;而某些系统,地址除了用于送货,还需要对用户所在地区分布做长期的统计,为了统计方便,上面的ADDRESS设计就不符合原子性了,也许应该为:

ID USER_NAME AGE PHONE PROVINCE CITY ADDRESS
1 Nick Huang 10 12345678 广东省 深圳市 地王大厦1003室

典型的例子:多个信息用分隔符拼接记录

还有其他一些典型的不符合原子性的,就是将多个数据放在一个字段中了。

如Phone字段:

ID USER_NAME AGE PHONE
1 Nick Huang 10 23658745,25654150

还有这种情况,如EXT_FIELDS字段:

ID USER_NAME AGE PHONE ADDRESS EXT_FIELDS
1 Nick Huang 10 12345678 深圳市XXX <DATA><JOB>Programmer</JOB><PASSPORT>12345678</PASSPORT></DATA>

第二范式:非主键必须完全依赖于主键,而不能只依赖于主键的一部分

非主键必须完全依赖于主键,而不能只依赖于主键的一部分(联合主键)

不符合此特性的示例

博文《权限管理系统概要设计》有一系列用户权限的表,如果以此为例子,将其中的表结构设计为如下,则不符合第二范式:

USER_ID、ROLE_ID为主键,描述用户和角色的关联关系;STATUS描述这个关联关系是生效还是失效。

可以看出,STATUS是描述这段关联的,是依赖USER_ID、ROLE_ID的,即完全依赖于主键。

而USER_NAME是用户名称,它只依赖于USER_ID,即只依赖于主键的一部分。USER_NAME字段的设置不符合第二范式。

如果有一天,用户的名称需要修改,那么就要修改与此用户相关的每一笔关联的数据。

第三范式:非主键必须直接依赖于主键,而不是传递依赖或间接依赖

非主键必须直接依赖于主键,而不是传递依赖或间接依赖。

不符合此特性的示例

博文《权限管理系统概要设计》有一系列用户权限的表,如果以此为例子,将其中的表结构设计为如下,则不符合第三范式:

此为角色表,ID为角色ID,NAME为角色名称,STATUS为此角色是否生效,SYSTEM_ID为此角色所属的系统ID,SYSTEM_NAME为此角色所属的系统的名称。

可以看出SYSTEM_NAME为传递依赖,在角色表中SYSTEM_ID依赖与ID,而SYSTEM_NAME有依赖与SYSTEM_ID。SYSTEM_NAME字段的设置不符合第三范式。

后话

是不是数据库设计一定得严格遵守3范式呢?

这不一定,要视具体情况,实际上,常见许多情况故意设置冗余字段使系统查询更高效、更方便。

【Normal Form】数据库表结构设计所遵从的范式的更多相关文章

  1. Java 通过JDBC查询数据库表结构(字段名称,类型,长度等)

    Java 通过JDBC查询数据库表结构(字段名称,类型,长度等) 发布者:唛唛家的豆子   时间:2012-11-20 17:54:02   Java 通过JDBC查询数据库表结构(字段名称,类型,长 ...

  2. 自学Zabbix之路15.4 Zabbix数据库表结构简单解析-Expressions表、Media表、 Events表

    点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 自学Zabbix之路15.4 Zabbix数据库表结构简单解析-Expressions表.Medi ...

  3. 用户中心mysql数据库表结构的脚本

    /* Navicat MySQL Data Transfer Source Server : rm-m5e3xn7k26i026e75o.mysql.rds.aliyuncs.com Source S ...

  4. mysql数据库表结构导出

    mysql数据库表结构导出 命令行下具体用法如下: mysqldump -u用戶名 -p密码 -d 数据库名 表名 > 脚本名; 导出整个数据库结构和数据 mysqldump -h localh ...

  5. magereverse - Magento数据库表结构

    Magento数据库表结构相当复杂,250多张表包含了非常多的表关联关系,让刚刚接触Magento的开发者来说真的非常头疼.往往是看到一个产品的各种属性分散在非常多的表中,找不到任何办法来取出它们的数 ...

  6. 为什么要用hibernate 与基于数据库表结构的项目开发

    最近开始学习hibernate,其实并不知道要学习什么,有什么用.后来问了一下同事,他就说快捷方便简单,很多事情不用自己做他会帮你做好,但是我觉得不应该是这样的,于是我就去搜了一下,就搜到了一篇帖子, ...

  7. activiti数据库表结构全貌解析

    http://www.jianshu.com/p/e6971e8a8dad 下面本人介绍一些activiti这款开源流程设计引擎的数据库表结构,首先阐述:我们刚开始接触或者使用一个新的东西(技术)时我 ...

  8. K3数据库表结构

    K3数据库表结构查看方法,直接在数据库中打开表 t_TableDescription,其中即各表及其与K3功能的对应关系 也可直接查询: select * from t_TableDescriptio ...

  9. 比较两个mysql数据库表结构的差异

    需求来源:一个线上系统,一个开发系统,现在要把开发系统更新到线上,但是开发系统的数据库结构与线上的略有差异,所以需要找出两个数据库的表结构差异. 数据库表结构的差异 注:操作均在Linux系统下完成 ...

随机推荐

  1. C# 测试服务器连接 Ping

    .aspx页: 一个textbox(txtIP)输入服务器地址,一个button(Btn_ok)点击测试,一个listbox(lboxContent)显示测试信息 .aspx.cs页: using S ...

  2. Quoit Design---hdu1007(最近点对问题 分治法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1007 题意:给你n(2<=n<=10^6)个点的坐标,然后找到两个点使得他们之间的距离最小 ...

  3. (一)在Windows下编译扩展OpenCV 3.1.0 + opencv_contrib 及一些问题

    一.准备工作: 1.下载OpenCV安装包:https://github.com/opencv/opencv 安装过程实际上就是解压过程,安装完成后得到(这里修改了文件名): 2.下载opencv_c ...

  4. CORS浏览器跨域

    在SO上发现一个解释跨域很棒的,忍不住拿过来 链接在此:http://stackoverflow.com/questions/10636611/how-does-access-control-allo ...

  5. http的一些事

    查找资料将http中缓存相关的知识记录下 一般来说:Last-Modifed和Expires是一对,ETag和Cache-Control是一对 Last-Modified Client端跟Server ...

  6. 使用SpringMVC集成SpringSession的问题

    最近在使用SpringSession时遇到一个问题,错误日志如下: Exception sending context initialized event to listener instance o ...

  7. apache on centos

    httpd https://www.centos.org/docs/5/html/Deployment_Guide-en-US/s1-apache-startstop.html

  8. Centos7下配置node.js环境

    1.软件环境: Centos7.VMware 10.0.NodeJS v0.10.24 2.安装过程 1>安装过程中需要管理员权限,及root权限,可以敲入如下命令. [sharing@loca ...

  9. Centos 7 mysql Buffered warning: Changed limits: max_connections: 214 解决方法

    Everytime I restart MySQL I have this warning: [Warning] Buffered warning: Changed limits: max_conne ...

  10. python staticmethod and classmethod方法

    静态方法无绑定,和普通函数使用方法一样,只是需要通过类或者实例来调用.没有隐性参数. 实例方法针对的是实例,类方法针对的是类,他们都可以继承和重新定义,而静态方法则不能继承,可以认为是全局函数. #h ...