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 用户名(来源地址为%,可不写来源地址)

相关推荐
忘川w2 小时前
NISP-PTE基础实操——代码审计
android·笔记·安全·网络安全
秋也凉2 小时前
有关Maven的个人笔记总结
java·笔记·maven
91刘仁德3 小时前
c语言 进阶 动态内存管理
c语言·经验分享·笔记
揉揉1025 小时前
【软件基础学习配置那些事 4-2】3ds Max2026 基础操作“视图基本操作”“视图的切换”“模型基础操作”“显示、隐藏栅格 ”
经验分享·笔记·3dsmax
谢白羽6 小时前
GPT-SoVITS笔记
笔记·gpt
丁满与彭彭9 小时前
嵌入式学习笔记--MCU阶段--DAY08总结
笔记·单片机·学习
上官鹿离9 小时前
C++学习笔记(六:数组)
c++·笔记·学习
巴伦是只猫9 小时前
【深度学习笔记 Ⅱ】8 mini-batch 梯度下降法
笔记·深度学习·batch
特种加菲猫10 小时前
Linux进程核心机制:状态、优先级与上下文切换详解
linux·笔记