MySQL必知必会

关系型数据库
DML: Data Manapulate Lanauage 数据操作语言
      INSERT, REPALCE, UPDATE, DELETE

DDL:  Data Definition Lanauage 数据定义语言
      CREATE, ALTER, DROP

DCL: Data Control Lanauage  数据控制语言
      GRANT,REVOKE


DBMS:
    数据管理的独立性
    有效的完成数据的存取
    数据完整性和安全性
    数据集中管理
    并发存储与故障恢复
    减少应用程序的开发时间

RDBS拥有的组件:
    缓存器
    故障恢复器
    磁盘空间管理器
    事务管理器
    锁管理器
    SQL分析器
    SQL优化器
    SQL计划执行器

mysql
    -u USERNAME
    -p PASSWD
    -h DOMAIN

mysql客户端:
    交互式模式
    批处理模式(执行mysql脚本)

交互式模式中的命令类别:
    客户端命令
    服务器端命令


关系数据库对象
    表
    索引
    视图
    约束
    存储过程
    存储函数
    触发器(主动数据库)
    游标
    用户
    权限
    事务

表
    行,列
    表:实体
    列:field,column
    行:raw

字段名称
    字符
        CHAR(n)
        VARCHAR(n) 
        BINARY(n):区分大小写 
        VARBINARY(n)
        TEXT(n)
        BLOB(n)
    数值
        精确数值型
            整型
                  TINYINT
                  SMALLINT
                  MEDIUMINT
                  INT
                  BIGINT

                  修饰符: UNSIGNED
                           NOT NULL
            十进制
                  DECIMAL
        近似数值型
            浮点型
                  FLOAT
                  DOUBLE
    日期时间
        DATA
        TIME
        DATETIME    
        STAMP
    布尔
    内置:ENUM, SET



DDL
    CREATE
    ALTER
    DROP
DML
    INSERT
    UPDATE
    DELETE
DCL
    GRANT
    REVOKE

创建数据库
    CREATE DATABASE db_name; 
    CREATE DATABASE [IF NOT EXISTS] db_name;

    DROP DATABASE [IF EXISTS] db_name;

创建表
    CREATE TABLE tb_name(col1,col2,...);

    create:
        create table TABLE_NAME (
        Id   int NOT NULL,
        Name char(10),
        Age  int,
        Sex  char(5)
        );


    查看库中的表:SHOW TABLES FROM db_name;
    查看表的结构:DESC tb_name;

    删除表:DROP TABLE tb_name;

修改表列名:
    ALTER TABLE tb_name 
        MODIFY   mysql> ALTER TABLE t1 MODIFY b BIGINT NOT NULL;
        CHANGE   mysql> ALTER TABLE t1 CHANGE a b INTEGER;
        ADD
        DROP

更改表名称
        RENAME table 原表名 to 新表名;
查看表的创建语句
        SHOW CREATE table '表名';

DML:
    INSERT INTO tb_name (col1,col2,...) VALUES|VALUE ('STRING', NUM,...);
    INSERT INTO tb_name (col1,col2,...) VALUES|VALUE ('STRING', NUM,...),('STRING',NUM,...);    

    UPDATE tb_name SET column=value WHERE  

    DELETE FROM tb_name WHERE CONDITION;

选择:
    SELECT 字段 FROM tb_name WHERE CONDITION

    *: 所有字段
    WHERE:没有条件表示显示所有行;

创建用户:
    CREATE USER 'USERNAME'@'HOST' [IDENTIFIED BY 'PASSWORD'];
    DROP USER 'USERNAME'@'HOST';

    HOST:
        IP:
        HOSTNAME:
        NETWORK:
        通配符
            _:匹配任意单个字符, 172.16.0._
            %:匹配任意字符;

    jerry@'%'
DCL:
    GRANT pri1,pri2,... ON DB_NAME.TB_NAME TO 'USERNAME'@'HOST' [IDENTIFIED BY 'PASSWORD'];
    REVOKE pri1,pri2,... ON DB_NAME.TB_NAME FROM 'USERNAME'@'HOST';

    查看用户的授权:SHOW GRANTS FOR 'USERNAME'@'HOST';

    ALL PRIVILEGES

关系型数据
表示层:表
逻辑层:存储引擎
物理层:数据文件

数据查询和存储
存储管理器:
            权限及完整性管理器
            事物管理器
            文件管理器
            缓冲区管理器
查询管理器:
            DML解释器  
            DCL解释器          
            DDL解释器
            查询执行引擎
smp:对称多处理器      

MySQL插件式存储引擎
5.5.8之前:MyISAM(不支持事务,适用于查询多,增删少)
5.5.8之后:InnoDB(支持事物,适用于增删比较多)

文件中记录组织:
堆文件组织:一条记录可以放在任何地方
顺序文件组织:根据“搜索码”值顺序存放
散列文件组织:分成N个片


表结构定义文件,表数据文件

表空间:实现一个表放多个表的数据(table space)

数据字典:
    关系的元数据:
        关系的名字、字段的名字、字段的类型和长度、视图、约束

缓冲区管理器:
    缓存置换策略
    被钉住的块:不允许置换出去


Root user password assignment
1#mysqladmin -u USERNAME -h HOSTNAME password 'NEW_TION;PASS' -p(输入旧密码)
2,mysql> SET PASSWORD FOR 'USERNAME'@'HOST'=PASSWORD('new_passwd');
3,mysql> UPDATE mysql.user SET PASSWORD=PASSWORD('new_passwd') WHERE CONDITION;

mysql客户端工具
    mysql
    mysqladmin
    mysqldump
    mysqlcheck
    mysqlimport

可以在用户家目录建立my.cnf
[client]
user = 'root'
password = 'redhat'
host = localhost


mysql非客户端工具
    myisamchk
    myisampack

存储引擎:
MyISAM:不支持事务,只支持表锁,不支持外键,并发写不好,支持B树索引、FULLTEXT索引、空间索引,支持表压缩
    每表三个文件:
    .frm:表结构
    .MYD:表数据
    .MYI:表索引

InnoDB:支持事务,行级别的锁,支持B树索引、聚簇索引、自适应hash索引,表空间,支持raw(裸设备)磁盘
    默认所有表数据共享一个表空间,可以编辑/etc/my.cnf永久话化
    SHOW VARIABLES LIKE '%innodb'中找到innodb_file_per_table
    .frm:表结构
    .ibd:表空间
    .opt:默认字符集和排序规则选项

MRG_MYISAM:支持两个表逻辑上的合并

CSV:两个数据库移植的时候使用

ARCHIVE:用于实现归档,用于做数据挖掘,不再修改

MEMORY:用于创建临时表,存储在内存中
mysql 
    --user, -u
    --host, -h
    --password, -p
    --port
    --protocol
    --database DATABASE, -D


mysql>
    交互模式
    批处理模式(执行mysql脚本)    
    mysql -uroot -p'redhat' < test.sql
    或
    mysql> source test.sql

客户端命令:
    \c:提前终止语句的执行
    \g:无论语句结束符是什么,直接执行
    \d:自定义结束符是什么
    \G:竖排显示
    \W:显示警告信息
    \#: 新建对象field自动补全





AUTO_INCREMENT
    整型
    非空
    无符号
    主键或唯一

Mysql服务器变量
    全局变量:对当前会话无效,只对新会话生效
    mysql> SHOW GLOBAL VARIABLES
    会话变量:及时生效,只对当前会话有效
    mysql> SHOW [SESSION] VARIABLES

生效时间:
    动态--临时修改
    静态--写在配置文件,通过参数传递给mysqld

mysql> SHOW TABLE STATUS LIKE 'students'\G;
mysql> SHOW CHARACTER SET;(查看字符集)
mysql> SHOW INDEXES FROM 'students';(查看表上的索引)
mysql> SHOW COLLATION;(查看字符集)
mysql> SHOW GLOBAL VARIABLES LIKE '%char%';(查看变量)
mysql> SELECT LAST_INSERT_ID();
mysql> SELECT DATABASE();

查看服务器变量 :@@变量名
mysql> SELECT @@global.sql_mode; 或 mysql> SHOW GLOBAL VARIABLES LIKE 'sql_mode';
mysql> SELECT @@session.sql_mode; 或 mysql> SHOW SESSION LIKE 'sql_mode';

设定服务器变量:SET GLOBAL|SESSION 变量名='value'

SQL语句:
mysql> SHOW COLLATION LIKE '%gbk%';
mysql> CREATE SCHEMA IF NOT EXISTS students CHARACTER SET 'gbk' COLLATION 'gbk_chinese_ci'


选择:SELECT * FROM tb_name WHERE 
    布尔表达式
        算术运算:
        比较操作符:
        其它运算符:IN, BETWEEN ... AND ..., LIKE, RLIKE(REGEXP), IS NULL, IS NOT NULL
        逻辑运算:AND, OR, NOT, XOR

    DISTINCT

投影:SELECT field1, ... FROM tb_name;

ORDER BY field,... {ASC|DESC}

聚合计算:COUNT()、SUM()、MAX()、MIN()和AVG();

GROUP BY field1,... 
    HAVING 

LIMIT [offset],num

多表查询:
    交叉连接
    自然连接
        WHERE tb1.field=tb2.field
    外连接
        左外
            FROM tb1 LEFT JOIN tb2 ON condition
        右外
            FROM tb1 RIGHT JOIN tb2 ON condtion
    自连接

子查询:
    FROM
    WHERE
        比较操作符:子查询只能返回一个字段的单值;
        IN:列表(某字段的多个值)


广义查询:
DML: 
    DELETE
    INSERT INTO
    UPDATE

INSERT INTO tb_name (col1, col2, ...) VALUES (val1, val2, ...)[,(val1, val2, ...),...]
    字符型:单引号
    数值型:不需要引号
    日期时间型:
    空值:NULL''

INSERT三种:
INSERT INTO tutors (Tname,Gender,Age) VALUES ('Joe','M',28);
INSERT INTO tutors SET Tname='Tom',Gender='F',Age=30;
INSERT INTO tutors (Tname,Gender,Age) SELECT Name,Gender,Age FROM students WHERE Age>20;

REPLACE INTO
REPLACE INTO tutors (Tname,Gender,Age) VALUES ('Joe','M',28);
REPLACE INTO tutors SET Tname='Tom',Gender='F',Age=30;
REPLACE INTO tutors (Tname,Gender,Age) SELECT Name,Gender,Age FROM students WHERE Age>20;

DELETE: 
    DELETE FROM tb_name WHERE condition;

TRUNCATE tb_name: 清空表,并重置AUTOINCREMENT计数器;


UPDATE tb_name SET col1=..., col2=... WHERE 

锁:
    读锁:共享锁
    写锁:独占锁
      LOCK TABLES tb_name {READ|WRITE}
      UNLOCK TABLES

锁粒度:从大到小,Mysql服务器仅支持表级锁,行锁需要由存储引擎支持
    表锁:整张表
    页锁:锁定一个数据块,划分的DATA BLOCK
    行锁:一个实体,元组


Mysql的事务(ACID测试):
原子性(Atomicity)  :事务引起的操作,要么都完成,要么都不执行。
一致性(Consistency):写入的事务和处理后的数据在完成之前和完成之后应当一致
隔离性(Isolation)  :如果两个事物同时执行,不能互相影响。MVCC:多版本并发控制
持久性(Durability) :出现崩溃,要可以恢复,保持在磁盘的数据应持久

日志中存储的操作过程,而非数据本身

隔离级别(隔离级别越高,并发越差):
READ-UNCOMMITTED:读未提交。只要第一个事务操作,即使未提交,第二个也可以立刻就可以看到。
READ-COMMITTED  :读提交。同上,会产生"幻读"
REPEATABLE-READ :可重读。无论提交与否,截止事务提交之前都不变。
SERIABLIZABLE   :可串行。一个事务一个事务排队来。

查看隔离级别:mysql> SHOW GLOBAL VARIABLES LIKE '%iso%';
修改隔离级别:mysql> SET SESSION tx_isolation='READ-UNCOMMITTED';
再查看隔离级别:mysql> SELECT @@tx_isolation;

事务:CPU, I/O
    RDBMS, 
        ACID:
            Automicity:原子性,事务所引起的数据库操作,要么都完成,要么都不执行;
            Consistency:一致性,A(3000)-->B(2000)
                1:A:3000-->2500, 
                2: A+B: 4500, 
            Isolation: 隔离性
                事务调度:事务之间影响最小
                MVCC:多版本并发控制
            Durability:一旦事务成功完成,系统必须保证任何故障都不会引起事务表示出不一致性;
                1、事务提交之前就已经写出数据至持久性存储;
                2、结合事务日志完成;
                    事务日志:顺序IO
                    数据文件:随机IO

    事务的状态:
        活动的:active
        部分提交的:最后一条语句执行后
        失败的:提交后未能完成
        中止的:没提交,走了一半就提前停止
        提交的:

事务:并发执行
    1、提高吞吐量和资源利用率
    2、减少等待时间

事务调度:
    可恢复调度;
    无级联高度:

mysql> START TRANSACTION;(启动事务)
mysql> DELETE FROM tutors WHERE Tname LIKE 'stu%'
mysql> ROLLBACK;(回滚delete操作)
mysql> COMMIT;(事务提交之后不可以撤销)

查看是否自动提交(建议关闭自动提交,减少I/O操作):
mysql> SELECT @@autocommit

记录/回滚事务保存点
mysql> SAVEPOINT pointA;
mysql> ROLLBACK TO pointA;

=============================================================================================
Mysql用户权限管

user: Contains user accounts, global privileges, and other non-privilege columns.
user: 用户帐号、全局权限

db: Contains database-level privileges.
db: 库级别权限

host: Obsolete.
host: 废弃

tables_priv: Contains table-level privileges.
表级别权限

columns_priv: Contains column-level privileges.
列级别权限

procs_priv: Contains stored procedure and function privileges.
存储过程和存储函数相关的权限

proxies_priv: Contains proxy-user privileges.
代理用户权限


权限级别:
    全局级别: SUPER、
    库
    表: DELETE, ALTER, TRIGGER
    列: SELECT, INSERT, UPDATE
    存储过程和存储函数
=============================================================================================
Mysql日志类型


错误日志:服务器启动和关闭、服务器运行过程中的错误信息、事物调度器运行一个事件时产生的信息、在从服务器上启动从服务的日志
    log_error
    log_warnings
一般查询日志:DML、DDL
    general_log
    general_log_file
    log
    log_output
慢查询日志
    long_query_time
    log_slow_queries={YES|NO}
    slow_query_log                       
    slow_query_log_file                       

二进制日志:任何引起或可能引起数据库变化的操作;
    复制、即时点恢复;
    mysqlbinlog

    二进制日志的格式(binlog_format):
        基于语句: statement
        基于行: row
        混合方式: mixed

    二进制日志事件:
        产生的时间
        相对位置

    二进制日志文件:
        索引文件
        二进制日志文件



查找关于log的参数
mysql> SHOW GLOBAL VARIABLES LIKE '%log%'
查看二进制日志的信息
mysql> SHOW BINLOG EVENTS IN '二进制日志文件名' [FROM pos];
mysql> SHOW BINLOG EVENTS IN 'mysql-bin.000005' [FROM 107];

查看当前正在使用的二进制日志文件
mysql> SHOW MASTER STATUS;
查看当前拥有的二进制文件
mysql> SHOW BINARY LOGS; 
删除二进制日志 
mysql> PURGE BINARY LOGS TO '某二进制日志文件'
滚动二进制日志
mysql>FLUSH LOGS;


利用mysqlbinlog查看日志和导出
root# mysqlbinlog  --start-position=177  --stop-position=358 mysql-bin.000005
root# mysqlbinlog  --start-datetime='2017-04-09 15:14:39'  [--stop-datetime] mysql-bin.000005
root# mysqlbinlog  --start-datetime='2017-04-09 15:14:39'  [--stop-datetime] mysql-bin.000005 > /root/back.sql




中继日志:
    从主服务器的二进制日志文件中复制而来的时间,并保存为的日志文件

事务日志:ACID,将随机IO转换为顺序IO;
    事务性存储引擎用于保证保证原子性、一致性、隔离性和持久性
    innodb_flush_log_at_trx_commit:
        0:每秒同步,并执行磁盘flush操作
        1:每事务同步,并执行磁盘flush操作(推荐)
        2:每事务同步,但不执行磁盘flush操作,有操作系统决定flush


expire_logs_days={0..99}
设定二进制日志的过期天数,超出此天数的二进制日志文件将被自动删除。默认为0,表示不启用过期自动删除功能。如果启用此功能,自动删除工作通常发生在MySQL启动时或FLUSH日志时。作用范围为全局,可用于配置文件,属动态变量。

general_log={ON|OFF}
设定是否启用查询日志,默认值为取决于在启动mysqld时是否使用了--general_log选项。如若启用此项,其输出位置则由--log_output选项进行定义,如果log_output的值设定为NONE,即使用启用查询日志,其也不会记录任何日志信息。作用范围为全局,可用于配置文件,属动态变量。

general_log_file=FILE_NAME
查询日志的日志文件名称,默认为“hostname.log"。作用范围为全局,可用于配置文件,属动态变量。


binlog-format={ROW|STATEMENT|MIXED}
指定二进制日志的类型,默认为STATEMENT。如果设定了二进制日志的格式,却没有启用二进制日志,则MySQL启动时会产生警告日志信息并记录于错误日志中。作用范围为全局或会话,可用于配置文件,且属于动态变量。

log={YES|NO}
是否启用记录所有语句的日志信息于一般查询日志(general query log)中,默认通常为OFF。MySQL 5.6已经弃用此选项。

log-bin={YES|NO}
是否启用二进制日志,如果为mysqld设定了--log-bin选项,则其值为ON,否则则为OFF。其仅用于显示是否启用了二进制日志,并不反应log-bin的设定值。作用范围为全局级别,属非动态变量。

log_bin_trust_function_creators={TRUE|FALSE}
此参数仅在启用二进制日志时有效,用于控制创建存储函数时如果会导致不安全的事件记录二进制日志条件下是否禁止创建存储函数。默认值为0,表示除非用户除了CREATE ROUTING或ALTER ROUTINE权限外还有SUPER权限,否则将禁止创建或修改存储函数,同时,还要求在创建函数时必需为之使用DETERMINISTIC属性,再不然就是附带READS SQL DATA或NO SQL属性。设置其值为1时则不启用这些限制。作用范围为全局级别,可用于配置文件,属动态变量。

log_error=/PATH/TO/ERROR_LOG_FILENAME
定义错误日志文件。作用范围为全局或会话级别,可用于配置文件,属非动态变量。

log_output={TABLE|FILE|NONE}
定义一般查询日志和慢查询日志的保存方式,可以是TABLE、FILE、NONE,也可以是TABLE及FILE的组合(用逗号隔开),默认为TABLE。如果组合中出现了NONE,那么其它设定都将失效,同时,无论是否启用日志功能,也不会记录任何相关的日志信息。作用范围为全局级别,可用于配置文件,属动态变量。

log_query_not_using_indexes={ON|OFF}
设定是否将没有使用索引的查询操作记录到慢查询日志。作用范围为全局级别,可用于配置文件,属动态变量。

log_slave_updates
用于设定复制场景中的从服务器是否将从主服务器收到的更新操作记录进本机的二进制日志中。本参数设定的生效需要在从服务器上启用二进制日志功能。

log_slow_queries={YES|NO}
是否记录慢查询日志。慢查询是指查询的执行时间超出long_query_time参数所设定时长的事件。MySQL 5.6将此参数修改为了slow_query_log。作用范围为全局级别,可用于配置文件,属动态变量。

log_warnings=#
设定是否将警告信息记录进错误日志。默认设定为1,表示启用;可以将其设置为0以禁用;而其值为大于1的数值时表示将新发起连接时产生的“失败的连接”和“拒绝访问”类的错误信息也记录进错误日志。

long_query_time=#
设定区别慢查询与一般查询的语句执行时间长度。这里的语句执行时长为实际的执行时间,而非在CPU上的执行时长,因此,负载较重的服务器上更容易产生慢查询。其最小值为0,默认值为10,单位是秒钟。它也支持毫秒级的解析度。作用范围为全局或会话级别,可用于配置文件,属动态变量。

max_binlog_cache_size{4096 .. 18446744073709547520}
二进定日志缓存空间大小,5.5.9及以后的版本仅应用于事务缓存,其上限由max_binlog_stmt_cache_size决定。作用范围为全局级别,可用于配置文件,属动态变量。

max_binlog_size={4096 .. 1073741824}
设定二进制日志文件上限,单位为字节,最小值为4K,最大值为1G,默认为1G。某事务所产生的日志信息只能写入一个二进制日志文件,因此,实际上的二进制日志文件可能大于这个指定的上限。作用范围为全局级别,可用于配置文件,属动态变量。

max_relay_log_size={4096..1073741824}
设定从服务器上中继日志的体积上限,到达此限度时其会自动进行中继日志滚动。此参数值为0时,mysqld将使用max_binlog_size参数同时为二进制日志和中继日志设定日志文件体积上限。作用范围为全局级别,可用于配置文件,属动态变量。

innodb_log_buffer_size={262144 .. 4294967295}
设定InnoDB用于辅助完成日志文件写操作的日志缓冲区大小,单位是字节,默认为8MB。较大的事务可以借助于更大的日志缓冲区来避免在事务完成之前将日志缓冲区的数据写入日志文件,以减少I/O操作进而提升系统性能。因此,在有着较大事务的应用场景中,建议为此变量设定一个更大的值。作用范围为全局级别,可用于选项文件,属非动态变量。

innodb_log_file_size={108576 .. 4294967295}
设定日志组中每个日志文件的大小,单位是字节,默认值是5MB。较为明智的取值范围是从1MB到缓存池体积的1/n,其中n表示日志组中日志文件的个数。日志文件越大,在缓存池中需要执行的检查点刷写操作就越少,这意味着所需的I/O操作也就越少,然而这也会导致较慢的故障恢复速度。作用范围为全局级别,可用于选项文件,属非动态变量。

innodb_log_files_in_group={2 .. 100}
设定日志组中日志文件的个数。InnoDB以循环的方式使用这些日志文件。默认值为2。作用范围为全局级别,可用于选项文件,属非动态变量。

innodb_log_group_home_dir=/PATH/TO/DIR
设定InnoDB重做日志文件的存储目录。在缺省使用InnoDB日志相关的所有变量时,其默认会在数据目录中创建两个大小为5MB的名为ib_logfile0和ib_logfile1的日志文件。作用范围为全局级别,可用于选项文件,属非动态变量。


relay_log=file_name
设定中继日志的文件名称,默认为host_name-relay-bin。也可以使用绝对路径,以指定非数据目录来存储中继日志。作用范围为全局级别,可用于选项文件,属非动态变量。

relay_log_index=file_name
设定中继日志的索引文件名,默认为为数据目录中的host_name-relay-bin.index。作用范围为全局级别,可用于选项文件,属非动态变量。

relay-log-info-file=file_name
设定中继服务用于记录中继信息的文件,默认为数据目录中的relay-log.info。作用范围为全局级别,可用于选项文件,属非动态变量。


relay_log_purge={ON|OFF}
设定对不再需要的中继日志是否自动进行清理。默认值为ON。作用范围为全局级别,可用于选项文件,属动态变量。

relay_log_space_limit=#
设定用于存储所有中继日志文件的可用空间大小。默认为0,表示不限定。最大值取决于系统平台位数。作用范围为全局级别,可用于选项文件,属非动态变量。


slow_query_log={ON|OFF}
设定是否启用慢查询日志。0或OFF表示禁用,1或ON表示启用。日志信息的输出位置取决于log_output变量的定义,如果其值为NONE,则即便slow_query_log为ON,也不会记录任何慢查询信息。作用范围为全局级别,可用于选项文件,属动态变量。

slow_query_log_file=/PATH/TO/SOMEFILE
设定慢查询日志文件的名称。默认为hostname-slow.log,但可以通过--slow_query_log_file选项修改。作用范围为全局级别,可用于选项文件,属动态变量。


sql_log_bin={ON|OFF}
用于控制二进制日志信息是否记录进日志文件。默认为ON,表示启用记录功能。用户可以在会话级别修改此变量的值,但其必须具有SUPER权限。作用范围为全局和会话级别,属动态变量。

sql_log_off={ON|OFF}
用于控制是否禁止将一般查询日志类信息记录进查询日志文件。默认为OFF,表示不禁止记录功能。用户可以在会话级别修改此变量的值,但其必须具有SUPER权限。作用范围为全局和会话级别,属动态变量。

sync_binlog=#
设定多久同步一次二进制日志至磁盘文件中,0表示不同步,任何正数值都表示对二进制每多少次写操作之后同步一次。当autocommit的值为1时,每条语句的执行都会引起二进制日志同步,否则,每个事务的提交会引起二进制日志同步。








=============================================================================================
MySQL优化框架

1. SQL语句优化
2. 索引优化
3. 数据库结构优化
4. InnoDB表优化
5. MyISAM表优化
6. Memory表优化
7. 理解查询执行计划
8. 缓冲和缓存
9. 锁优化
10. MySQL服务器优化
11. 性能评估
12. MySQL优化内幕

MySQL优化需要在三个不同层次上协调进行:MySQL级别、OS级别和硬件级别。MySQL级别的优化包括表优化、查询优化和MySQL服务器配置优化等,而MySQL的各种数据结构又最终作用于OS直至硬件设备,因此还需要了解每种结构对OS级别的资源的需要并最终导致的CPU和I/O操作等,并在此基础上将CPU及I/O操作需要尽量降低以提升其效率。

数据库层面的优化着眼点:
1、是否正确设定了表结构的相关属性,尤其是每个字段的字段类型是否为最佳。同时,是否为特定类型的工作组织使用了合适的表及表字段也将影响系统性能,比如,数据频繁更新的场景应该使用较多的表而每张表有着较少字段的结构,而复杂数据查询或分析的场景应该使用较少的表而每张表较多字段的结构等。
2、是否为高效进行查询创建了合适的索引。
3、是否为每张表选用了合适的存储引擎,并有效利用了选用的存储引擎本身的优势和特性。
4、是否基于存储引擎为表选用了合适的行格式(row format)。例如,压缩表在读写操作中会降低I/O操作需求并占用较少的磁盘空间,InnoDB支持读写应用场景中使用压缩表,但MyISAM仅能在读环境中使用压缩表。
5、是否使用了合适的锁策略,如在并发操作场景中使用共享锁,而对较高优先级的需求使用独占锁等。同时,还应该考虑存储引擎所支持的锁类型。
6、是否为InnoDB的缓冲池、MyISAM的键缓存以及MySQL查询缓存设定了合适大小的内存空间,以便能够存储频繁访问的数据且又不会引起页面换出。

操作系统和硬件级别的优化着眼点:
1、是否为实际的工作负载选定了合适的CPU,如对于CPU密集型的应用场景要使用更快速度的CPU甚至更多数量的CPU,为有着更多查询的场景使用更多的CPU等。基于多核以及超线程(hyperthreading)技术,现代的CPU架构越来越复杂、性能也越来越强了,但MySQL对多CPU架构的并行计算能力的利用仍然是有着不太尽如人意之处,尤其是较老的版本如MySQL 5.1之前的版本甚至无法发挥多CPU的优势。不过,通常需要实现的CPU性能提升目标有两类:低迟延和高吞吐量。低延迟需要更快速度的CPU,因为单个查询只能使用一颗;而需要同时运行许多查询的场景,多CPU更能提供更好的吞吐能力,然而其能否奏效还依赖于实际工作场景,因为MySQL尚不能高效的运行于多CPU,并且其对CPU数量的支持也有着限制。一般来说,较新的版本可以支持16至24颗CPU甚至更多。
2、是否有着合适大小的物理内存,并通过合理的配置平衡内存和磁盘资源,降低甚至避免磁盘I/O。现代的程序设计为提高性能通常都会基于局部性原理使用到缓存技术,这对于频繁操作数据的数据库系统来说尤其如此——有着良好设计的数据库缓存通常比针对通用任务的操作系统的缓存效率更高。缓存可以有效地延迟写入、优化写入,但并能消除写入,并综合考虑存储空间的可扩展性等,为业务选择合理的外部存储设备也是非常重要的工作。
3、是否选择了合适的网络设备并正确地配置了网络对整体系统系统也有着重大影响。延迟和带宽是网络连接的限制性因素,而常见的网络问题如丢包等,即是很小的丢包率也会赞成性能的显著下降。而更重要的还有按需调整系统中关网络方面的设置,以高效处理大量的连接和小查询。
4、是否基于操作系统选择了适用的文件系统。实际测试表明大部分文件系统的性能都非常接近,因此,为了性能而苦选文件系统并不划算。但考虑到文件系统的修复能力,应该使用日志文件系统如ext3、ext4、XFS等。同时,关闭文件系统的某些特性如访问时间和预读行为,并选择合理的磁盘调度器通常都会给性能提升带来帮助。
5、MySQL为响应每个用户连接使用一个单独的线程,再加内部使用的线程、特殊目的线程以及其它任何由存储引擎创建的线程等,MySQL需要对这些大量线程进行有效管理。Linux系统上的NPTL线程库更为轻量级也更有效率。MySQL 5.5引入了线程池插件,但其效用尚不明朗。






使用InnoDB存储引擎最佳实践:
1、基于MySQL查询语句中最常用的字段或字段组合创建主键,如果没有合适的主键也最好使用AUTO_INCRMENT类型的某字段为主键。
2、根据需要考虑使用多表查询,将这些表通过外键建立约束关系。
3、关闭autocommit。
4、使用事务(START TRANSACTION和COMMIT语句)组合相关的修改操作或一个整体的工作单元,当然也不应该创建过大的执行单元。
5、停止使用LOCK TABLES语句,InnoDB可以高效地处理来自多个会话的并发读写请求。如果需要在一系列的行上获取独占访问权限,可以使用SELECT ... FOR UPDATE锁定仅需要更新的行。
6、启用innodb_file_per_table选项,将各表的数据和索引分别进行存放。
7、评估数据和访问模式是否能从InnoDB的表压缩功能中受益(在创建表时使用ROW_FORMAT=COMPRESSED选项),如果可以,则应该启用压缩功能。





EXPLAIN语句解析:
id:SELECT语句的标识符,一般为数字,表示对应的SELECT语句在原始语句中的位置。没有子查询或联合的整个查询只有一个SELECT语句,因此其id通常为1。在联合或子查询语句中,内层的SELECT语句通常按它们在原始语句中的次序进行编号。但UNION操作通常最后会有一个id为NULL的行,因为UNION的结果通常保存至临时表中,而MySQL需要到此临时表中取得结果。

select_type:
即SELECT类型,有如下值列表:
SIMPLE:简单查询,即没有使用联合或子查询;
PRIMARY:UNION的最外围的查询或者最先进行的查询;
UNION:相对于PRIMARY,为联合查询的第二个及以后的查询;
DEPENDENT UNION:与UNION相同,但其位于联合子查询中(即UNION查询本身是子查询);
UNION RESULT:UNION的执行结果;
SUBQUERY:非从属子查询,优化器通常认为其只需要运行一次;
DEPENDENT SUBQUERY:从属子查询,优化器认为需要为外围的查询的每一行运行一次,如用于IN操作符中的子查询;
DERIVED:用于FROM子句的子查询,即派生表查询;


table:
输出信息所关系到的表的表名,也有可能会显示为如下格式:
:id为M和N的查询执行联合查询后的结果;
:id为N的查询执行的结果集;


type:
MySQL官方手册中解释type的作用为“type of join(联结的类型)”,但其更确切的意思应该是“记录(record)访问类型”,因为其主要目的在于展示MySQL在表中找到所需行的方式。通常有如下所示的记录访问类型:
system: 表中仅有一行,是const类型的一种特殊情况;
const:表中至多有一个匹配的行,该行仅在查询开始时读取一次,因此,该行此字段中的值可以被优化器看作是个常量(constant);当基于PRIMARY KEY或UNIQUE NOT NULL字段查询,且与某常量进行等值比较时其类型就为const,其执行速度非常快;
eq_ref:类似于const,表中至多有一个匹配的行,但比较的数值不是某常量,而是来自于其它表;ed_ref出现在PRIMARY KEY或UNIQUE NOT NULL类型的索引完全用于联结操作中进行等值(=)比较时;这是除了system和const之外最好的访问类型;
ref:查询时的索引类型不是PRIMARY KEY或UNIQUE NOT NULL导致匹配到的行可能不惟一,或者仅能用到索引的左前缀而非全部时的访问类型;ref可被用于基于索引的字段进行=或<=>操作;
fulltext:用于FULLTEXT索引中用纯文本匹配的方法来检索记录。
ref_or_null:类似于ref,但可以额外搜索NULL值;
index_merge:使用“索引合并优化”的记录访问类型,相应地,其key字段(EXPLAIN的输出结果)中会出现用到的多个索引,key_len字段中会出现被使用索引的最长长度列表;将多个“范围扫描(range scan)”获取到的行进行合并成一个结果集的操作即索引合并(index merge)。
unique_subquery:用于IN比较操作符中的子查询中进行的“键值惟一”的访问类型场景中,如 value IN (SELECT primary_key FROM single_table WHERE some_expr);
index_subquery:类似于unique_subquery,但子查询中键值不惟一;
range:带有范围限制的索引扫描,而非全索引扫描,它开始于索引里的某一点,返回匹配那个值的范围的行;相应地,其key字段(EXPLAIN的输出结果)中会输出所用到的索引,key_len字段中会包含用到的索引的最长部分的长度;range通常用于将索引与常量进行=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN或IN()类的比较操作中;
index:同全表扫描(ALL),只不过是按照索引的次序进行而不行的次序;其优点是避免了排序,但是要承担按索引次序读取整个表的开销,这意味着若是按随机次序访问行,代价将非常大;
ALL:“全表扫描”的方式查找所需要的行,如果第一张表的查询类型(EXPLAIN的输出结果)为const,其性能可能不算太坏,而第一张表的查询类型为其它结果时,其性能通常会非常差;


Extra:
Using where:MySQL服务器将在存储引擎收到数据后进行“后过滤(post-filter)”以限定发送给下张表或客户端的行;如果WHERE条件中使用了索引列,其读取索引时就由存储引擎检查,因此,并非所有带有WHERE子句的查询都会显示“Using where”;
Using index:表示所需要的数据从索引就能够全部获取到,从而不再需要从表中查询获取所需要数据,这意味着MySQL将使用覆盖索引;但如果同时还出现了Using where,则表示索引将被用于查找特定的键值;
Using index for group-by:类似于Using index,它表示MySQL可仅通过索引中的数据完成GROUP BY或DISTINCT类的查询;
Using filesort:表示MySQL会对结果使用一个外部索引排序,而不是从表里按索引次序来读取行;

====================================================================================
Mysql备份类型
热备份:读写均不受影响
温备份:仅可以执行读操作
冷备份:离线备份,读写均停止

物理备份和逻辑备份
物理备份:复制数据文件,速度快,
逻辑备份:将数据导出至文本文件中,速度慢,容易丢失浮点精度,可移植能力强

完全备份、增量备份、差异备份
完全备份:备份所有数据
增量备份:仅备份上次完全备份后增加的数据
差异备份:以完全备份为准,备份差异数据,可能出现包含

备份什么?数据,配置文件,二进制日志,事务日志


MyISAM:温备份
InnoDB:热备份xtrabackup,mysqldump

Mysql备份工具:
mysqldump:逻辑备份工具(对于MyISAM-温备份,对于Innodb-热备份)
mysqlhotcopy:物理备份工具、温备份

文件系统工具:
cp:冷备用
lv:逻辑卷快照,几乎热备
    mysql>FLUSH TABLES;
    mysql>LOCK TABLES;
    创建快照,释放锁,而后复制数据

第三方工具:
ibbackup:商业工具
xtrabackup:开源工具


mysqldump使用

mysql> FLUSH TABLES WITH READ LOCK;
root#mysqldump -uroot -p jiaowu > /root/jiaowu.sql
mysql> UNLOCK TABLES;
mysql> FLUSH LOGS;
mysql> SHOW BINARY LOGS;


--master-data={0|1|2}
    0: 不记录二进制日志文件及路位置;
    1:以CHNAGE MASTER TO的方式记录位置,可用于恢复后直接启动从服务器;
    2:以CHANGE MASTER TO的方式记录位置,但默认为被注释;


将二进制日志的保存点记录在日志中,下次接着备份就可以
root#mysqldump -uroot -p --master-data=2 studb > /root/studb-`data +%F-%H-%M-%S`.sql

--lock-all-tables:锁定所有表
--flush-logs:执行日志flush滚动

如果指定库中的表类型均为InnoDB,可使用--single-transaction启动热备份

备份多个库:
    --all-databases:备份所有库
    --databases DB_NAME,DB_NAME :备份指定库

备份所有库(完全备份)
root# mysqldump -uroot -p --lock-all-tables --flush-logs --all-databases --master-data=2 > /root/all.sql
mysql>PURGE BINARY LOGS TO 'mysql-bin.000011' (复制完二进制文件后,删除11之前的日志)
root# mysqlbinlog mysql-bin.0000111 > /root/mon-incremental.sql

 备份策略:每周完全+每日增量
    完全备份:mysqldump
    增量备份:备份二进制日志文件(flush logs)

模拟:
root# mysql_install_db --user=mysql --datadir=/mydata/data
root# service mysqld start
root# mysql -uroot -p < alldatabases.sql(导入完整) 因为初始化,root暂时为空密码
root# mysql -uroot -p < mon-incremental.sql(导入增量)

===(待续)

远程连接

一般在公司开发中,可能会将数据库统一搭建在一台服务器上,所有开发人员共用一个数据库,而不是在自己的电脑中配置一个数据库
运行命令
mysql -hip地址 -uroot -p
-h后面写要连接的主机ip地址
-u后面写连接的用户名
-p回车后写密码
数据库操作

创建数据库
create database 数据库名 charset=utf8;
删除数据库
drop database 数据库名;
切换数据库
use 数据库名;
查看当前选择的数据库
select database();
表操作

查看当前数据库中所有表
show tables;
创建表
auto_increment表示自动增长

create table 表名(列及类型);
如:
create table students(
id int auto_increment primary key,
sname varchar(10) not null
);
修改表

alter table 表名 add|change|drop 列名 类型;
如:
alter table students add birthday datetime;
删除表
drop table 表名;
查看表结构
desc 表名;
更改表名称
rename table 原表名 to 新表名;
查看表的创建语句
show create table '表名';
数据操作

查询
select * from 表名
增加
全列插入:insert into 表名 values(...)
缺省插入:insert into 表名(列1,...) values(值1,...)
同时插入多条数据:insert into 表名 values(...),(...)...;insert into 表名(列1,...) values(值1,...),(值1,...)...;
主键列是自动增长,但是在全列插入时需要占位,通常使用0,插入成功后以实际数据为准
修改
update 表名 set1=值1,... where 条件
删除
delete from 表名 where 条件
逻辑删除,本质就是修改操作update
alter table students add isdelete bit default 0;
如果需要删除则
update students isdelete=1 where ...;
备份与恢复

数据备份

进入超级管理员
sudo -s
进入mysql库目录
cd /var/lib/mysql
运行mysqldump命令
mysqldump –uroot –p 数据库名 > ~/Desktop/备份文件.sql;
按提示输入mysql的密码
数据恢复

连接mysqk,创建数据库

退出连接,执行如下命令

mysql -uroot –p 数据库名 < ~/Desktop/备份文件.sql
根据提示输入mysql密码


字符串函数

查看字符的ascii码值ascii(str),str是空串时返回0
select ascii('a');
查看ascii码值对应的字符char(数字)
select char(97);
拼接字符串concat(str1,str2...)
select concat(12,34,'ab');
包含字符个数length(str)
select length('abc');
截取字符串
left(str,len)返回字符串str的左端len个字符
right(str,len)返回字符串str的右端len个字符
substring(str,pos,len)返回字符串str的位置pos起len个字符
select substring('abc123',2,3);
去除空格
ltrim(str)返回删除了左空格的字符串str
rtrim(str)返回删除了右空格的字符串str
trim([方向 remstr from str)返回从某侧删除remstr后的字符串str,方向词包括both、leading、trailing,表示两侧、左、右
select trim('  bar   ');
select trim(leading 'x' FROM 'xxxbarxxx');
select trim(both 'x' FROM 'xxxbarxxx');
select trim(trailing 'x' FROM 'xxxbarxxx');
返回由n个空格字符组成的一个字符串space(n)
select space(10);
替换字符串replace(str,from_str,to_str)
select replace('abc123','123','def');
大小写转换,函数如下
lower(str)
upper(str)
select lower('aBcD');
数学函数

求绝对值abs(n)
select abs(-32);
求m除以n的余数mod(m,n),同运算符%
select mod(10,3);
select 10%3;
地板floor(n),表示不大于n的最大整数
select floor(2.3);
天花板ceiling(n),表示不小于n的最大整数
select ceiling(2.3);
求四舍五入值round(n,d),n表示原数,d表示小数位置,默认为0
select round(1.6);
求x的y次幂pow(x,y)
select pow(2,3);
获取圆周率PI()
select PI();
随机数rand(),值为0-1.0的浮点数
select rand();
还有其它很多三角函数,使用时可以查询文档
日期时间函数

获取子值,语法如下
year(date)返回date的年份(范围在1000到9999)
month(date)返回date中的月份数值
day(date)返回date中的日期数值
hour(time)返回time的小时数(范围是0到23)
minute(time)返回time的分钟数(范围是0到59)
second(time)返回time的秒数(范围是0到59)
select year('2016-12-21');
日期计算,使用+-运算符,数字后面的关键字为year、month、day、hour、minute、second
select '2016-12-21'+interval 1 day;
日期格式化date_format(date,format),format参数可用的值如下

获取年%Y,返回4位的整数

* 获取年%y,返回2位的整数

* 获取月%m,值为1-12的整数

获取日%d,返回整数

* 获取时%H,值为0-23的整数

* 获取时%h,值为1-12的整数

* 获取分%i,值为0-59的整数

* 获取秒%s,值为0-59的整数

select date_format('2016-12-21','%Y %m %d');
当前日期current_date()
select current_date();
当前时间current_time()
select current_time();
当前日期时间now()
select now();


外键

思考:怎么保证关系列数据的有效性呢?任何整数都可以吗?
答:必须是学生表中id列存在的数据,可以通过外键约束进行数据的有效性验证
为stuid添加外键约束
alter table scores add constraint stu_sco foreign key(stuid) references students(id);
此时插入或者修改数据时,如果stuid的值在students表中不存在则会报错
在创建表时可以直接创建约束
create table scores(
id int primary key auto_increment,
stuid int,
subid int,
score decimal(5,2),
foreign key(stuid) references students(id),
foreign key(subid) references subjects(id)
);
外键的级联操作

在删除students表的数据时,如果这个id值在scores中已经存在,则会抛异常
推荐使用逻辑删除,还可以解决这个问题
可以创建表时指定级联操作,也可以在创建表后再修改外键的级联操作
语法
alter table scores add constraint stu_sco foreign key(stuid) references students(id) on delete cascade;
级联操作的类型包括:
restrict(限制):默认值,抛异常
cascade(级联):如果主表的记录删掉,则从表中相关联的记录都将被删除
set null:将外键设置为空
no action:什么都不做

你可能感兴趣的:(Linux-系统运维)