基础
数据类型
常见数据类型的属性
- 整型
TINYINT、SMALLINT、MEDIUMINT、INT(INTEGER)和 BIGINT
- 可选属性
- M:表示显示宽度(从MySQL 8.0.17开始,整数数据类型不推荐使用显示宽度属性)
- UNSIGNED:无符号类型(非负)
- ZEROFILL:0填充
- 使用场景
- TINYINT :一般用于枚举数据,比如系统设定取值范围很小且固定的场景。
- SMALLINT :可以用于较小范围的统计数据,比如统计工厂的固定资产库存数量等。
- MEDIUMINT :用于较大整数的计算,比如车站每日的客流量等
- INT、INTEGER :取值范围足够大,一般情况下不用考虑超限问题,用得最多。比如商品编号。
- BIGINT :只有当你处理特别巨大的整数时才会用到。比如双十一的交易量、大型门户网站点击量、证券公司衍生产品持仓等
- 如何选择
系统故障产生的成本远远超过增加几个字段存储空间所产生的成本。因此,我建议你首先确保数据不会超过取值范围,在这个前提之下,再去考虑如何节省存储空间。
- 可选属性
- 浮点类型
FLOAT(单浮点)、DOUBLE(双浮点)、REAL(默认DOUBLE)- 精度的说明
- 精度说明
由于浮点数是使用二进制存储的,由于存在二进制无法表达的情况,所以只能四舍五入
- 精度的说明
- 定点数
DECIMAL- DECIMAL(M,D) 的最大取值范围与 DOUBLE 类型一样,但是有效的数据范围是由M和D决定的
- 以 字符串 的形式进行存储
- 定点数类型取值范围相对小,但是精准,没有误差,适合于对精度要求极高的场景
- 位类型
BIT(存储二进制值)- 使用SELECT命令查询位字段时,可以用 BIN() 或 HEX() 函数进行读取。
- 日期与时间类型
MySQL8.0版本支持的日期和时间类型主要有:YEAR类型、TIME类型、DATE类型、DATETIME类型和TIMESTAMP类型。
- DATE:使用 CURRENT_DATE() 或者 NOW() 函数,会插入当前系统的日期。
- TIME:
- DATETIME:
- TIMESTAMP:存储数据的时候需要对当前时间所在的时区进行转换,查询数据的时候再将时间转换回当前的时区。因此,使用TIMESTAMP存储的同一个时间值,在不同的时区查询时会显示不同的时间。
- TIMESTAMP与DATETIME的区别:
- 开发经验:
实际项目中建议使用DATETIME,但是一般存注册时间、发布时间等,不建议使用,而是使用时间戳,虽然DATETIME直观,但是不便于计算
- 文本字符串类型:CHAR 、 VARCHAR 、 TINYTEXT 、 TEXT 、MEDIUMTEXT 、 LONGTEXT 、 ENUM 、 SET 等类型
- CHAR与VARCHAR
- CHAR:
- 一般需要指定长度,不指定为1
- 保存时,实际长度小于说明长度,会在右侧填充空格,检索时会去除空格
- VARCHAR:
- 必须指定长度
- 会保留数据尾部的空格
选择情况: - 短的信息-CHAR
- 固定的信息-CHAR
- 十分频繁修改的信息-VARCHAR
- 不同引擎下:MyISAM同上,MEMORY两种类型都可以,InnoDB都建议使用VARCHAR
- CHAR:
- CHAR与VARCHAR
- TEXT类型(由于实际存储的长度不确定, MySQL 不允许 TEXT 类型的字段做主键)
TINYTEXT、TEXT、 MEDIUMTEXT 和 LONGTEXT 类型
- 可以存储较大文本,但是搜索比较慢
- 和BLOB类型的数据一样删除容易导致“空洞”,频繁使用的表不建议使用,建议单独分开
- ENUM类型
枚举类型 - SET类型
- 二进制字符串类型
BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB类型- BINARY和VARBINARY类似于CHAR和VARCHAR,只是它们存储的是二进制字符串。
- BLOB类型
TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB 4种类型
- JSON类型
- 空间类型
约束
- 概念:作用于表中字段上的规则,用于限制存储在表中的数据
- 目的:保证数据库中数据的正确性、有效性和完整性
- 分类:
外键约束
删除/更新行为
多表查询
- 内连接
两张表交集的部分 - 外连接
- 左外连接:包含左边的以及左右交集的所有数据
- 右外连接:包含右边的以及左右交集的所有数据
- 联合查询:UNION
事务
索引
最左前缀法则
索引失败的情况
SQL提示
前缀索引
索引设计原则
锁机制
按锁的粒度分:
- 全局锁
- 表级锁
- 行级锁
全局锁
加锁以后只能读,不能写
经典使用场景:备份库
#加锁
flush table with read lock;
#备份
mysqldump -uroot -p1234 itcast > itcast.sql
#解锁
unlock tables;
表级锁
- 表共享读锁
- 表独占写锁
语法:
- 加锁:
lock tables 表名... read/write
- 释放锁
unlock tables/客户端断开连接
元数据锁
加锁过程是系统自动控制,在访问一张表的时候会自动加上。
主要作用是维护元数据的数据一致性
意向锁
- 意向共享锁(IS):于表锁共享锁兼容,于表锁排它锁互斥
select ... lock in share mode添加
- 意向排他锁(IX):于表锁共享锁及排它锁都互斥。意向锁之间不会互斥
insert、update、delete、select ... for update添加
行级锁
锁定粒度最小,发生锁冲突的概率最低,并发度最高。应用在InnoDB存储引擎中
- 共享锁(S):允许一个事务去读一行,阻止其他事务获取相同数据集的排它锁
- 排它锁(X):允许获取排它锁的事务更新数据,阻止其他事务获取相同数据集的共享锁和排它锁
间隙锁/临键锁
目的:防止幻读
- 索引上的等值查询(唯一索引),给不存在的记录加锁时,优化为间隙锁
- 索引上的等值查询(普通索引),向右遍历时最后一个值不满足查询需求时,next-key lock退化为间隙锁
- 索引上的等值查询(唯一索引),会访问到不满足条件的第一个值为止
注意:间隙锁的唯一目的是防止其他事务插入间隙。间隙锁可以共存,一个事务采用的间隙锁不会阻止另一个事务在同一间隙上采用间隙锁
SQL编写
通用语法及分类
- DDL
数据定义语言 - DML
数据操作语言 - DQL
数据查询语言 - DCL
数据控制语言
查询所有数据库
SHOW DATABASES;
查询当前数据库
SELECT DATABASE()
创建
CREATE DATABASE [IF NOT EXISTS] 数据库名 [DEFAULT CHARSET 字符集] [COLLATE 排列规则];
删除
DROP DATABASE[IF EXISTS] 数据库名;
使用
USE 数据库名;
查询当前数据库所有表
SHOW TABLES;
查询表结构
DESC 表名;
查询指定表的建表语句
SHOW CREATE TABLE 表名;
表创建
CREATE TABLE 表名(
字段1 字段1类型[COMMENT 字段1注解],
......
)[COMMENT 表注解];
添加字段
ALTER TABLE 表名 ADD 字段名 类型 (长度) [COMMENT 注解] [约束];
修改数据类型
ALTER TABLE 表名 MODIFY 字段名 新数据类型(长度);
修改字段名和字段类型
ALTER TABLE 表名 CHAHGE 旧字段名 新字段名 类型(长度) [COMMENT 注解] [约束];
删除字段
ALTER TABLE 表名 DROP 字段名;
修改表名
ALTER TABLE 表名 RENAME TO 新表名