首页 > 数据库技术 > 详细

MySQL学习笔记

时间:2019-06-03 12:19:33      阅读:108      评论:0      收藏:0      [点我收藏+]

技术分享图片

MySQL

数据库引擎

InnoDB

  • 支持事务安全

    事务四大特征(ACID)
    原子性(A):要么都成功,要么都失败

    一致性(C):保证没有数据更新会执行到一半而导致和其他数据不统一

    隔离性(I):事务A和事务B之间具有隔离性

    持久性(D):是事务的保证,事务终结的标志(内存的数据持久到硬盘文件中)

  • 为处理巨大数据量而设计

    它的CPU效率肯能是任何其他基于磁盘的关系数据库引擎所不能匹敌的

  • 将表和索引在一个逻辑表空间中
  • 支持外键
  • 被用在众多需要高性能的大型数据库站点上

MyISAM

拥有较高的插入、查询速度、但不支持事务

  • 在支持大文件的文件系统和操作系统上被支持
  • 表最大索引64,每个索引最大的列数16
  • 最大的键长度是1000B
  • BLOB和TEXT可以被索引
  • null值被允许在索引的列中
  • 可以把数文件和索引文件放在不同目录
  • 每个字符列可以有不同的字符集
  • 有VARCHAR的表可以固定或动态记录长度
  • VACHAR和CHAR列可以多达64KB

存储引擎的选择

索引

对数据库表中一列或多列的值进行排序的一种结构,

使用索引可提高数据库中特定数据的查询速度

含义和特点

  • 类型

    • BTREE

      INNODB和MyISAM引擎只支持BTREE

    • HASH

      MEMORY/HEAP引擎只支持HASH

  • 优点

    • 唯一索引可保证数据库表中每一行数据的唯一性.
    • 大大加快查询速度
    • 可以加速表和表之间的连接
    • 可显著减少分组和排序的时间.
  • 缺点

    • 创建和维护索引要消耗时间
    • 占磁盘空间
    • 对表中数据CUD时,索引也要动态的维护,耗时

分类

  • 普通索引和唯一索引

    普通索引: 可插入重复值和空值

    唯一索引: 列值必须唯一,但可有空值

    组合索引: 列值的组合必须唯一

    主键索引: 特殊的唯一索引,不允许空值

  • 单列索引和组合索引

    单列索引: 一个索引只包含单个列,一个表可以有多个单列索引.

    组合索引: 多个字段组合创建的索引.在查询中使用了这些字段的左边字段时,索引才会被引用

  • 全文索引

    全文索引:
    • FULLTEXT,列值支持全文查找,可存入空值和重复值,

    • 可以创建在char、varchar或text类型的列上

  • 空间索引

    空间索引:

    • 对空间数据类型字段建立的所以呢
    • 四种空间类型: GEPMETRY POINT LINESTRING POLYGON
    • 使用SPQTIAL关键字扩展创建正规索引的语法来创建空间so因
    • 列必须为NOT NULL,只能在MyISAM的表中创建

设计原则

  • 索引并非越多越好,占空间、影响CUD性能
  • 不对经常更新的表进行过多的索引,并使索引的列尽可能少,但对经常查询的字段创建索引.
  • 数据量小不要使用索引
  • 在条件表达式中不同值多的列上建立索引.
  • 唯一的值使用唯一索引
  • 频繁排序或分组的列上建立索引.

性能优化

查询

show status like ‘value‘ 查询数据库性能参数.

value 可以替换为:

  • Connections 连接次数
  • Uptime 上线时间
  • Slow_queries 慢查询次数
  • Com_select 查询的次数
  • Com_insert 插入操作的次数
  • Com_update 更新操作的次数
  • Com_delete 删除操作的次数

  • 分析查询语句

    explain/describe/desc select select_options

  • 使用索引提高查询速度
  • 使用索引查询

    • 使用LIKE关键字的查询语句(%在第一个位置索引不会起作用)
    • 使用多列索引的查询语句(假如一个索引由a、b、c三个字段组成,必须使用a字段,查询时才能使索引生效,最多包含16个字段)

    • 使用OR关键字的查询语句(查询条件只有or,且or前后的两个条件中的列都是索引时,查询中才使用索引.否则查询将不使用索引)

  • 优化子查询

    子查询虽然可以使查询语句很灵活,但是执行效率不高.

    可以使用JOIN查询代替子查询,连接查询不需要建立临时表,速度比子查询快.

数据库结构

  • 将字段很多的表分解成多个表

    将使用频率很低的表拆解出来.

  • 增加中间表

    对于经常需要联合查询的表,可以建立中间表提高查询效率.

    给经常查询的字段建立一个中间表,并将原来联合查询的表的数据插入到中间表中.以后就可以使用中间表来查询了

  • 增加冗余字段

    合理地加入冗余字段可以提高查询速度.

    通过在冗余字段上加入自己需要联合查询才能查出来的值,这样避免联合查询提高效率

  • 优化插入记录的速度

    • 禁用索引(MYSQL会根据表的索引对插入的记录建立索引.建立索引有额外开销)
    • 禁用唯一性检查(理由和上面差不多)
    • 使用批量插入(一起插入比一条一条 insert语句要快)
    • 使用LOAD DATA IN FILE批量导入(比insert快)
  • 分析表、检查表和优化表

    • 分析表

      分析表: 分析关键字的分布.

      ANALYZE TABLE  tbl_name;
      

      分析表的过程会加一个只读锁,分析期间只能读,不能update&insert

    • 检查表

      检查表是否存在错误.

      除了表还可以检查视图,也加只读锁

      CHECK TABLE tbl_name;

    • 优化表

      主要是消除删除或者更新造成的空间浪费.

      通过OPTIMIZE TABLE可以消除删除和更新造成的文件素片.也会加锁

      只能优化表中的VARCHAR、BLOB或TEXT类型的字段.

MySQL服务器

  • 优化服务器硬件

    • 配置较大的内存

      增加系统的缓冲区容量,使数据在内存停留的时间更长,以减少磁盘I/O

    • 配置高速磁盘系统
    • 合理分配磁盘I/O

      把磁盘I/O分散在多个设备上,减少资源竞争.提高并行操作

    • 配置更多处理器

      多处理器可同时执行多个线程

  • 优化MySQL参数

    P447 修改my.cnf或my.ini参数

错误汇总

开多个mysql实例

  • 无法启动新增服务实例

    tail -200 /var/log/mysqld.log

    查看日志. 发现某某权限不足

    解决:

    chmod 777 某某文件
    chmod 777 某某文件上层目录

  • 无法通过命令行进入mysql

    ERROR 2002 (HY000): Can‘t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock‘ (2)

    解决:

    使用的是mysql官网的开启实例的方法

    mysqld@replica01

    在配置文件中配置里自己的mysql.sock

    注意上面的报错,使用的是/var/lib/mysql/mysql.sock并不是自己配置的.

    当我更改命令使用mysql -uroot -h192.168.43.96 -P3307

    出现了错误:

    ERROR 1130 (HY000): Host '192.168.43.96' is not allowed to connect to this MySQL server

    这时候再次更改命令

     mysql -uroot -h127.0.0.1 -P3307 -p

    当时没修改hosts文件把当前ip地址加进去所以不知道

集群

InnoDB-cluster

NDB-cluster

区别

  • 差异
  • 应用常见类型

    NDB Cluster具有一系列独特属性,非常适合为需要高可用性,快速故障转移,高吞吐量和低延迟的应用程序提供服务。由于其分布式架构和多节点实现,NDB Cluster还具有特定约束,可能会使某些工作负载无法正常运行

  • 选择方式

InnoDB锁

乐观锁

用数据版本(Version)记录机制实现,这是乐观锁最常用的一种实现方式。何谓数据版本?即为数据增加一个版本标识,一般是通过为数据库表增加一个数字类型的 “version” 字段来实现。当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加1。当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的version值进行比对,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新,否则认为是过期数据。

举例
1、数据库表设计
三个字段,分别是id,value、version

select id,value,version from TABLE where id=#{id}

复制代码2、每次更新表中的value字段时,为了防止发生冲突,需要这样操作

update TABLE
set value=2,version=version+1
where id=#{id}?and version=#{version};

悲观锁

与乐观锁相对应的就是悲观锁了。悲观锁就是在操作数据时,认为此操作会出现数据冲突,所以在进行每次操作时都要通过获取锁才能进行对相同数据的操作,这点跟java中的synchronized很相似,所以悲观锁需要耗费较多的时间。

  • 共享锁

    共享锁又称读锁 read lock,是读取操作创建的锁。其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁。
    如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁。获得共享锁的事务只能读数据,不能修改数据.

  • 排它锁

    排他锁 exclusive lock(也叫writer lock)又称写锁。

    若事务 1 对数据对象A加上X锁,事务 1 可以读A也可以修改A,其他事务不能再对A加任何锁,直到事物 1 释放A上的锁。这保证了其他事务在事物 1 释放A上的锁之前不能再读取和修改A。排它锁会阻塞所有的排它锁和共享锁

行锁

行级锁都是基于索引的,如果一条SQL语句用不到索引是不会使用行级锁的,会使用表级锁。

行级锁的缺点是:由于需要请求大量的锁资源,所以速度慢,内存消耗大。

表锁

innodb 的行锁是在有索引的情况下,没有索引的表是锁定全表的.

死锁

死锁(Deadlock)?
所谓死锁:是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程在无外力协助下,永远分配不到必需的资源而无法继续运行,这就产生了一种特殊现象死锁。

作者:搜云库技术团队
链接:https://juejin.im/post/5b5ea32351882519f6477c5c
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 产生死锁的条件

    • 互斥条件

      一个资源每次只能被一个进程使用。

    • 请求与保持条件

      一个进程因请求资源而阻塞时,对已获得的资源保持不放。

    • 不剥夺条件

      进程已获得的资源,在末使用完之前,不能强行剥夺。

    • 循环等待条件

      若干进程之间形成一种头尾相接的循环等待资源关系。

  • 降低死锁的方式

    • 按同一顺序访问对象。
    • 避免事务中的用户交互。
    • 保持事务简短并在一个批处理中。
    • 使用低隔离级别。
    • 使用绑定连接。
  • 解决死锁的方法

    • 方法1

      1.查询是否锁表

      show OPEN TABLES where In_use > 0;

      2.查询进程(如果您有SUPER权限,您可以看到所有线程。否则,您只能看到您自己的线程)

      show processlist

      3.杀死进程id(就是上面命令的id列)

      kill id
    • 方法2

      1:查看当前的事务

      SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;

      2:查看当前锁定的事务

      SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;

      3:查看当前等锁的事务

      SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS; 

      杀死进程

      kill 进程ID

事务

一个支持事务(Transaction)的数据库,必须要具有这四种特性,否则在事务过程(Transaction processing)当中无法保证数据的正确性,交易过程极可能达不到交易方的要求

并发问题

  • 脏读

    (针对未提交数据)如果一个事务中对数据进行了更新,但事务还没有提交,另一个事务可以“看到”该事务没有提交的更新结果,这样造成的问题就是,如果第一个事务回滚,那么,第二个事务在此之前所“看到”的数据就是一笔脏数据。

  • 不可重复读

    (针对其他提交前后,读取数据本身的对比)不可重复读取是指同一个事务在整个事务过程中对同一笔数据进行读取,每次读取结果都不同。如果事务1在事务2的更新操作之前读取一次数据,在事务2的更新操作之后再读取同一笔数据一次,两次结果是不同的,所以,Read Uncommitted也无法避免不可重复读取的问题。

  • 幻读

    (针对其他提交前后,读取数据条数的对比)?幻读是指同样一笔查询在整个事务过程中多次执行后,查询所得的结果集是不一样的。幻读针对的是多笔记录。在Read Uncommitted隔离级别下, 不管事务2的插入操作是否提交,事务1在插入操作之前和之后执行相同的查询,取得的结果集是不同的,所以,Read Uncommitted同样无法避免幻读的问题。

事务四大特征(ACID)

  • 原子性(A)

    整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

  • 一致性(C)

    以转账案例为例,假设有五个账户,每个账户余额是100元,那么五个账户总额是500元,如果在这个5个账户之间同时发生多个转账,无论并发多少个,比如在A与B账户之间转账5元,在C与D账户之间转账10元,在B与E之间转账15元,五个账户总额也应该还是500元,这就是保护性和不变性。

    • 保护性
    • 不变性
  • 隔离性/串行化(I)

    隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。

    • read uncommitted
    - 事物A和事物B,事物A未提交的数据,事物B可以读取到
    - 这里读取到的数据叫做“脏数据”
    - 这种隔离级别最低,这种级别一般是在理论上存在,数据库隔离级别一般都高于该级别
    • read committed

      • 事物A和事物B,事物A提交的数据,事物B才能读取到
      • 这种隔离级别高于读未提交
      • 换句话说,对方事物提交之后的数据,我当前事物才能读取到
      • 这种级别可以避免“脏数据”
      • 这种隔离级别会导致“不可重复读取”
      • Oracle默认隔离级别
    • repeatable read

      在可重复读中,该sql第一次读取到数据后,就将这些数据加锁(悲观锁),其它事务无法修改这些数据,就可以实现可重复读了。但这种方法却无法锁住insert的数据,所以当事务A先前读取了数据,或者修改了全部数据,事务B还是可以insert数据提交,这时事务A就会发现莫名其妙多了一条之前没有的数据,这就是幻读,不能通过行锁来避免。需要Serializable隔离级别 ,读用读锁,写用写锁,读锁和写锁互斥,这么做可以有效的避免幻读、不可重复读、脏读等问题,但会极大的降低数据库的并发能力。

    • serializable

      • 事务A和事务B,事务A在操作数据库时,事务B只能排队等待
      • 这种隔离级别很少使用,吞吐量太低,用户体验差
      • 这种级别可以避免“幻像读”,每一次读取的都是数据库中真实存在数据,事务A与事务B串行,而不并发
  • 持久性(D)

    在事务完成以后,该事务对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

MySQL学习笔记

原文:https://www.cnblogs.com/xisuo/p/10966444.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!