做网站文章要一篇一篇的写吗,樱桃小丸子网页设计代码,苏南网站建设,好的结构设计网站1. 前言
在面向对象语言中涉及到诸多的设计模式#xff0c;例如单例模式、适配器模式#xff0c;设计模式的存在是为了让系统中的代码逻辑更加清晰#xff0c;帮助开发者建立更加健壮的系统#xff0c;同时满足易修改特性和易扩展特性。数据库设计时也存在类似设计模式的通…1. 前言
在面向对象语言中涉及到诸多的设计模式例如单例模式、适配器模式设计模式的存在是为了让系统中的代码逻辑更加清晰帮助开发者建立更加健壮的系统同时满足易修改特性和易扩展特性。数据库设计时也存在类似设计模式的通用规范被称为数据库范式。满足范式的数据库是简洁的表与表之间的关系也清晰且明确不会存储过多的冗余信息在增删改查的时候也可以避免冗余的操作。 2. 数据库设计三大范式
面试官提问 请描述下数据库设计的三大范式
题目解析 回答本题时可以从总分的结构来阐述即先阐述数据库范式的定义再挨个解释每种范式的设计原则。
数据库范式定义为了建立逻辑结构合理、冗余较小的数据库在设计数据表时必须要遵循的设计规范。
接下来可以分点阐述第一、第二、第三范式的定义和案例。 2.1 数据库第一范式1NF
数据库第一范式是设计数据库时需要满足的最基本范式
① 定义第一范式First Normal Form要求数据库表中的所有字段都是不可拆分的原子字段换句话说每个字段不可以再进行拆分。
② 案例解释对于一张最简单的用户信息表定义了用户编号、姓名、年龄、电话这三个字段user_info表如下
用户编号(user_id)姓名(username)年龄(age)电话(phone)1小明20100862小红21100873小王2210088
其中电话(phone)这个字段可能存储的是座机电话号码、也可能是手机电话号码定义上并不明确这就违背了第一范式的原子性。所以为了满足第一范式我们可以将电话字段拆分为座机电话(fixed_phone)和手机电话(cell_phone)两个字段拆分后的user_info表如下
用户编号(user_id)姓名(username)年龄(age)座机电话(fixed_phone)手机电话(cell_phone)1小明2010086180100020002小红2110087180100020013小王221008818010002002
③ 范式优点拆分之后字段定义定义清晰。在查询数据库时我们可以明确过滤的是座机号码还是手机号码方便业务层逻辑开发而且后续维护也方便。 2.2 数据库第二范式2NF
在满足第一范式的基础上数据库第二范式对字段定义进行了更严格的约束
① 定义第二范式Second Normal Form要求数据库中的每一列都和主键相关不能和主键的一部分相关。
② 案例解释在电商环境下我们需要设计一个订单表因为订单和商品绑定 所以将商品编号和订单编号作为订单表的联合主键初始设计的订单order表如下
订单编号(order_id)商品编号(good_id)购买数量(order_num)单位(unit)商品单价(good_price)购买时间(purchase_time)1000188881千克1002020-10-111000288881千克1002020-10-121000388903克3002020-10-13
仔细观察我们就能发现这种设计的问题在于good_id 8888的商品对于order_id 10001和10002记录都存储了相同的单位和商品价格这种冗余存储在数据量大的场景下是不能接收的并且违反了第二范式设计原则商品价格只和商品编号有关和订单编号无关我们将这张表进行拆分
拆分的原则是将属于商品的信息单独提炼为一张商品表在原有的订单表只保留商品编号作为联合查询时的查询依据优化后的订单order表如下
订单编号(order_id)商品编号(good_id)购买数量(order_num)购买时间(purchase_time)10001888812020-10-1110002888812020-10-1210003888932020-10-13
单独拆分出的商品good表如下
商品编号(good_id)单位(unit)商品单价(good_price)8888千克1008889克300
③ 范式优点拆分之后降低了数据库的冗余存储并且逻辑清晰要查询商品信息即走good表要查询订单信息即走order表。 2.3 数据库第三范式3NF
① 定义第三范式Third Normal Form要求数据库表中的每个字段和主键都直接相关不能间接相关。
② 案例解释还是以第一范式中的user_info表作为案例如果要存储每个用户的省份和省会城市我们可能会设计出下面这样一张表
用户编号(user_id)姓名(username)年龄(age)座机电话(fixed_phone)手机电话(cell_phone)省份(province)省会城市(city)1小明201008618010002000北京市北京市2小红211008718010002001黑龙江省哈尔滨市3小王221008818010002002贵州省贵阳市
我们将用户编号(user_id)作为主键则姓名、年龄、座机电话、手机电话都和用户这个主体强相关和主键直接相关而省份和省会城市则和用户这个主体是弱相关和主键间接相关并且存在依赖关系用户编号 - 姓名姓名 - 省份省份 - 省会城市这样构建了用户编号 - 省会城市的间接传递关系这种关系会导致数据冗余而且在执行删除/修改/增加操作的时候会产生异常情况删除所有贵州省下的用户信息即user_id 3的记录贵州省和贵阳市的信息也被删除了显然不合理因为省份这个定义和省份下的人员记录并没有关系。
所以我们需要将user_info表拆分我们通过省份构建数据关系优化后的用户user_info表如下
用户编号(user_id)姓名(username)年龄(age)座机电话(fixed_phone)手机电话(cell_phone)省份(province)1小明201008618010002000北京市2小红211008718010002001黑龙江省3小王221008818010002002贵州省
独立拆分出的省份province表如下
省份(province)省会城市(city)北京市北京市黑龙江省哈尔滨市贵州省贵阳市
③ 范式优点提高了表的独立性降低数据存储冗余。 3. 小结
作为开发在日常设计数据库表的时候可能不会特意注意使用数据库范式但是细心关注大部分企业项目的表结构就会发现大部分表都是遵循数据库范式设计的第二范式和第三范式可能会混淆概念第二范式的核心是关注非主键列是否依赖主键或者主键的一部分第三范式的核心是关注非主键列是否依赖主键还是依赖其他的非主键列。