sql 范式

先了解以下几个概念:
       完全函数依赖:X->Y,并且对于X的任何一个真子集X`,都有X`不能推出Y
       部分函数依赖:X->Y,并且存在X的一个真子集X`,有X`->Y
       码:能够确定出其他属性 的 属性或者属性组合
       主属性:码中的属性
       非主属性:不存在于任何码中的属性

范式分为四种:

  1. 第一范式 (1NF)
  2. 第二范式 (2NF)
  3. 第三范式 (3NF)
  4. BCNF (通常认为是第三范式的修正)

范式判断:

  1. 第一范式
    如果一个关系模式R的所有属性都是不可分的基本数据项,则R∈1NF。简单的说,就是每一个列(属性),不能再分割成多个列(属性)。
  2. 第二范式
    在满足第一范式的基础上,非主属性完全函数依赖于任何一个候选码,则为第二范式
    举例:有一个关系模式S-L-C(Sno,Dept,Sloc,Cno,Grade),其中Sno 是学号,Dept是学院,Sloc是住所,Cno是班级,Grade是成绩
    其中的函数依赖有
           (Sno,Cno)->Grade (此关系是完全函数依赖)
           Sno->Sdept,(Sno,Cno)->Sdept(此关系是部分函数依赖)
           Sno->Sloc,(Sno,Cno)->Sloc,
           Sdept->Sloc
    以上的函数依赖关系中,存在部分函数依赖,所以此关系模式不是第二范式
  3. 在满足第二范式的基础上,每一个非主属性既不传递依赖于码,也不部分依赖于码
    举例:有一个关系模式S-L(Sno,Sdept,Sloc)
    其中的函数依赖有:
           Sno->Sdept,
           Sdept->Sloc,
           Sno->Sloc,
    以上的函数依赖关系可以看出,Sdept完全依赖于Sno,Sloc完全依赖于Sdept,Sloc完全依赖于Sno,而Sno不依赖于Sdept,从而判断出Sno和Sloc存在传递依赖关系.所以此关系模式不是第三范式
  4. 在满足第三范式的基础上
           1.所有非主属性对每一个码都是完全函数依赖
           2.所有主属性对每一个不包含它的码也是完全函数依赖
           3.没有任何属性完全函数依赖于非码的任何一组属性

判断诀窍:
       第一步:根据关系模式,写出所有的函数依赖关系,码,主属性,非主属性
       第二步:在所有的函数依赖关系中,判断是否存在部分依赖和传递依赖
       第三部:所有主属性对每一个不包含它的码也是完全函数依赖
       第四步:没有任何属性完全函数依赖于非码的任何一组属性

### 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、付费专栏及课程。

余额充值