MySQL笔记4

一、范式

1.概念与意义

范式(Normal Form)是数据库设计需遵循的规范,解决"设计随意导致后期重构困难"问题。主流有 三大范式(1NF、2NF、3NF),还有进阶的 BCNF、4NF、5NF 等,范式间是递进依赖(如 2NF 基于 1NF,3NF 基于 2NF )。

2.第一范式(1NF)

(1)**规则:**字段需满足原子性(不可再拆分)

(2)示例:

如图,学生表中"student"字段列存储的数据,明显还可拆分为姓名、性别、身高,拆分后才符合 1NF。所以应将表结构更改为下图,才符合1NF:

(3)不满足1NF的影响:

客户端语言和表之间无法很好的生成映射关系

查询到数据后,需要处理数据时,还需要对其字段进行额外拆分

插入数据时,对于第一个字段的值还需要先拼装后才能进行写入

3.第二范式(2NF)

(1)**规则:**满足1NF的基础上,表中所有列必须完全依赖主键(一张表只描述一类业务,无冗余关联)。

(2)**示例:**观察1NF中表中 course 、 score 这两列数据,跟前面的几列数据实际上依赖关系并不大,所以此时在1NF表基础上可以再次拆分一下表结构:

student 表

course 表

score 表

结构优化后,之前的一张表被拆分成学生表、课程表、成绩表三张,每张表中的 id 字段作为主键,其他字段都依赖这个主键。无论在那张表中,都可以通过id主键确定其他字段的信息,每张表的业务属性都具备"唯一性"。

(3)不满足2NF的影响:

因字段对主键存在部分依赖,会导致:数据冗余(部分信息重复存)

更新异常(改一处需动多条)

插入/删除异常(操作受主键关联限制,易出错)

4.第三范式(3NF)

(1)**规则:**满足2NF的基础上,非主键字段不传递依赖于主键(字段间独立,无间接依赖)。

(2)**示例:**观察2NF中 student 表,最后的两个字段 department(学生所属的院校) 和 dean (这个院系的院长 )。一个学生的院长是谁,是取决于学生所在的院系,最后的两个字段存在依赖关系。所以进一步优化表结构:

department 表

student 表

将原本的学生表拆为院系表、学生表两张,学生表中则是只存储一个院系id,由院系表存储院系相关的所有数据。学生表中的每个非主键字段与其他非主键字段之间,都是相互独立的,之间不会再存在任何依赖性,所有的字段都依赖于主键。

(3)不满足3NF的影响:

会因字段传递依赖,导致数据冗余(同信息重复存)

更新异常(改一个值需动多条数据,易漏改)

删除异常(删数据可能误删或残留脏数据)

插入异常(新信息难单独插入)

让表结构难维护、业务流程易受牵连

5.三范式小结

1NF:确保原子性,表中每一个列数据都必须是不可再分的字段。

2NF:确保唯一性,每张表都只描述一种业务属性,一张表只描述一件事。

3NF:确保独立性,表中除主键外,每个字段之间不存在任何依赖,都是独立的。

经过三范式的设计优化后,整个库中的所有表结构,会显得更为优雅,灵活性也会更强。

6.巴斯-科德范式(BCNF)

(1)**核心问题:**3NF未约束联合主键字段间的依赖。若联合主键中某字段依赖另一字段,仍会导致冗余、更新异常。

(2)**示例:**这里我们可以通过联合主键,确定学生表中任何一个学生的信息,但是一条学生信息中的班主任(adviser),取决于学生所在的班级,因此班主任字段其实也依赖于班级字段。

如果联合主键中的一个字段依赖于另一个字段,会造成不小的问题,使得整张表的维护性变差,因此这里需要进一步调整结构:

原本的学生表则又被拆为了班级表、学生表两张,在学生表中只存储班级id,然后使用班级id和学生姓名两个字段作为联合主键。

注:第三范式只要求非主键字段之间,不能存在依赖关系,但没要求联合主键中的字段不能存在依赖,因此第三范式并未考虑完善,巴斯-科德范式修正的就是这点,是对第三范式的补充及完善。

7.第四范式(4NF)

(1)**核心问题:**表中存在多值依赖(一个字段值由多个字段共同决定,如用户权限依赖"用户+角色" ),导致冗余和操作异常。

(2)示例:

各字段含义:

user_name:用户名

role:角色信息

ROOT:超级管理员角色

ADMIN:管理员角色

USER:普通用户角色

permission:权限信息

*:超级管理员拥有的权限级别,*表示所有

BACKSTAGE:管理员拥有的权限级别,表示可操作后台

LOGIN:普通用户拥有的权限级别,表示可登录访问平台

一个用户可以拥有多个角色,同时一个角色可以拥有多个权限,所以此时无法单独根据用户名去确定权限值,权限值必须依赖用户、角色两个字段来决定,这种一个字段的值取决于多个字段才能确定的情况,就被称为多值依赖

需进一步将表格拆分为:

users 表

roles 表

permissions 表

users_roles 表

roles_permissions 表

将原本的用户角色权限表,拆分成了用户表、角色表、权限表、用户角色关系表、角色权限关系表。一方面用户表、角色表、权限表中都不会有数据冗余,第二方面无论是要删除亦或新增一个角色、权限时,都不会影响其他表。后面的两张关系表,主要是为了维护用户、角色、权限三者之间的关系。

8.第五范式

(1)规则: 建立在4NF的基础上,进一步消除表中的连接依赖,直到表中的连接依赖都是主键所蕴含的。

(2)**实际价值:**解决"无损连接"理论问题,生产环境极少用到(场景罕见、难察觉 ),了解即可。

9.第六范式

(1)**概念:**域键范式,也被称之为终极范式,但目前也仅有学术机构在研究,在生产环境中实际的用途也不大

10.反范式

(1)**概念:**不遵循数据库范式设计的结构,称为反范式结构。

(2)优缺点:

优点

消除数据冗余,节省存储空间;

表结构清晰,简化 SQL 操作、减少出错。

缺点(范式级别过高时)

数据分散到多张表,联表查询需求暴增;

联表过多可能引发索引失效,严重拖慢业务系统性能。

(3)**设计意义:**因范式过高会导致性能问题,设计库表时无需 100% 遵循范式;当"破坏范式对业务的好处>坏处"时,主动采用反范式设计。

注:不以规则为绝对标准,业务优先:能支撑业务需求、带来实际价值的设计,就是好设计。

二、数据库范式设计总结

1.范式设计的整体认知

(1) **复杂度与代价:**范式级别越高,理解难度越大,为满足范式付出的设计代价(如拆分表数量、性能开销)也越大。

(2) **实际项目应用:**一般项目中,满足到第三范式(3NF)或巴斯 - 科德范式(BCNF) 即可,继续追求更高范式易因过度精细设计导致整体性能下降。

(3)**灵活权衡原则:**控制在第三范式级别,可平衡数据冗余与性能影响;若打破范式对业务更有利,也可违背范式设计。

2.库表结构设计的合理性对比

(1)**不合理设计的问题:**会造成数据冗余,浪费存储空间;不便于常规 SQL 操作(如插入、删除),甚至引发异常。

(2)**合理设计的好处:**节省空间(内存和磁盘);数据划分合理,数据库性能高且数据完整;结构便于维护和常规SQL操作

(3)**各范式递进关系:**呈包含关系,从第一范式(1NF)到域键范式(终极范式),级别越高约束越严格,如 1NF⊂2NF⊂3NF⊂BCNF⊂4NF⊂5NF⊂域键范式 。

(4)各范式概念:

1NF(第一范式):原子性,字段值不可再分。

2NF(第二范式):唯一性,字段依赖主键,每行数据描述同一业务属性。

3NF(第三范式):独立性,非主属性不传递依赖于主键。

BCNF(巴斯 - 科德范式):主键字段独立性,联合主键字段间无依赖性。

4NF(第四范式):多值依赖,表中一个字段值由多个字段决定。

5NF(第五范式):无连接依赖,表中字段数据间不存在连接依赖关系。

域键范式(终极范式):追求库表设计的终极完美范式,目前多处于学术研究阶段 。

三、MySQL数据库账户及授权

1.密码策略

(1)密码插件:

MySQL版本 默认密码插件 替换原因
8.0+ caching_sha2_password mysql_native_password,解决SHAI算法安全性问题(易被破解)
5.7及以下 mysql_native_password 依赖SHAI算法,已被NIST建议弃用

关键差异: caching_sha2_password 更安全, mysql_native_password 验证速度快,但算法弱

(2)查看数据库当前密码策略的语句:show variables like '%password%';(查看所有密码相关变量)

(从上往下 )表中每一行的意思:

是否自动生成RSA密钥对文件

哈希轮数,数值越大安全性越强

RSA 私钥文件

RSA 公钥文件

MySQL密码过期时间,单位为天

超时断开

随机密码长度

是否支持代理用户控制认证插件

不允许用户使用最近n次使用过的密码

修改密码时是否需要提供当前用户使用的密码,OFF不需要,ON需要

不允许用户使用最近n天内使用过的密码

该变量通常为空,它可能用于特定的报告或审计目的

(3)**查看密码设置策略:**show variables like 'validate_password%';

注:若显示为空,则表示未装插件,输入安装插件语句即可:Iinstall component 'file://component_validate_password';

(从上往下 )表中每一行的意思:

用于控制密码修改时字符变化比例的要求

能将密码设置成当前用户名

插件用于验证密码强度的字典文件路径,默认为空

密码最小长度,默认为8,有最小值为4的限制

密码至少要包含的小写字母和大写字母的个数

密码至少要包含的数字个数

密码强度检查等级

密码必须包含的特殊字符个数

(4)密码强度检查等级解释(validate_password.policy) :

等级 检查对象
0 或 low 检查长度6
1 或 medium 检查长度、数字、大小写、特殊字符
2 或 strong 检查长度、数字、大小写、特殊字符、字典文件

(5)设置密码强度检查的语句:

设置密码验证强度检查策略:set global validate_password.policy=等级强度;

设置至少要包含大/小写字母的个数:set global validate_password.mixed_case_count=个数;

设置至少要包含数字的个数:set global validate_password.number_count=个数;

设置至少包含特殊字符个数:set global validate_password.special_char_count=个数;

设置密码长度:set global validate_password.length=长度值;

修改后,可刷新权限,使其生效:flush privileges;

(6)修改密码的语句:

先查看 root 用户信息:select user, host, plugin from mysql.user;

再修改其密码:alter user 'root'@'来源地址' identified by '新密码';(来源地址---本地主机为localhost,远程主机为%)

最后刷新权限即可

2.登录账户管理

(1)管理原则: MySQL8遵循**"** 先创建账户,再赋予权限**"**的流程,清晰分离账户创建与权限配置步骤

(2)关键操作命令:

操作目标 SQL命令 说明
查看当前用户信息 select user(); 快速获取当前登录用户名
进入系统数据库 use mysql; 切换到存储用户数据的库
查看数据库表 show tables; 确认 user 表存在
查看用户表结构 desc user; 了解 user 表字段设计
查询用户核心信息 select user,host,authentication_string from user; 提取账号、允许登录主机、加密密码

3.新建登录账户

(1)**新建账户的语句:**create user '用户名'@'来源地址' identified by '密码';

注:登录主机为 localhost(本地登录) 或 %(远程登录)

退出当前账户,登录新建的账户,看是否能成功进入(只能查看有限库):

4.账户授权

(1)账户权限管理原则:

最小化赋权:生产环境仅授予必要权限(如 select ),避免高危操作( update / insert )

分离角色:区分管理账号( root )与应用账号(业务用户)

定期清理:删除/回收闲置账户权限

(2)常见的用户权限:

(3)**查看权限的语句:**show grants;(查看当前用户) show grants for '用户名'@'来源地址';(查看其他账户权限)

上例显示 haha 账户只有 usage 默认权限,即连接登录权限

(4)**赋予账户权限的语句:**grant 权限列表 on 数据库名.表名 to '用户名'@'来源地址' ;

赋予 haha 账户查询mysql库的权限

查看 user 表的权限信息:

登录被赋予权限的账户,测试一下:

(5)**新建远程账户(指定网段):**create user 'test1'@'网段' identified by '密码';

(6)新建高权限账户(含赋权能力):

但是,all 所有权限中不包含给账户赋权的权限 grant:

给 haha 账户赋予给别的账户赋权的权限:

若赋权不成功则先给 root 账户增加 system_user 权限

5.回收权限

(1)**作用:**取消用户已授权的数据库操作权限,细化权限管理

(2)**语句:**revoke 权限列表/all on 库名.表名 from '用户名'@'来源地址';

回收 select 权限

回收所有权限

6.删除账户

(1)**作用:**彻底清除MySQL用户,连带其权限配置,清理无用账户

(2)**语句:**drop user '用户名'@'来源地址'; drop user 用户名(来源地址为%,可不写来源地址)

相关推荐
一只侯子2 小时前
Face AE Tuning
图像处理·笔记·学习·算法·计算机视觉
whale fall5 小时前
【剑雅14】笔记
笔记
星空的资源小屋6 小时前
跨平台下载神器ArrowDL,一网打尽所有资源
javascript·笔记·django
Xudde.6 小时前
Quick2靶机渗透
笔记·学习·安全·web安全·php
AA陈超7 小时前
Git常用命令大全及使用指南
笔记·git·学习
愚戏师8 小时前
Python3 Socket 网络编程复习笔记
网络·笔记
降临-max8 小时前
JavaSE---网络编程
java·开发语言·网络·笔记·学习
大白的编程日记.9 小时前
【计算网络学习笔记】MySql的多版本控制MVCC和Read View
网络·笔记·学习·mysql
IMPYLH10 小时前
Lua 的 require 函数
java·开发语言·笔记·后端·junit·lua
YJlio13 小时前
进程和诊断工具学习笔记(8.29):ListDLLs——一眼看清进程里加载了哪些 DLL,谁在偷偷注入
android·笔记·学习