SQL的范式理论

还说七期的师哥师姐给我们讲课。当时说到了数据库的三范式理论,听得时候听明白了,课下自己总结了一下。

其实,数据库的范式理论无非是为了节省资源,就是在保证数据完整性的前提下最大程度上减小数据的冗余程度。而数据库三范式也是前人经过多次的经验总结出来的,觉得数据库在这样的设计规则下会在数据完整性和占用数据资源两者之间取得一个较好的平衡。

下面通过例子来认识一下数据库三范式理论:

第一范式:

第一范式是指数据库表的每一列都是不可分割的基本数据项,同一列的中不能哟多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。第一范式包括下面的指导性原则:

1、 数组的每个属性只能包含一个值

2、 关系中的每个数组必须包含相同数量的值

3、 关系中的每个数组一定不能相同

例如下面的这个关系就是不符合第一范式的

学生姓名

性别

入学时间

张三

2005年

李四

2005年

赵武

王六

2006年

江涛

2009年

大家看上边的图是不是觉得很别扭呢,对,第三行里面有两个学生姓名。不必担心,因为我们在sql server中建表的时候绝对不会出现这种情况的,所以你大可不必担心自己设计出来的表不符合第一范式。那么正确的表的关系应该是下面这样的:

学生姓名

性别

入学时间

张三

2005年

李四

2005年

赵武

2006年

王六

2006年

江涛

2009年

第二范式:

如果一个数据表已经满足第一范式,而且该数据表中的任何一个非主键字段的数值都依赖于该数据表的主键字段,那么该数据表满足第二范式。

例如下面的表:

项目编号

名称

负责人

负责人部门

1

项目1

张涛

项目部

2

项目2

王明

建材部

3

项目3

张红

业务部

我们一个一个的来看,项目编号显然是主键字段,根据项目编号可以推出项目名称,可以推出项目负责人,但是根据项目编号不能推出项目负责人部门,所以上面的表是不符合第二范式的。接下来我们把上面的表拆成两个符合第二范式的表

项目编号

名称

负责人

1

项目1

张涛

2

项目2

王明

3

项目3

张红

负责人

负责人部门

张涛

项目部

王明

建材部

张红

业务部

第三范式

如果一个数据表已经满足第三范式,而且该数据表中的任何两个非主关键字段的数据值之间不存在函数信赖关系,那么该数据表满足第三范式,即3NF。

大家可以看下面的表格

编号

姓名

性别

工资

奖金

1

王鹏

8000

800

2

张红

7700

770

假如公司有这样的规定:工资的百分之十作为奖金发放给员工,那么上面的表的设计就不符合第三范式了。

从第三范式的定义我们可以看出,根据工资可以推出奖金的多少,所以工资和奖金之间是存在函数信赖关系的。但是可能就有这样的疑问了,我要是根据姓名还能推出性别呢,这怎么办呢?试想一下,如果没有员工的基本信息表你能根据姓名推出性别吗?也就是说我们数据的根源信息都不知道,你怎么推出其他的信息,也可以理解为上面的表格就是我们刚刚说到的“根源信息”。

我是这么理解的,不知道大家对上面的理解有什么疑问,请多多指教!

### SQL范式及其在数据库设计中的应用 #### 什么是SQL范式? SQL范式是指通过一组规则和标准来优化数据库的设计,从而减少数据冗余并增强数据的一致性和完整性。这些范式由埃德加·科德首次提出,并逐步发展成为现代数据库设计的核心理论之一[^2]。 #### 常见的范式层次 以下是常见的几个主要范式: 1. **第一范式 (1NF)** 数据库表中的每一列都必须是不可分割的基本数据项,即不允许有嵌套集合或多值属性。这确保了每一条记录都是原子性的。 2. **第二范式 (2NF)** 在满足1NF的基础上,进一步要求非主键字段完全依赖于整个主键而非部分主键。这意味着如果某个表具有复合主键,则所有其他字段应只与完整的主键相关联[^4]。 3. **第三范式 (3NF)** 这是在2NF基础上的一个扩展,规定除了主键外没有任何其他字段之间存在传递函数依赖关系。换句话说,任何非主属性都不能间接地依赖另一个非主属性。 4. **巴斯-科德范式 (BCNF)** BCNF是对3NF的一种更严格的改进形式,在此级别上消除了任何形式的功能依赖冲突问题,即使当候选关键字多于一个时也能保持逻辑一致[^1]。 #### 如何利用范式进行数据库规范化? 要实现高效的数据库规范化过程,可以遵循以下几个原则: - 首先识别业务需求以及相应的实体间的关系; - 将原始未加工的数据拆分为多个符合最低限度的第一范式的表格; - 接着依据功能依赖分析调整到更高阶次如二三范式直至达到理想状态下的BCNF水平为止; 下面给出一段简单的Python代码用于演示如何创建基本的SQLite数据库并执行一些基础操作: ```python import sqlite3 conn = sqlite3.connect('example.db') c = conn.cursor() # 创建一张新表 c.execute('''CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY, name TEXT NOT NULL UNIQUE, age INT CHECK(age >= 0))''') # 插入几条测试数据 c.executemany("INSERT INTO users VALUES (?, ?, ?)", [(None,'Alice',30),(None,'Bob',25)]) # 查询全部用户信息 for row in c.execute("SELECT * FROM users ORDER BY age"): print(row) conn.commit() conn.close() ``` 上述脚本展示了怎样构建一个简单但已遵照一定范式约束条件的小型用户管理系统模型。 #### 实际应用场景举例说明 考虑这样一个场景——学校教务管理系统的课程注册情况跟踪。假设最初版本如下所示: | StudentID | CourseName | Grade | |-----------|------------------|-------| | S001 | Database Systems | A | | S002 | Calculus | B+ | 然而这样的布局违反了至少三个级别的规范要求因为重复出现了诸如学生姓名之类的额外细节并且难以维护更新同步等问题。因此重新规划后的架构可能看起来像这样分开存储学生的个人信息、所修读科目清单还有最终评分结果分别置于独立关联起来的不同子集当中去处理会更加合理有效率得多[^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值