三大范式和BC范式

https://www.cnblogs.com/awidy/articles/3978724.html

引言

数据库的设计范式是数据库设计所需要满足的规范,满足这些规范的数据库是简洁的、结构明晰的,同时,不会发生插入 (insert)、删除(delete)和更新(update)操作异常。反之则是乱七八糟,不仅给数据库的编程人员制造麻烦,而且面目可憎,可能存储了 大量不需要的冗余信息。

设计范式是不是很难懂呢?非也,大学教材上给我们一堆数学公式我们当然看不懂,也记不住。所以我们很多人就根本不按照范式来设计数据库。

实质上,设计范式用很形象、很简洁的话语就能说清楚,道明白。本文将对范式进行通俗地说明,并以笔者曾经设计的一个简单论坛的数据库为例来讲解怎样将这些范式应用于实际工程。

 

范式说明

第一范式(1NF):

数据库表中的字段都是单一属性的,不可再分。这个单一属性由基本类型构成,包括整型、实数、字符型、逻辑型、日期型等。

例如,如下的数据库表是符合第一范式的:

字段1字段2字段3字段4
    

而这样的数据库表是不符合第一范式的:

字段1字段2

字段3

字段4
  字段3.1字段3.2 

很显然,在当前的任何关系数据库管理系统(DBMS)中,傻瓜也不可能做出不符合第一范式的数据库,因为这些DBMS不允许你把数据库表的一列再分成二列或多列。因此,你想在现有的DBMS中设计出不符合第一范式的数据库都是不可能的。

第二范式(2NF):

数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖(部分函数依赖指的是存在组合关键字中的某些字段决定非关键字段的情况),也即所有非关键字段都完全依赖于任意一组候选关键字。

假定选课关系表为SelectCourse(学号, 姓名, 年龄, 课程名称, 成绩, 学分),关键字为组合关键字(学号, 课程名称),因为存在如下决定关系:

(学号, 课程名称) → (姓名, 年龄, 成绩, 学分)

这个数据库表不满足第二范式,因为存在如下决定关系:

(课程名称) → (学分)

(学号) → (姓名, 年龄)

即存在组合关键字中的字段决定非关键字的情况。

由于不符合2NF,这个选课关系表会存在如下问题:

(1) 数据冗余:

同一门课程由n个学生选修,”学分”就重复n-1次;同一个学生选修了m门课程,姓名和年龄就重复了m-1次。

(2) 更新异常:

若调整了某门课程的学分,数据表中所有行的”学分”值都要更新,否则会出现同一门课程学分不同的情况。

(3) 插入异常:

假设要开设一门新的课程,暂时还没有人选修。这样,由于还没有”学号”关键字,课程名称和学分也无法记录入数据库。

(4) 删除异常:

假设一批学生已经完成课程的选修,这些选修记录就应该从数据库表中删除。但是,与此同时,课程名称和学分信息也被删除了。很显然,这也会导致插入异常。

把选课关系表SelectCourse改为如下三个表:

学生:Student(学号, 姓名, 年龄);

课程:Course(课程名称, 学分);

选课关系:SelectCourse(学号, 课程名称, 成绩)。

这样的数据库表是符合第二范式的,消除了数据冗余、更新异常、插入异常和删除异常。

另外,所有单关键字的数据库表都符合第二范式,因为不可能存在组合关键字。

第三范式(3NF):

在第二范式的基础上,数据表中如果不存在非关键字段对任一候选关键字段的传递函数依赖则符合第三范式。所谓传递函数依赖,指的是如 果存在”A → B → C”的决定关系,则C传递函数依赖于A。因此,满足第三范式的数据库表应该不存在如下依赖关系:

关键字段 → 非关键字段x → 非关键字段y

假定学生关系表为Student(学号, 姓名, 年龄, 所在学院, 学院地点, 学院电话),关键字为单一关键字”学号”,因为存在如下决定关系:

(学号) → (姓名, 年龄, 所在学院, 学院地点, 学院电话)

这个数据库是符合2NF的,但是不符合3NF,因为存在如下决定关系:

(学号) → (所在学院) → (学院地点, 学院电话)

即存在非关键字段”学院地点”、”学院电话”对关键字段”学号”的传递函数依赖。

它也会存在数据冗余、更新异常、插入异常和删除异常的情况,读者可自行分析得知。

把学生关系表分为如下两个表:

学生:(学号, 姓名, 年龄, 所在学院);

学院:(学院, 地点, 电话)。

这样的数据库表是符合第三范式的,消除了数据冗余、更新异常、插入异常和删除异常。

鲍依斯-科得范式(BCNF):

在第三范式的基础上,数据库表中如果不存在任何字段对任一候选关键字段的传递函数依赖则符合第三范式。

假设仓库管理关系表为StorehouseManage(仓库ID, 存储物品ID, 管理员ID, 数量),且有一个管理员只在一个仓库工作;一个仓库可以存储多种物品。这个数据库表中存在如下决定关系:

(仓库ID, 存储物品ID) →(管理员ID, 数量)

(管理员ID, 存储物品ID) → (仓库ID, 数量)

所以,(仓库ID, 存储物品ID)和(管理员ID, 存储物品ID)都是StorehouseManage的候选关键字,表中的唯一非关键字段为数量,它是符合第三范式的。但是,由于存在如下决定关系:

(仓库ID) → (管理员ID)

(管理员ID) → (仓库ID)

即存在关键字段决定关键字段的情况,所以其不符合BCNF范式。它会出现如下异常情况:

(1) 删除异常:

当仓库被清空后,所有”存储物品ID”和”数量”信息被删除的同时,”仓库ID”和”管理员ID”信息也被删除了。

(2) 插入异常:

当仓库没有存储任何物品时,无法给仓库分配管理员。

(3) 更新异常:

如果仓库换了管理员,则表中所有行的管理员ID都要修改。

把仓库管理关系表分解为二个关系表:

仓库管理:StorehouseManage(仓库ID, 管理员ID);

仓库:Storehouse(仓库ID, 存储物品ID, 数量)。

这样的数据库表是符合BCNF范式的,消除了删除异常、插入异常和更新异常。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/510192.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

重装pip

curl https://bootstrap.pypa.io/get-pip.py -o get-pip.psudo python get-pip.py --force-reinstallsudo apt-get purge python-pkg-resources sudo apt-get -f install sudo rm -Rf /usr/local/bin/pip sudo apt-get install python-pip sudo pip install -U pip

I begin to keep a daily

This is the first day that I write journal because of my English is very poor, so I want to improve my English.I believe that I can keep it. Todays weather is worse than yesterday,it is the big fog and haze(霾). Visibility(能见度) les…

Hadoop文章收集汇总 - 如禁止转载,请及时联系本人 收集学习互联网各位前辈分享的文章

工具自动自动集成文章列表与URL 公众号名称标题作者发布时间Hadoop实操如何使用Sentry管理Hive仓库目录外的其他目录的acl同步Fayson2018/9/30 8:27Hadoop实操如何使用Impala合并小文件Fayson2018/9/29 1:14Hadoop实操如何规划设置Kafka Broker的heap sizeFayson2018/9/28 0:27…

html之文档的头部和元数据定义(上)

什么叫元数据? 要理解这个问题,首先要知道“元”是什么。元(meta),一般被我们翻译成“关于……的……”。 元数据(meta data)——“data about data” 关于数据的数据,一般是结构化数据(如存储在数据库里的数据&#x…

线程和std::shared_ptr智能指针使用

//定义线程指针 std::unique_ptr<std::thread> thread_; //指向定义函数 threadCapture_.reset(new std::thread([this]() { func(); } ));#功能函数 void func() {while(1){std::chrono::system_clock::time_point now std::chrono::system_clock::…

Hbase二级索引+CDH+Lily

1.更改表结构&#xff0c;允许复制 已存在的表 disable tableName alter tableName,{NAME >fn, REPLICATION_SCOPE >1} enable tableName 不存在的表 create ‘table‘,{NAME >‘cf‘, REPLICATION_SCOPE >1} #其中1表示开启replication功能&#xff0c;0表示不开…

html之文档的头部和元数据定义(下,未写完)

设置网页定时跳转 当http-quip属性的值为Content-Language时&#xff0c;就可以设置网页所使用的语言&#xff1a;<mata http-equiv"Refresh" content"n; urlhttp://yourlinlk">定时浏览器将在n秒后跳转到链接&#xff0c;如果没有定义url&#xff0…

win10(UEFI)和Ubuntu双系统安装,无法进入ubuntu。

因为win10采用UEFI引导&#xff0c;所以在安装Ubuntu系统的时候着重注意 其中一个分区为efi作为引导分区 要将安装的启动引导器(grub2)设备选择在efi分区上 如下图&#xff1a;

TF-IDF + K-Means 中文聚类例子 - scala

Demo仅供参考 使用spark1.6import java.io.{BufferedReader, InputStreamReader} import java.util.Arraysimport org.ansj.splitWord.analysis.ToAnalysis import org.apache.hadoop.fs.FSDataInputStream import org.apache.spark.{SparkConf, SparkContext} import org.apa…

双目标定与矫正 matlab

matlab版本有2015a 或更新的本 1.预先拍摄好多幅标定板图像 像这样&#xff1a; 分别将左右图像放在left和right文件夹中。 2.相机标定 选择APPS,下拉菜单选择"stereo camera calibration" 进入一下界面&#xff0c;点击“add image”,分别设置camera1 &#xff0…

平衡二叉树模板

#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct node {int ndata; //记录关键字数值node *l,*r;int nheight; //平衡因子 }; int height(node* p) //返回…

Hbase PageFilter 取出数量不准确问题

PageFilter pf new PageFilter(pageFilterSize); filterList.addFilter(pf); PageFilter&#xff1a;设置获取的数据行数PageFilter作用在region上&#xff0c;只能保证当前region返回相应的数量&#xff0c;也就是说大概可理解为 region数量*pageFilterSize

CV_LOAD_IMAGE_COLOR 和 CV_BGR2RGBA找不到定义

添加下面头文件 #include "opencv2/imgcodecs/legacy/constants_c.h" #include "opencv2/imgproc/types_c.h"

堆排序原理及算法实现(最大堆)

堆排序 堆排序是利用堆的性质进行的一种选择排序。下面先讨论一下堆。 1.堆 堆实际上是一棵完全二叉树&#xff0c;其任何一非叶节点满足性质&#xff1a; Key[i]<key[2i1]&&Key[i]<key[2i2]或者Key[i]>Key[2i1]&&key>key[2i2] 即任何一非叶节点的…

Storm 安装

下载地址&#xff1a;http://storm.apache.org/ 下载完成后解压到相应目录 修改 conf目录下的storm.yaml文件,集群的所有服务器统一配置 #zookeeper地址&#xff0c;默认端口2181 storm.zookeeper.servers:- "test1"- "test2"- "test3"#nimbus…

Failed to connect to 127.0.0.1 port 1080: Connection refused package:git

windows平台&#xff1a; 解决方法&#xff1a; 打开c:/user/***/..gitconfig 删除一下内容&#xff1a; [http "https://github.com"] proxy 127.0.0.1:50647 [https "https://github.com"] proxy 127.0.0.1:50647 proxy 127.0.0.1:506…

Hbase Region in transition (RIT) 异常解决

查看Hbase状态&#xff0c;突然发现出现了RIT&#xff0c;并且很长时间了~ 查看了一些相关RIT介绍 &#xff08;部分介绍和Hbase2.0不同&#xff0c;如&#xff1a;RIT状态信息2.0已不在zookeeper保存&#xff09; https://mp.weixin.qq.com/s?__bizMzU5OTQ1MDEzMA&mid224…

邻接表的构建、DFS、BFS搜索

接着上次的文章“图的构建&#xff08;邻接链表法&#xff09;”&#xff0c;邻接链表法构建图相对来说比较简单&#xff0c;并且遍历起来也相对简单&#xff0c;但是要是动态添加图的节点和图的边&#xff0c;则是实在不方便&#xff0c;不过现在不管那么多&#xff0c;今天的…

Storm性能简单测试

看了很多关于Storm性能的文章&#xff0c;说法不一&#xff0c;自己根据实际业务测一下是否能满足自身要求&#xff08;只做了简单集群和代码调优&#xff09; 场景&#xff1a;kafka消费数据标准化后存储到Hbase中 服务器资源&#xff1a;两台32G内存做Supervisor 使用资源平…

C++之带有默认参数值的构造函数

在一个类中 &#xff0c;如果程序员没有写&#xff0c;任何一个构造函数&#xff0c;则编译器将为该类提供一个默认的构造函数&#xff0c;如果程序员对类的构造函数进行了重载&#xff0c;则编译器将不提供默构造函数&#xff0c;这里需要手动书写一个无参的构造函数&#xff…