1. 常用的表字段类型
数值型
主要分为两个类别:整数、浮点数。数值型数据类型都可分为有符号和无符号。
类型 | 大小 | 说明 |
---|---|---|
tinyint | 1字节 | 小 |
smallint | 2字节 | 大 |
meniumint | 3字节 | 大 |
int、integer | 4字节 | 大 |
bigint | 8字节 | 极大 |
float | 4字节 | 浮点(单精度) |
double | 8字节 | 浮点(双精度) |
decimal | 对declmal(M,D)如果M>D,为M+2否则为D+2 | 小 |
注:mysql以一个可选的显示宽度指示器的形式对SQL标准进行扩展(例 INT(6)的意思只是说该字段最大只能存储6位数,高于6位的数字存储会进行截断。但是其占用空间不会发生改变)
字符型
8种基本字符串类型
类型 | 大小 | 说明 |
---|---|---|
char | 0-255字节 | 定长 |
carchar | 0-255字节 | 变长 |
tinyblob | 0-255字节 | 不超255个字符的二进制字符串 |
tinytext | 0-255字节 | 短文本字符串 |
blob | 64K字节 | 二进制形式的长文本数据 |
text | 64K字节 | 长文本数据 |
mediumblob | 16M字节 | 二进制形式的中等长度文本数据 |
mediumtext | 16M字节 | 中等长度文本数据 |
logngblob | 4G | 二进制形式的极大文本数据 |
longtext | 4G | 极大文本数据 |
注:如果确切知道字符长度选用char。char由于本身定长特性使其性能高于carchar
时间类型
5种时间数据类型
类型 | 大小(字节) | 格式 | 说明 |
---|---|---|---|
Date | 3 | YYYY-MM-DD | 日期 |
Time | 3 | HH:MM:SS | 时间值或持续时间 |
Year | 1 | YYYY | 年份值 |
Datetime | 8 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值 |
TimeStamp | 8 | YYYYMMDD HHMMSS | 时间戳 |
注:如果没有对timestamp类型的字段没有明确赋值,或被赋予null值,mysql会自动使用系统当前日期和时间来填充它。
复合类型
Mysql还支持enum、set两种复合类型。虽然在技术上它们仍然是字符串。
enum:只允许从一个集合种取一个值
set:允许从一个集合种取得任意多个值
2. 合理的选择数据类型
选择合理范围内最小的:这样可以有效减小磁盘空间占用以及I/O读写开销
选择相对简单的数据类型:数字类型相对于字符串类型要简单多,尤其是在运算时。
不要使用null:mysql对NULL字段的索引优化不佳,会增加更多的计算难度,同时在保存和处理null时会做更多的工作。
数字不要用字符类型存储:一是占用存储空间更大,二是排序时字符串的9大于22,三是进行运算时mysql会将字符串转为数值类型,致使索引失效。
3. 主键、外键
主键:唯一标注表种的每一行,它可以时一个列或多个列的组合,
★ 保证实体的完整性
★ 加快数据库的操作速度
外键:其他表的主键或者唯一键
★保证数据库数据的一致性和完整性
★设置外键约束的两个表具有父子关系,即子表种外键的字段取值范围由父表决定。其关联关系有四种:
cascade:级联方式,主表delete、update的时候,从表delete、update掉关联记录;
setnull:置空方式,主表delete、update时,从表将关联记录的外键字段所在列设为null,注意这种方式在设计从表时外键不能设置为not null;
restrict /no action:禁止方式,先检查外键在从表中是否有关联数据,有则不运行删除(可以先删除从表的);
4. 索引
5. 索引失效的集中情况
★ 查询中有函数计算;
★ 查询中有模糊查询(不能以%开头但可以以%结尾);
★ 查询条件中有or,索引失效,除非所有条件都加上索引;
★ 使用不能与(!= 或者 <>)
★ is null 或者 is not null
★ 字符串不加引号,会导致索引失效 why
★ 最左原则,联合索引中遵循最左原则,即如果要使用联合索引,那么前面的索引列一定要包含
6. 慢查询
慢查询指查询时间超过固定阈值的查询记录。mysql默认情况下不开启慢查询
查看状态: show variables like "%slow_query_log%";
手动开启:set global slow_query_log = on;
设置超时时间:set global slow_query_log_time = 10;
设置记录地址:set global slow_query_log_file = "G:\var\slow_log.txt";
注:也可直接修改my.ini文件
7. 慢查询优化
1. 数据库开启慢查询,具体方法请查看本文第6点
2. 分析慢查询日志
3. 分析慢查询语句:采用explain分析出慢的原因
4.慢查询优化:
1. 添加索引;
2. 索引失效,排查原因并修改查询语句;
3. 优化数据库结构,提升查询速度:
1. 将字段多的表进行拆分;
2. 增加中间表,将经常联合查询的表,可建立中间表以提升查询效率,将联合查询改为对中间表的单表查询;
3. 分解关联查询,将联合查询分解为小查询,尽量将逻辑判断放在应用程序中;
4. 优化LIMIT分页,limit不是直接去偏移量,而是全部取出然后根据偏移量进行截取输出,此种优化是尽可能使用索引覆盖扫描,而不是查询所有列。然后根据需求在做一次关联操作最后返回所需的列;
8. 数据库设计--三大范式
数据库设计时需要考虑数据冗余,查询和更新速度,字段的数据类型是否合理等,所以建立科学的、规范的数据库是需要满足一些规范来优化数据库数据存储方式,在关系型数据库中这些规范就成为范式。
第一范式:要求数据库的每一列都是不可分割的原子数据项,简记为1NF;
第二范式:在1NF的基础上,所有非主属性都完全依赖于每一个候选关键属性,称R满足第二范式,简记为2NF;第二范式确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)
第三范式:在2NF的基础上,任何非主属性不依赖于其他非主属性,简记为3NF。第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。
注:关系实质上是一张二维表,其中每一行都是一个元组,每一列都是一个属性。
参考博文:https://www.cnblogs.com/wsg25/p/9615100.html
9. 分页、分页优化
三种分页方式:
★ 第一种:limit m,n
其含义为扫描满足条件的m+n行,撇去前面的m行,返回最后的n行。如果m值非常大时,扫描的效率是非常低下的。
传统limit m,n 其相对偏移量一直都是第一页,这样的话越翻到后面,效率越差。
select * from dept order by deptno desc limit 3,3;
★ 第二种:limit m
这种方式不管翻多少页都只会扫描m条数据,但是仅能实现上一页/下一页,无法跳页。
select * from dept where deptno > 1020 order by deptno asc limit 20 //下一页
select * from dept where deptno < 1000 order by deptno desc limit 20 //上一页
★ 第三种:优化 limit m,n
如果limit m,n 不可避免的话,就要优化效率,尽可能缩小m值。
优化方法:记录当前页id的最大值和最小值,计算跳转页面和当前页面的相对偏移,由于页面相近,这个偏移量不会很大,这样的话m值相对较小,大大减少扫描的行数。
如果当前是第10页,每页20条。当前最大条目id是2519,最小的为2500;
则第10页的sql如下:
select * from tb_goods_info where auto_id >= 2500 order by auto_id asc limit 0,20;
第9页:
select * from tb_goods_info where auto_id < 2500 order by auto_id desc limit 0,20
第8页:
select * from tb_goods_info where auto_id < 2500 order by auto_id desc limit 20,20;
第11页:
select * from tb_goods_info where auto_id > 2519 order by auto_id asc limit 0,20;
第12页:
select * from tb_goods_info where atuo_id > 2519 order by auto_id asc limit 20,20;
参考博文: https://www.cnblogs.com/hechenhao/p/8082065.html
10. 表的联合查询
join、union
union:该操作符用于合并两个或多个select语句的结果集。union会默认合并相同列,如果不合并可用union all 。
注:union内部的select语句必须拥有相同数量的列。列也必须拥有相似的数据类型,同时,每条select语句中的列的顺序必须相同。
join:连接两张表。类型:join、left join、right join、inner join、full join等。
笛卡尔积(cross join):join基础,要理解join首先要理解笛卡尔积。笛卡尔积就是将A表的每一条记录与B表的每一条记录强行拼在一起。所以,如果A表有n条记录,B表有m条记录,笛卡尔积产生的结果就是产生n*m表记录。
★ inner join:内连接,求两张表的交集;
★ left join:左连接,求两张表的交集外加左表剩下的数据;
★ right join:右连接,求两张表的交集外加右表剩下的数据;
★ outer join(full join):外连接,求两张表的并集;(注:mysql不支持outer join)
★ natural join:mysql自己判断完成连接过程,不需要指定连接条件。mysql会使用表内的相同字段作为作为连接条件(比较的是行,仅在两行完全相同时进行输出,否则输出null)
参考博文:https://www.cnblogs.com/canger/p/9760217.html
11. JOIN常用操作
★ 左连接:select * from t1 left join t2 on t1.id = t2.id;
★ 右连接:select * from t1 right join t2 on t1.id = t2.id;
★ 内连接:select * from t1 inner join t2 on t1.id = t2.id;
★ 左表独有:select * from t1 left join t2 on t1.id = t2.id where t2.id is null;
★ 右表独有:select * from t1 right join t2 on t1.id = t2.id where t1.id is null;
★ 全连接:
oracle:select * from t1 full join t2 on t1.id=t2.id;
mysql:select * from t1 left join t2 on t1.id = t2.id union select * from t1 right join t2 on t1.id = t2.id;
★ 并集去交集:select * from t1 left join t2 on t1.id = t2.id where t2.id is null union select * from t1 right join t2 on t1.id = t2.id where i1.id is null;
★ 自然连接:select * from t1 natural join t2;
★ 自然连接-左连接:select * from t1 natural left join t2;
★ 自然连接-右连接:select * from t1 natural right join t2;