数据库

目录

数据库

SQL语句

范式

主键外键

索引

事务

mysql

常用语句

启动关闭连接数据库

函数

DELETE与TRUNCATE的区别

索引

sql优化

表优化

查看和中止sql

慢查询日志

存储引擎

分表分区


SQL语句

  • DDL语句
  • 关键字——CREATE、ALTER、DROP、TRUNCATE等
  • 使用——DDL主要定义或改变表的结构,表之间的链接和约束等,在建表实使用
  • DML语句
  • 关键字——SELECT、UPDATE、INSERT、DELETE
  • 使用——用来对数据库里的数据进行操作的语言
  • DCL语句
  • 关键字——GRANT、REVOKE等
  • 使用——用来设置或更改数据库用户或角色权限的语句

范式

  • 作用——减少冗余
  • 第一范式——要满足属性不可拆分
  • 第二范式——消除非主属性对主属性的部分依赖
  • 第三范式——要求一个关系中不包含已在其它关系已包含的非主关键字信息
  • BCNF范式——在3NF基础上消除对主码子集的依赖
  • 反范式——没有冗余的数据库未必是最好的数据库,有时为了提高运行效率和性能,低范式标准,适当保留冗余数据

主键外键

  • 主键——表的一个特殊字段。该字段能惟一地标识该表中的每条信息;可以没有主键,有主键不能为空;
  • 外键——特殊字段。字段sno是一个表A的属性,且依赖于表B的主键;外键必须依赖于已存在表的主键;可以为空值

索引

  • 创建删除索引
  • 创建索引——ALTER TABLE table_name ADD INDEX idx_1(code);
  • 删除索引——DROP INDEX idx_1 ON table_name ;
  • 定义——索引由数据库表中一列或多列组合而成,其作用是提高对表中数据的查询速度;
  • 缺点——索引不是万能的!会使数据修改操作变慢,占用相当大的空间,使用索引有限制
  • 优点——索引可以加快数据检索操作
  • mysql中主键(primary key)和唯一键(unique)区别
  • 主键索引——保证唯一性,不允许为空,一个表中至多一个
  • 唯一索引——保证唯一性,允许一个空值,可以有多个
  • mysql指定索引 from tables force 索引名

事务

  • 概念:事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消
  • 特性
  • 原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样
  • 一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏
  • 隔离性:隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。
  • 持久性:在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚

mysql

常用语句

  • 数据导出
  • sql导出:SELECT * FROM new_product INTO OUTFILE 'D:/Program Files (x86)/export_data/new_product.sql' fields terminated by  '|' ;
  • 查看数据库版本——select version() from dual;
  • mysql8.0之后支持row_numer——ROW_NUMBER() over(PARTITION by dynastyid ) rn

启动关闭连接数据库

  • 启动 mysql 服务:service mysqld start
  • 查看mysqld 状态:mysqld status
  • 关闭mysql服务:service mysql stop
  • 重启mysql服务:service restart stop
  • 连接数据库:mysql -u root -p pwd

函数

  • GROUP_CONCAT()函数——group by 的聚合函数,将group by产生的同一个分组中的值连接起来,返回一个字符串结果,可以指定分隔符
  • IF(expr,v1,v2)函数——if判断类似3目运算符,expr表达式正确返回v1,错误返回v2
  • IFNULL(v1,v2)函数——空值转换函数

DELETE与TRUNCATE的区别

  • DELETE是可以带WHERE的,所以支持条件删除;而TRUNCATE只能删除整个表;
  • DELETE是DML,操作时原数据会被放到 rollback segment中,可以被回滚;而TRUNCATE是DDL,操作时不会进行存储,不能进行回滚;
  • 在数据量比较小的情况下,DELETE和TRUNCATE的清理速度差别不是很大。但是数据量很大的时候TRUNCATE优势大

索引

  • MERGE:当使用视图时,会把查询视图的语句和创建视图的语句合并起来,形成一条语句,最后再从基表中查询
  • 视图中存在
  • 汇总函数或窗口函数(SUM()、MIN()、MAX()、COUNT()等)
  • DISTINCT
  • GROUP BY
  • HAVING
  • LIMIT
  • UNION或UNION ALL等不会使用索引
  • TEMPTABLE:当使用视图时,会把创建视图的语句的查询结果当成一张临时表,再从临时表中进行筛选
  • UNDEFINED:未定义,自动,让系统帮你选

sql优化

  • 索引优化
  • 索引使用情况
  • 配置全值,对索引中索引列都指定具体值;
  • 配置值得范围,对索引的值能够进行范围查找;
  • 匹配最左前缀,仅仅使用索中的最左边列进行查找,如col1+col2+col3的联合索引,能被包含col1、(col1+col2)、(col1+col2+col3)的等值查询利用到
  • 仅对索引查询,当查询的列都在索引字段中时,查询效率更高;
  • 不能使用索引的情况
  • 以%开头的like查询不能使用B-Tree索引
  • 数据类型出现隐式转换时不能使用索引
  • 复合索引使用需满足最左原则
  • 如果mysql估计使用索引比全表扫描慢,则不在使用索引
  • 用or分割开的条件
  • sql语句优化
  • 执行计划
  • 语句——EXPLAIN SELECT语句
  • id:选择标识符——id值越大优先级越高,越先被执行;id相同时,执行顺序由上至下
  • select_type:表示查询的类型
  • SIMPLE(简单SELECT,不使用UNION或子查询等)
  • PRIMARY(子查询中最外层查询,查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY)
  • UNION(UNION中的第二个或后面的SELECT语句)
  • DEPENDENT UNION(UNION中的第二个或后面的SELECT语句,取决于外面的查询)
  • UNION RESULT(UNION的结果,union语句中第二个select开始后面所有select)
  • SUBQUERY(子查询中的第一个SELECT,结果不依赖于外部查询)
  • DEPENDENT SUBQUERY(子查询中的第一个SELECT,依赖于外部查询)
  • DERIVED(派生表的SELECT, FROM子句的子查询)
  • UNCACHEABLE SUBQUERY(一个子查询的结果不能被缓存,必须重新评估外链接的第一行)
  • table:输出结果集的表
  • partitions:匹配的分区
  • type:表示表的连接类型——ALL、index、range、 ref、eq_ref、const、system、NULL(从左到右,性能从差到好)
  • possible_keys:表示查询时,可能使用的索引
  • key:表示实际使用的索引
  • key_len:索引字段的长度——不损失精确性的情况下,长度越短越好
  • ref:列与索引的比较
  • rows:扫描出的行数——估算出结果集行数,表示MySQL根据表统计信息及索引选用情况,估算读取的行数
  • filtered:按表条件过滤的行百分比
  • Extra:执行情况的描述和说明
  • Range checked for each record (index map: 0x4) (匹配字段类型,编码不相符等)
  • MySQL发现没有使用好的索引,但是发现在前面的表的列值已知之后,可能会使用一些索引。 对于上表中的每一行组合,MySQL检查是否可以使用range或index_merge访问方法来检索行。

  • converting HEAP to ondisk
  • 该线程正在将内部临时表从 MEMORY 表转换为磁盘表
  • Using join buffer (Block Nested Loop),
  • Using join buffer (Batched Key Access)
  • Block Nested-Loop Join算法:将外层循环的行/结果集存入join buffer, 内层循环的每一行与整个buffer中的记录做比较,从而减少内层循环的次数。优化器管理参数optimizer_switch中中的block_nested_loop参数控制着BNL是否被用于优化器。默认条件下是开启,若果设置为off,优化器在选择 join方式的时候会选择NLJ(Nested Loop Join)算法。
  • Batched Key Access原理:对于多表join语句,当MySQL使用索引访问第二个join表的时候,使用一个join buffer来收集第一个操作对象生成的相关列值。BKA构建好key后,批量传给引擎层做索引查找。key是通过MRR接口提交给引擎的(mrr目的是较为顺序)MRR使得查询更有效率,要使用BKA,必须调整系统参数optimizer_switch的值,batched_key_access设置为on,因为BKA使用了MRR,因此也要打开MRR (参考)

表优化

  • 分析表 ANALYZE
  • 检查表 check
  • 优化表 OPTIMIZE——通过可以消除删除和更新造成的磁盘碎片,从而减少空间的浪费 只读锁

查看和中止sql

  • 查看正在运行的sql select * from information_schema.PROCESSLIST where info is not null;
  • 中止正在运行的sql kill process_id;

慢查询日志

  • 查询是否开启慢查询日志(slow_query_log)——语句:show variables like "%slow%;
  • 开启慢查询日志——语句:set global slow_query_log = on
  • 查询慢查询阈值(long_query_time)——语句:show variables like "%long%;
  • 修改慢查询阈值——语句:set global long_query_time = 5

存储引擎

  • 查看存储引擎
  • 查看所有支持的 engine:show engines;
  • 查看当前库的 engine:show variables like '%engine%;
  • innodb
  • 最常用,支持事务、回滚、自增、外键
  • 表结构存在.frm 文件中
  • 数据和索引存在表空间中,聚集索引方式方式
  • 读写效率稍差,占用空间大
  • myisam
  • 表结构存在.frm 文件中
  • .myd 存储数据, .myi 存储索引,采用非聚集索引方式
  • 快速,占空间小,不支持事务和并发
  • mysql索引底层数据结构采用B+树
  • hash很快,但每次IO只能取一个数
  • AVL和红黑树,在大量数据的情况下,IO操作还是太多
  • B树每个节点内存储的是数据,因此每个节点存储的分支太少
  • B+节点存储的是索引+指针(引用指向下一个节点),可以存储大量索引,同时最终数据存储在叶子节点,并且有引用横向链接,可以在2-3次的IO操作内完成千万级别的表操作。
  • 建议索引是是自增长数字,这样适合范围查找
  • mysql回表
  • 主键索引——InnoDB 是聚集索引方式,因此数据和索引都存储在同一个文件里。首先 InnoDB 会根据主键 ID 作为 KEY 建立索引 B+树,B+树的叶子节点存储的是主键 ID 对应的数据
  • 非主键索引——叶子节点存储的数据的是主键 KEY。拿到主键 KEY 后,InnoDB 才会去主键索引树里根据刚在 非主键索引树找到的主键 KEY 查找到对应的数据。

分表分区

  • 分区
  • 概念:是把一个数据表的文件和索引分散存储在不同的物理文件中
  • 分区类型
  • RANGE分区:基于属于一个给定连续区间的列值,把多行分配给分区
  • LIST分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择
  • HASH分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含MySQL 中有效的、产生非负整数值的任何表达式。
  • KEY分区:类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL服务器提供其自身的哈希函数。必须有一列或多列包含整数值。
  • 原理:mysql通过分区把数据保存到不同的文件里,同时索引也是分区的。相对于未分区的表来说,分区后单独的数据库文件索引文件的大小都明显降低,效率则明显的提示了。
  • 分区的限制
  • 主键或者唯一索引必须包含分区字段,如primary key (id,username),不过innoDB的大组建性能不好
  • 很多时候,使用分区就不要在使用主键了,否则可能影响性能
  • 只能通过int类型的字段或者返回int类型的表达式来分区,通常使用year或者to_days等函数(mysql 5.6 对限制开始放开了)
  • 每个表最多1024个分区,而且多分区会大量消耗内存
  • 分区的表不支持外键,相关的逻辑约束需要使用程序来实现
  • 分区后,可能会造成索引失效,需要验证分区可行性
  • 分表
  • 概念:分表和分区类似,区别是,分区是把一个逻辑表文件分成几个物理文件后进行存储,而分表则是把原先的一个表分成几个表。进行分表查询时可以通过union或者视图。
  • 分表规则
  • 水平分割
  • 水平分分割最为常用。水平分割通常是指切分到另外一个数据库或表中。
  • 垂直分割
  • 把常用、不常用的字段分开放
  • 把大字段独立存放在一个表中