SQL & MySQL 用法速通
概述
什么是数据库 ?数据库有啥用 ?
假设我们要做一个购物网站
如果我们将「用户信息、商品信息、…」这些重要数据放到内存中,那么服务器断电或重启都会导致数据的全部丢失
所以,我们需要将这些数据放到数据库中,达到数据持久化保存的目的
表
关系型数据库使用「表」来存储数据
常见的关系型数据库管理系统
- MySQL:开源免费跨平台、稳定高性能
- Oracle:也挺适合大型系统,比如「银行系统、医院系统、…」
- SQL Server:常见于 c# 和 .net 体系,适合在 Windows Server 中使用
MySQL
一些高级知识和技巧本文不作介绍,如「一些常用函数、给表设置约束、表之间的关系、多表查询、子查询」
实验环境
ubuntu-20.04-lts、mysql8
1 | # intallation |
如何接入 MySQL
- 方法一
1 | mysql -u root |
- 方法二:使用图形化客户端,eg:dbeaver
SQL
结构化查询语言,用于操作关系型数据库
分类
数据定义语言(
D
ataD
efinitionL
anguage),用于操作数据库对象「库、表、列…」create
、drop
、alter
数据操作语言(
D
ataM
anipulationL
anguage),用于操作数据库中的数据insert
、delete
、update
数据查询语言(
D
ataQ
ueryL
anguage)select
注释
1 | -- 单行注释 |
数据类型
1 | int -- 整型 |
常用命令
1 | -- 显示所有数据库 |
1 | # 查看当前数据库中的所有表 |
练习
1 | SELECT |
规范
基础规范
- 大部分场景适合 Innodb,部分日志写入场景适合 tokudb 或 myrockets 引擎
- 禁止大文件大照片直接存储在 Mysql 下(考虑下 mosaic)
- 由于 emoji 表情等使用场景的普及,大部分存储需求可能需要使用 utf8mb4 来进行存储,utf8mb4 是 utf8 的超集
- 高并发的互联网使用场景下,架构设计原则应该是 “解放 DB 的 CPU,将计算上移到服务层”,防止高并发的场景下,这些功能拖死数据库
- 表名使用小写,表名中尽量不包含特殊字符或 / 符号等
- 为方便业务开发以及后期维护,应该简单明了地标记用途
- 数据表字段最好也有中文注释
SQL 规范
- 避免负向查询,主要指 not in,<>,not like 等,因为如果查询条件中只有这类条件,会导致全表扫描
- % 开头的模糊查询,会导致查询无法使用索引来定位数据,会导致全表扫描
- 如果只 select 索引字段,或者只 select 索引字段和主键,会全扫描索引树找到相应字段,但这不是利用索引来定位数据,因为要查询的字段就在索引树上
- 模糊查询利用索引定位数据的解决方案:反转模糊查询的字段,但是对于 “%keyword%” 的索引,此方法无效
1 | select * from student where name like '%三'; |
- 如下
1 | select id from xxx where from_unixtime(start_day)>='2020-10-08'; |
- 一般情况下,手机号推荐使用 varchar(32) 存储,因为会有地区等属性;如果 phone 是 varchar,则如下写法会触发隐式转换,导致全表扫描
1 | select id from xxx where phone = 15635638290; |
(隐式转换的情况下,全表扫描一般是发生在字符类型字段,数字类型一般不会影响执行计划)
避免使用 select *
- select * 会获取不必要的列,这会增加 cpu,io,net 的消耗
- 在有索引覆盖的情况下,会导致无法有效利用覆盖索引
- 程序开发过程中容易因为忘记添加或删除字段,导致出现 bug
分片库的场景下,查询不带分片键容易引起查询放大的问题,会导致所有分片做无效查询
不允许在主库上执行统计 SQL(count/sum)
不允许大表使用 join,子查询
不允许超过 3 个表的 join 查询
处理 bug
ERROR 1819 (HY000)
Your password does not satisfy the current policy requirements
其实这是 mysql 的默认安全级别导致的
1 | -- 查看 mysql 的默认安全级别 |
- 搞定~
ERROR 1698 (28000)
Access denied for user root@localhost
1 | sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf |
1 | use mysql; |
- 将
skip-grant-tables
注释或删除,更改密码成功~
- 现在,如果你在尝试接入 mysql 时依然报错,则需要再次让
skip-grant-tables
生效,并再次执行service mysql restart
,无密接入 mysql 后执行如下操作
1 | use mysql; |
- 将
skip-grant-tables
注释或删除,更改密码成功~
参考了
- https://www.cnblogs.com/cpl9412290130/p/9583868.html
- https://blog.csdn.net/r527665047/article/details/107056941
- https://my.oschina.net/u/4327623/blog/4325113
(完)