三大范式

1NF:字段原子唯一不可再拆

2NF:非主属性必须完全依赖主键

3NF:非主属性必须直接依赖主键

外键

外键是表中用于关联另一张表的字段,它指向另一张表的主键或唯一键,用于维护数据完整性

一般不加外键约束,操作的时候会检查其他表;

FOREIGN KEY (stu_id) REFERENCES Student(stu_id);

一般comment注释下关联性,业务层面解决

存储过程

将SQL语句通过逻辑控制封装在一起供调用

语句

(操作)DML:delete insert update可以回滚

(定义)DDL:drop truncate 不可以回滚

数据库设计

**找到:实体-属性-关系 **

  1. 一对多

image-20260522110007027

  1. 多对多:需要中间的表

image-20260522110051166

  1. 一对一:两种方式
  • 主键关联

image-20260522110225770

  • 唯一外键关联

image-20260522110245787

MySQL执行流程

  1. 连接器:TCP建立连接,最大连接数:show variables like 'max_connections'
  2. 查询缓存:key:【SQL语句】 value:【查询结果】 8.0之后移除,表更新清除缓存
  3. 解析SQL:进行词法分析语法分析
  4. 执行SQL:预处理【字段、表是否正确】,优化【索引使用与选择】,执行【连接存储引擎】
  5. 存储引擎:获取记录返回给执行器

窗口函数使用

窗口函数和聚合函数的区别:

image-20260522135531083

语法:{}里的三个都是可选的

PARTITION BY的意思就是窗口,写了这个就是按字段值不同有多个分区,否则就是一个整体大分区

image-20260522141649350

  1. 排名函数

    ROW_NUMBER() - 连续序号

    RANK() - 并列排名(有间隔) 1 2 2 4

    DENSE_RANK() - 并列排名(无间隔)

    image-20260522141850050

  2. 分布函数

    PERCENT_RANK() - 百分比排名

    CUME_DIST() - 累积分布

    image-20260522142414449

  3. 前后行函数

    LAG() - 获取前一行的值

    LEAD() - 获取后一行的值

    image-20260522142455246

  4. 聚合函数作窗口函数

    SUM() OVER() - 累计求和

    COUNT() OVER() - 累计计数

    image-20260522142850056

InnoDB存储

查看数据库文件存储位置:SHOW VARIABLES LIKE 'datadir'

MySQL 5.7版本有三个文件:

  • db.opt:字符集

  • .frm:存储表结构

  • .ibd:存储数据

MySQL 8.0版本只有一个文件:

.ibd: 存储结构索引数据等所有信息

表空间由段(segment)、区(extent)、页(page)、行(row)组成

磁盘交互的基本单位是:页(page),一个B+树节点就是一页16KB,索引工作的时候先把根页加载

==行大小超出了页大小,行格式就有溢出页地址指向溢出页==

行格式

主要介绍Compact行格式:

  1. 额外信息:

    变长字段长度列表:记录每个变长字段真实大小

    NULL值列表:记录可为NULL的值列表

    记录头:记录是否删除;下一条记录位置等等

  2. 真实数据

    • 隐藏列

      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显示,不影响存储范围

image-20260522135219641

5. DATETIME和TIMESTAMP选哪个

需要大范围:DATETIME

需要时区转换:TIMESTAMP

需要自动更新:TIMESTAMP