MySQL基本概念
三大范式
1NF:字段原子唯一不可再拆
2NF:非主属性必须完全依赖主键
3NF:非主属性必须直接依赖主键
外键
外键是表中用于关联另一张表的字段,它指向另一张表的主键或唯一键,用于维护数据完整性
一般不加外键约束,操作的时候会检查其他表;
FOREIGN KEY (stu_id) REFERENCES Student(stu_id);
一般comment注释下关联性,业务层面解决
存储过程
将SQL语句通过逻辑控制封装在一起供调用
语句
(操作)DML:delete insert update可以回滚
(定义)DDL:drop truncate 不可以回滚
数据库设计
**找到:实体-属性-关系 **
- 一对多
- 多对多:需要中间的表
- 一对一:两种方式
- 主键关联
- 唯一外键关联
MySQL执行流程
- 连接器:TCP建立连接,最大连接数:
show variables like 'max_connections' - 查询缓存:
key:【SQL语句】value:【查询结果】 8.0之后移除,表更新清除缓存 - 解析SQL:进行
词法分析和语法分析 - 执行SQL:
预处理【字段、表是否正确】,优化【索引使用与选择】,执行【连接存储引擎】 - 存储引擎:获取记录返回给执行器
窗口函数使用
窗口函数和聚合函数的区别:

语法:{}里的三个都是可选的
PARTITION BY的意思就是窗口,写了这个就是按字段值不同有多个分区,否则就是一个整体大分区

排名函数
ROW_NUMBER() - 连续序号
RANK() - 并列排名(有间隔) 1 2 2 4
DENSE_RANK() - 并列排名(无间隔)

分布函数
PERCENT_RANK() - 百分比排名
CUME_DIST() - 累积分布

前后行函数
LAG() - 获取前一行的值
LEAD() - 获取后一行的值

聚合函数作窗口函数
SUM() OVER() - 累计求和
COUNT() OVER() - 累计计数

InnoDB存储
查看数据库文件存储位置:SHOW VARIABLES LIKE 'datadir'
MySQL 5.7版本有三个文件:
db.opt:字符集.frm:存储表结构.ibd:存储数据
MySQL 8.0版本只有一个文件:
.ibd: 存储结构索引数据等所有信息
表空间由段(segment)、区(extent)、页(page)、行(row)组成
磁盘交互的基本单位是:页(page),一个B+树节点就是一页16KB,索引工作的时候先把根页加载
==行大小超出了页大小,行格式就有溢出页地址指向溢出页==
行格式
主要介绍Compact行格式:
额外信息:
变长字段长度列表:记录每个变长字段真实大小
NULL值列表:记录可为NULL的值列表
记录头:记录是否删除;下一条记录位置等等
真实数据
隐藏列
row_id:有主键和唯一约束,该字段非必须trx_id:表示这条数据由哪个事务生成的roll_pointer:这条记录上一个版本的指针实际字段信息
问题
1.varchar最大多少
单行最大限制:MySQL服务器层限制:65,535字节
所以varchar(n) 的n最大是多少?
n是指的==字符==数量,所以一个表如果只用一个字段,且采用ASCII编码,那么n最大为65532(3字节额外信息)
2. 为什么自增主键推荐用INT而不是BIGINT?
NT(4字节)足够存储21亿条数据,空间效率高。BIGINT(8字节)在JOIN、索引时会占用更多内存和磁盘。只有预估数据会超过20亿时才用BIGINT
3. 为什么金额要用DECIMAL而不是FLOAT/DOUBLE?
FLOAT/DOUBLE是近似存储,有精度损失。比如0.1+0.2在FLOAT中可能等于0.30000000000000004。DECIMAL是精确存储,通过字符串形式存储,适合财务计算
4. INT(10)和BIGINT(20)中的数字是什么意思
这是显示宽度,只影响ZEROFILL显示,不影响存储范围

5. DATETIME和TIMESTAMP选哪个
需要大范围:DATETIME
需要时区转换:TIMESTAMP
需要自动更新:TIMESTAMP




