MariaDB & MySQL:
DBMS;
RDBMS,relation DB management system:
C/S,通过专有协议;
关系模型(表,行&列,二维关系);
范式(第一范式,第二范式,第三范式);
关系运算(选择,投影);
数据库(表,索引,视图(虚表);SQL,structure query language;编程接口(UDF,user define function,存储过程,存储函数,触发器,事件调度器event scheduler;过程式编程(选择,循环));
三层模型(物理层,逻辑层,视图层);
解决方案(oracle,sybase,infomix,DB2,MySQL,MariaDB,postgresql,sqlite(嵌入式));
MariaDB:
插件式存储引擎,>SHOW ENGINES;
单进程多线程(连接线程,守护线程);
配置文件(集中式的配置,
能为mysql的各应用程序提供配置信息,[mysqld],[mysqld_safe],[mysql_multi],[server],[mysql],[mysqldump];
parameter = value,大多数参数都支持-或_,如skip-name-resolve或skip_name_resolve,尽量统一用一种;
查找路径,/etc/my.cnf-->/etc/mysql/my.cnf-->$MYSQL_HOME/my.cnf-->--default-extra-file=/PATH/TO/SOMEDIR/my.cnf-->~/.my.cnf);
安装方法(
OS vender(rpm);
MySQL官方(rpm,二进制包(展开即可用),源码编译安装));
安装后的设定(
1、
为所有root用户设定密码:
>SET PASSWORD #方式1
>UPDATE mysql.user SET password=PASSWORD(‘your_pass‘) WHERE user=‘myuser‘;
>FLUSH PRIVILEGES; #方式2
#mysqladmin #方式3
2、
删除所有匿名用户:
>DROP USER ‘myuser‘@‘localhost‘;
3、
建议关闭主机名反解功能:
skip_name_resolve
注:1、2在安装完后运行#mysql_secure_installation命令会有提示操作
);
元数据数据库(mysql库,user,host等表);
mysql<-->mysqld:
客户端程序:
#mysql #交互式CLI工具;
#mysqldump #备份工具,基于mysql协议向mysqld发起查询请求,并将查得的所有数据转换成insert语句保存在文本文件中;
#mysqladmin #基于mysql协议管理mysqld;
#mysqlimport #数据库导入工具;
常用选项:
-u --user
-h --host
-p --password
-P --port
--protocol=tcp|sock
-S --socket
-D --database
-C --compress
-e "SQL",如#mysql -e"SHOW DATABASES";
非客户端类的管理工具:
#myisamchk
#myisampack
如何获取程序默认使用的配置:
#mysql --print-defaults
#mysql --verbose [--help]
mysql的使用模式:
交互式模式,可运行命令两类(
客户端命令,\h
服务器端命令,SQL,需要语句结束符
);
脚本模式(
#mysql -uUSERNAME -hHOST -pPASSWORD < /PATH/FROM/file.sql
>source /PATH/FROM/file.sql
);
服务器端:
mysql工作特性有多种定义方式:配置文件参数,命令行选项;
#mysql --verbose [--help] #获取可用参数列表;
>SHOW GLOBAL VARIABLES [LIKE ‘%sql%‘]; #获取运行中的mysql进程使用的服务器参数及值;其中有些参数支持运行时修改,会立即生效;有些参数不支持运行时修改,只能通过修改配置文件,并重启服务才生效;有些参数作用域是全局的,不可改变;有些参数可为单个用户提供单独的配置;
>SHOW [SESSION] VARIABLES;
修改服务器变量的值:
>help SET
>SET GLOBAL system_var_name=value; #或>[email protected]@GLOBAL.system_var_name=value;全局,需要修改权限,仅对修改后新创建的会话有效,对已经建立的会话无效;
>SET [SESSION] system_var_name=value; #或>[email protected]@[SESSION.]system_var_name=value;会话;
状态变量:
用户保存mysql运行中统计数据的变量;
>SHOW GLOBAL STATUS;
>SHOW [SESSION] STATUS;
SQL:
ANSI SQL标准;SQL-86,SQL-89,SQL-92,SQL-99,SQL-03;
MySQL数据类型:
字符型:
CHAR,BINARY #(定长数据类型);
VARCHAR,VARBINARY #(变长数据类型,需要结束符);
TINYTEXT,TEXT,MEDIUMTEXT,LONGTEXT #(2^8,2^16,2^24,2^32,字符个数);
TINYBLOB,BLOB,MEDIUMBLOB,LONGBLOB #(2^8,2^16,2^24,2^32);
ENUM,SET;
数值型:
TINYINT,SMALLINT,MEDIUMINT,INT,BIGINT #(精确数值型,整型);
DECIMAL #(十进制型);
FLOAT #(近似数值型,浮点型);
DOUBLE;
日期时间型:
DATE;
TIME;
DATETIME;
TIMESTAMP;
YEAR(2),YEAR(4);
字符型修饰符:
NOT NULL #非空约束;
NULL;
DEFAULT ‘STRING‘ #指明默认值;
CHARACTER SET ‘‘ #使用的字符集,>SHOW CHARACTER SET;
COLLATION #排序规则,>SHOWCOLLATON;
内建类型(ENUM,SET)修饰符:
NOT NULL;
NULL;
DEFAULT;
整型数据修饰符:
NOT NULL;
NULL;
DEFAULT NUMBER;
AUTO_INCREMENT #内置LAST_INSERT_ID(),UNSIGNED,PRIMARY KEY|UNIQUE KEY,NOT NULL
时期时间型修饰符:
NOT NULL;
NULL;
DEFAULT;
SQL mode:
定义mysql对约束的响应行为;
>SET GLOBAL sql_mode=‘MODE‘; #或>[email protected]@GLOBAL.sql_mode=‘MODE‘;
MODE有:
TRADITIONAL;
STRICT_TRANS_TABLES #对事务的表严格约束;
STRICT_ALL_TABLES #对所有表严格约束;
DB组件:
数据库;
表;
索引;
视图;
用户;
存储过程;
存储函数;
触发器;
事件调度器等;
DDL,data define language,数据定义语言,CREATE,ALTER,DROP;
DML,data manipulatelanguage,数据操作语言,CRUD,INSERT,DELETE,UPDATE,SELECT,DELETE和UPDATE一定要有WHERE限制条件,否则将清空或修改所有数据;
DQL,data query language,SELECT;
数据库:
CREATE|ALTER|DROP {DATABASE|SCHEMA} [IF [NOT] EXISTS]
表:
二维关系;
设计表(遵循规范);
定义:字段,字段数据类型,修饰符;
约束;
创建表(
CREATE TABLE,直接创建;
通过查询现存的表创建,新表会被直接插入查询而来的数据;
通过复制现存的表的结构创建,不复制数据);
查看表结构(
>DESCRIBE tbl_name;
>SHOW TABLES STATUS LIKE ‘tbl‘\G;);
修改表(>ALTER TABLE);
删除表(>DROP TABLE);
>HELP CREATE TABLE
>HELP ALTER TABLE
>HELP SHOW INDEX
>use hellodb;
>SHOW INDEXES FROM students;
>EXPLAIN SELECT * FROM students WHERE sutID=3\G; #(根据primarykey查询,rows:1);
>EXPLAIN SELECT * FROM students WHERE Age=53\G; #(非primary key则会扫描全表,rows=25);
>ALTER TABLE students ADD INDEX(Age);
>SHOW INDEXES FROM students;
>EXPLAIN SELECT * FROM students WHERE Age=53\G; #(rows:1)
>CREATE INDEX name ON students(Name);
>SHOW INDEXES FROM students;
>EXPLAIN SELECT * FROM students WHERE Name LIKE‘X%‘; #(rows:6,使用索引)
>EXPLAIN SELECT * FROM students WHERE Name LIKE‘%X%‘; #(rows:25,全表扫描,未使用索引,mysql是最左前缀索引)
view视图:
视图中的数据事实上存储于基表中,因此修改操作也是针对基表实现,受基表限制;
>HELP CREATE VIEW
>HELP DROP VIEW
>CREATE VIEW test AS SELECT stuID,Name,Age FROM students;
>SHOW TABLES;
>SHOW TABLE STATUS LIKE ‘test‘\G #(comment:VIEW,其它都为NULL)
>EXPLAIN SELECT * FROM test WHERE Age=22; #(在基表students中查询)
INSERT INTO(3种syntax,ONDUMPLICATE KEY UPDATE有重复键时直接更新替换):
>INSERT INTO students (Name,Age,Gender) VALUES (‘jinjiao‘,100,‘M‘);
>INSERT INTO students SET Name=‘jinjiao‘,Age=100,Gender=‘M‘;
>INSERT INTO students (Name,Age,Gender) SELECT * FROM stu;
>HELP DELETE(要限制条件WHERE,LIMIT);
>DELETE FROM tbl_name WHERE CONDITION;
>HELP UPDATE
>UPDATE tbl_name SET col1=value1,col2=value2,WHERE CONDITION;
>SELECT now();
the clauses of the SELECT statement:
FROM clause-->WHERE clause-->GROUPBY-->HAVING clause-->ORDER BY-->SELECT-->LIMIT
单表查询:
DISTINCT #(数据去重);
SQL_CACHE #(显示指定存储查询结果于缓存之中);
SQL_NO_CACHE #(显示查询结果不予缓存);
注:
查询缓存功能打开query_cache_type=ON时,SQL_CACHE和SQL_NO_CACHE,SELECT的结果符合缓存条件即会缓存,否则不予缓存;
query_cache_type=demand时,查询缓存功能按需进行,显式指定SQL_CACHE的SELECT语句才会缓存,其它均不予缓存;
>SHOW GLOBAL VARIABLES LIKE ‘query%‘;
query_cache_size
query_cache_type
>SHOW GLOBAL VARIABLES LIKE ‘Qcache%‘;
Qcache_hits
>SHOW GLOBAL VARIABLES LIKE ‘Com_select‘;
Com_select #(查询的次数);
注:
Com_select和Qcache_hits结合查看;
字段显示可使用别名:
col1 AS alias1,col2 AS alias2
WHERE子句:
指明过滤条件实现选择功能;
过滤条件:布尔型表达式;
算术操作符:+-*/%
比较操作符:
=,>,>=,<,<=
!=和<>表示不等于
<=> #NULL,safe equal to
BETWEEN min_num AND max_num
IN(element1,element2,...) #可理解于多值等于
IS NULL #例如>SELECT... WHERE classID IS NULL,而不能用WHERE classID=NULL或WHERE classID=‘NULL‘
IS NOT NULL
LIKE #使用通配符,%表示任意长度任意字符,_表示任意单个字符
RLIKE #或REGEXP,匹配字符串,可用正则书写
逻辑操作符:
NOT
AND
OR
XOR
GROUP:
根据指定的条件把查询结果进行分组,以用于做聚合运算;
avg()
max()
min()
count()
sum()
HAVING:
对分组聚合运算后的结果指定过滤条件;
ORDER BY:
根据指定的字段对查询结果进行排序;
ASC #升序
DESC #降序
LIMIT [[offset,]row_count]:
对查询结果进行输出行数数量限制;
举例:
>SELECT avg(Age),Gender FROM students GROUP BY Gender;
>SELECT avg(Age) AS AAge,Gender FROM students GROUP BY Gender HAVING AAge>20;
>SELECT count(stuID) AS NOS,classID FROM students GROUP BY classID HAVING NOS>2;
>SELECT Name,Age FROM students ORDER BY Age DESC;
>SELECT Name,Age FROM students ORDER BY Age DESC LIMIT 10,10;
对查询结果中的数据请求施加锁:
FOR UPDATE #写锁,排它锁;
LOCK IN SHARE MODE #读锁,共享锁;
多表查询:
交叉连接 #笛卡尔乘积,最不高效;
>SELECT * FROM students,teachers;
等值连接 #常用
>SELECT * FROM students,teachers WHERE students.teacherID=teachers.TID;
>EXPLAIN SELECT s.Name AS stuName,t.Name AS teaName FROM students AS s,teachers AS t WHERE s.teacherID=t.TID;
>SELECT s.Name,c.Class FROM students AS s,Class AS c WHERE s.classID=c.classID; #学生对班级;
不等值连接
自然连接
自连接 #一张表当两张表用;
外连接:
左外连接,>... FROM tb1 LEFT JOIN tb2 ON tb1.col=tb2.col;,以左表为准,有等值连接予以显示,有不等值的右表字段留空即左表字段内容必须出现;
右外连接,>... FROM tb1 RIGHT JOIN tb2 ON tb1.col=tb2.col;,以右表为准,有等值连接的予以显示,有不等值连接的左表字段留空即右表字段内容必须出现;
>SELECT s.Name,c.Class FROM students AS s LEFT JOIN Class AS c ON s.classID=c.classID;
子查询:
查询语句中嵌套着查询语句,基于某语句的查询结果再次进行的查询;
MySQL对子查询的优化力度不够,不建议使用;
用在WHERE子句中的子查询,用于比较表达式中的子查询,子查询仅能返回单个值;
>EXPLAIN SELECT Name,Age FROM students WHERE Age> (SELECT avg(Age) FROM students);
用于在IN中的子查询,子查询要返回一个或多个值,从而构成一个列表;
>SELECT Name,Age FROM students WHERE Age IN(SELECT Age FROM teachers);
用于EXISTS;
用在FROM子句中的子查询;
格式:>SELECT tbl_alias.col1,... FROM (SELECT clause) AS tb_alias WHERE clause;
举例:每一个班级的平均年龄大于30
>SELECT aage,classID FROM (SELECT avg(Age) AS aage,classID FROM students WHERE classID IS NOT NULL GROUP BY classID) AS s WHERE s.aage>30;
UNION联合查询:
>EXLAIN SELECT Name,Age FROM students UNION SELECT Name,Age FROM teachers; #会显示为3个查询语句;
注:
MySQL(5.1-->5.5-->5.6-->5.7);
--no-auto-rehash #命令行补全相关;
当SQL语句执行后反馈信息有warning时,可用>SHOW WARNINGS;查看;
所有SHOW命令都支持通配符%;
storage engine是指表类型,即在表创建时指明使用的storage engine,同一个库中的表要使用同一种storage engine,>SHOW GLOBAL VARIABLES LIKE ‘default_storage_engine‘;
两类认证(authentication,object privilege);
MySQL索引,是[最]左前缀索引,如果查询时LIKE‘%sql%‘将不会使用索引,查询时尽量避免使用‘%sql%‘;
DELETE和UPDATE一定要有WHERE限制条件,否则将清空或修改所有数据;
skip_name_resolve,关闭主机名反解,否则授权的用户在登录时有问题;
查询语句任何字符上的不同(如大小写),都会导致缓存不能命中;
若对某字段作算术运算将无法使用索引,如>SELECT * FROM students WHERE Age+20>50;
若某索引用不上,最好不要创建它,会降低写性能;
复杂类型的查询有三种:简单子查询,用于FROM中的子查询,UNION联合查询;有UNION查询的分析结果会出现一个额外的警钟临时表;
MySQL architecture:
MySQL数据文件类型:
数据文件;
索引文件;
redo log,undo log,binary log,error log,query log,slow query log,relay log;
1、执行启动MySQL 命令之后,MySQL的初始化模块就从系统配置文件中读取系统参数和命令行参数,并按照参数来初始化整个系统,如申请并分配buffer,初始化全局变量,以及各种结构等。同时各个存储引擎也被启动,并进行各自的初始化工作。
2、当整个系统初始化结束后,由连接管理模块接手。连接管理模块会启动处理客户端连接请求的监听程序,包括tcp/ip的网络监听,还有unix的socket。这时,MySQL Server基本启动完成,准备好接受客户端请求。
3、当连接管理模块监听到客户端的连接请求(借助网络交互模块的相关功能),双方通过Client & Server交互协议模块所定义的协议“寒暄”几句之后,连接管理模块就会将连接请求转发给线程管理模块,去请求一个连接线程。
4、线程管理模块马上又会将控制交给连接线程模块,告诉连接线程模块:现在我这边有连接请求过来了,需要建立连接,你赶快处理一下。
5、连接线程模块在接到连接请求后,首先会检查当前连接线程池中是否有被cache 的空闲连接线程,如果有,就取出一个和客户端请求连接上,如果没有空闲的连接线程,则建立一个新的连接线程与客户端请求连接。
6、当然,连接线程模块并不是在收到连接请求后马上就会取出一个连接线程和客户端连接,而是首先通过调用用户模块进行授权检查,只有客户端请求通过了授权检查后,他才会将客户端请求和负责请求的连接线程连上。在MySQL 中,将客户端请求分为了两种类型:一种是query,需要调用Parser也就是Query解析和转发模块的解析才能够执行的请求;一种是command,不需要调用Parser就可以直接执行的请求。如果我们的初始化配置中打开了Full Query Logging 的功能,那么Query解析与转发模块会调用日志记录模块将请求计入日志,不管是一个Query类型的请求还是一个command 类型的请求,都会被记录进入日志,所以出于性能考虑,一般很少打开Full Query Logging 的功能。
7、当客户端请求和连接线程“互换暗号(互通协议)”接上头之后,连接线程就开始处理客户端请求发送过来的各种命令(或者query),接受相关请求。它将收到的query 语句转给Query解析和转发模块,Query解析器先对Query进行基本的语义和语法解析,然后根据命令类型的不同,有些会直接处理,有些会分发给其他模块来处理。
8、如果是一个Query 类型的请求,会将控制权交给Query解析器。Query 解析器首先分析看是不是一个select 类型的query,如果是,则调用查询缓存模块,让它检查该query 在query cache 中是否已经存在。如果有,则直接将cache 中的数据返回给连接线程模块,然后通过与客户端的连接的线程将数据传输给客户端。如果不是一个可以被cache 的query类型,或者cache 中没有该query 的数据,那么query 将被继续传回query 解析器,让query解析器进行相应处理,再通过query分发器分发给相关处理模块。
9、如果解析器解析结果是一条未被cache的select 语句,则将控制权交给Optimizer,也就是Query优化器模块。
10、如果是DML 或者是DDL 语句,则会交给表变更管理模块。表变更管理模块根据所对应的处理请求的不同,是分别由insert处理器、delete处理器、update处理器、create处理器,以及alter处理器这些小模块来负责不同的DML和DDL的。
11、如果是一些更新统计信息、检测、修复和整理类的query 则会交给表维护模块去处理。
12、复制相关的query则转交给复制模块去进行相应的处理。
13、请求状态的query则转交给了状态收集报告模块。
14、在各个模块收到Query解析与分发模块分发过来的请求后,首先会通过访问控制模块检查连接用户是否有访问目标表以及目标字段的权限。
15、如果有,就会调用表管理模块请求相应的表,并获取对应的锁。表管理模块首先会查看该表是否已经存在于table cache中,如果已经打开则直接进行锁相关的处理,如果没有在cache中,则需要再打开表文件获取锁,然后将打开的表交给表变更管理模块。
16、当表变更管理模块“获取”打开的表之后,就会根据该表的相关meta信息,判断表的存储引擎类型和其他相关信息。根据表的存储引擎类型,提交请求给存储引擎接口模块,调用对应的存储引擎实现模块,进行相应处理。
17、当一条query或者一个command处理完成(成功或者失败)之后,控制权都会交还给连接线程模块。如果处理成功,则将处理结果(可能是一个Result set,也可能是成功或者失败的标识)通过连接线程反馈给客户端。如果处理过程中发生错误,也会将相应的错误信息发送给客户端,然后连接线程模块会进行相应的清理工作,并继续等待后面的请求,重复上面提到的过程,或者完成客户端断开连接的请求。
18、如果在上面的过程中,相关模块使数据库中的数据发生了变化,而且MySQL 打开了binlog功能,则对应的处理模块还会调用日志处理模块将相应的变更语句以更新事件的形式记录到相关参数指定的二进制日志文件中。
19、在上面各个模块的处理过程中,各自的核心运算处理功能部分都会高度依赖整个MySQL的核心API 模块,比如内存管理,文件I/O,数字和字符串处理等等。
MySQL用户和权限管理:
权限类别:
库级别;表级别;字段级别;管理类;程序类;
管理类:
CREATE TEMPORARY TABLES
CRATE USER
FILE
SUPER
SHOW DATABASES
RELOAD
SHUTDOWN
REPLICATION SLAVE
REPLICATION CLIENT
LOCK TABLES
PROCESS
程序类:
CREATE
ALTER [FUNCTION|PROCEDURE|TRIGGER]
DROP
EXECUTE
库DATABASE和表TABLE级别:
ALTER
CREATE
CREATE VIEW
DROP
INDEX
SHOW VIEW
GRANT OPTION #能把自己获得的权限赠给其他用户一个副本;
数据操作:
SELECT;INSERT;DELETE;UPDATE;
字段级别:
SELECT (col1,col2,...)
UPDATE (col1,col2,...)
INSERT (col1,col2,...)
所有:
ALL PRIVILEGES
元数据数据库:
mysql库;
>USE mysql;
>SHOW TABLES;
授权表:
db,host,user;
columns_priv,tables_priv,procs_priv,proxies_priv;
用户账号:
‘USERNAME‘@‘HOST‘
@‘HOST‘ #主机名,ip地址,network,通配符%或_;
创建用户:
>CREATE USER ‘USERNAME‘@‘HOST‘ [IDENTIFIED BY‘password‘];
查看用户获得的授权:
>SHOW GRANTS FOR ‘USERNAME‘@‘HOST‘;
重命名用户:
>RENAME USER old_user_name TO new_user_name;
删除用户:
>DROP USER ‘USERNAME‘@‘HOST‘;
修改密码:
>SET PASSWORD FOR #方式1
>UPDATE myql.user SET password=PASSWORD(‘your_password‘) WHERE clause;
>FLUSH PRIVILEGES; #方式2
#mysqladmin [options] command #方式3
忘记管理员密码:
启动mysqld进程时,使用--skip-grant-tables和--skip-networking,--skip-networking禁用远程登录;
使用UPDATE命令修改管理员密码;
关闭mysqld进程,去掉--skip-grant-tables和--skip-networking,再启动mysqld;
>HELP GRANT #授权
>GRANT priv_type[,...] ON [{table|function|procedure}] db.{table|routine} TO ‘USERNAME‘@‘HOST‘[IDENTIFIED BY ‘YOUR_PASSWORD‘ [REQUIRE SSL] [WITH with_option];
object type:
TABLE
FUNCTION #存储函数;
PROCEDURE #存储过程;
priv_level:
db_name.routine_name #(存储过程或存储函数);
with_option:
GRANT OPTION
>REVOKE priv_type[,...] ON [{table|funciton|procedure}] db.{table|routine} FROM ‘USERNAME‘@‘HOST‘; #取消授权
caching with MySQL查询缓存:
查询的执行路径:
组件:查询缓存,解析器,预处理器,优化器,查询执行引擎,存储引擎;
如何判断是否命中:通过查询语句的哈希值判断;
哈希值考虑的因素包括:查询本身,要查询的DB,client使用的协议版本...
查询语句任何字符上的不同(如大小写),都会导致缓存不能命中;
哪些查询可能不会被缓存:查询中包含UDF,user define function,存储函数,用户自定义变量,临时表,mysql库的系统表,包含列级权限的表,有着不确定值的函数(如now());
查询缓存相关的服务器变量:
>SHOW GLOBAL VARIABLES LIKE ‘query%‘;
query_cache_min_res_unit #res即result,4096byte(查询结果小于该值不缓存),查询缓存中内存块的最小分配单位,较小的值会减少浪费,但会导致更频繁的内存分配操作,较大值会带来浪费会导致碎片过多;
query_cache_limit #能缓存的最大查询结果,对于有着较大结果的查询语句,建议在SELECT中使用SQL_NO_CACHE;
query_cache_size #查询缓存总共可用的内存空间,单位字节,必须是1024的整数倍;
query_cache_type #ON,OFF,DEMAND;
query_cache_wlock_invalidate #如果某表被其它的连接锁定,是否仍可从查询缓存中返回结果;默认OFF表示可在被其它连接锁定的场景中继续从缓存返回数据,ON表示不允许;
缓存命中率的评估:
Qcache_hits/(Qcache_hits + Com_select)
MySQL中的index:
基本法则:索引应构建在被用作查询条件的字段上;
索引实现级别在storage engine;
索引管理,按特定数据结构存储的数据;
索引不需修改,创建&删除,创建索引时不要在不验证的情况下轻易的在生产上操作;
若对某字段作算术运算将无法使用索引,如>SELECT * FROM students WHERE Age+20>50;
若某索引用不上,最好不要创建它,会降低写性能;
在查询时尽量避免使用‘%sql%‘;
管理索引的途径(
1、
创建表时指定,>CREATE INDEX;
2、
通过修改表的命令,创建或删除索引;
3、
删除索引,索引不需修改);
索引分类,索引类型(
稠密索引(字段中的所有记录),稀疏索引(字段的部分数据,有一级、二级、三级、四级),是否索引了每一个数据项;
B+Tree索引(balance),hash索引,R-Tree空间索引(MyISAM支持空间索引),FULLTEXT全文索引(在文本中查找关键词);
聚集索引(该索引存放实际数据),非聚集索引(该索引只是指针指向源数据),数据是否与索引存储在一起;
简单索引,组合索引;
主键索引(一对一查询),辅助索引(额外辅助其它查询操作);
常用索引类型:
B+Tree:
顺序存储,每一个叶子节点到根节点的距离是相同的;
左前缀索引,适合查询范围类的数据;
可使用B+Tree索引的查询类型(适用场景):
全键值,键值范围或键前缀查找;
全值匹配,精确到某个值,如‘jinjiao king‘;
匹配最左前缀,只精确匹配开头部分,如‘jin%‘;
匹配范围值;
精确匹配某一列并范围匹配另一列;
只访问索引的查询;
不适用场景:
如果不从最左列开始,索引无效,如(Age,Name)若根据Name查找则索引无效,(Name,Age)若根据Age查找则索引无效;
不能跳过索引中的列,如(stuID,Name,Age),不能跳过Name;
如果查询中某个列是范围查询,那么右侧的列都无法再使用索引优化查询,如(stuID,Name);
hash索引:
基于哈希表实现,适用于精确匹配索引中的所有列;
只有memory存储引擎支持显示hash索引;
适用场景:
只支持等值比较查询,如=,IN(),<=>;
不适用场景:
不适用于顺序查询(值不是按顺序存储的);
不支持模糊匹配;
索引的优点:
可降低服务器需要扫描的数据量,减少了io次数;
可帮助服务器避免排序和使用临时表;
可帮助将随机io转为顺序io;
高性能索引策略:
独立使用列(不要让列参与运算),尽量避免参与运算;
左前缀索引,索引构建于字段的左侧的多少个字符,要通过索引选择性(不重复的索引值和数据表的记录总数的比值)来评估;
多列索引(组合索引),顺序很关键,AND操作时更适合使用多列索引;
选择合适的索引列次序,将选择性最高的放左侧;
冗余和重复索引:
不好的索引使用策略,如有(Name,Age)则(Name)是多余的;
EXPLAIN:
通过EXPLAIN来分析索引的有效性,获取查询执行计划信息,用来查看查询优化器如何执行查询:
>EXPLAIN SELECT clause\G
输出:
id #当前查询语句中,每个SELECT语句的编号;复杂类型的查询有三种:简单子查询,用于FROM中的子查询,UNION联合查询;有UNION查询的分析结果会出现一个额外的警钟临时表;
select_type #SIMPLE简单查询,SUBQUERY简单子查询,DERIVED用于FROM中的子查询,UNION表示UNION语句的第一个之后的SELECT语句,UNION RESULT匿名临时表;
table #SELECT语句关联到的表;
type #关联类型,或访问类型,即MySQL决定的如何去查询表中行的方式,ALL(表示全表扫描),index(表示根据索引的次序进行全表扫描),如果在Extra列出现Using index表示使用和覆盖索引,range(有范围限制,根据索引实现范围扫描,扫描位置始于索引中的某一点,结束于另一点),ref(根据索引,返回表中匹配某单个值的所有行),eq_ref(仅返回一个行,但需要与某个参考值作比较),cons|system(直接返回单个行,性能最好),NULL(MySQL在优化器的分解查询语句,在执行阶段用得着才访问表或索引,类似覆盖索引);
possible_keys #查询可能会用到的索引;
key #查询中使用了的索引;
key_len #在索引中使用的字节数;
ref #在利用key字段所表示的索引完成查询时,所用的列或某常量值;
rows #MySQL估计为找所有的目标行而需要读取的行数;
Extra #额外信息,Usingindex(MySQL将会使用覆盖索引,以避免访问表),Using where(MySQL服务器将在storage engine检索后,再进行一次过滤),Using temporary(MySQL对结果排序时会使用临时表),Using filesort(MySQL将对结果使用一个外部索引排序);
MaridaDB storage engine:
pluggable storage engine;
MySQL5.1之前默认MyISAM,5.5之后默认InnoDB;
InnoDB:
处理大量的短期事务;
数据存储于table space表空间中(
所有InnoDB表的数据放置于同一个表空间中(表空间文件在datadir目录下,ibdata{1,2,3,...};
每个表单独使用一个表空间,存储表的数据和索引,innodb_file_per_table=ON,数据文件(存储数据和索引),tbl_name.ibd,tbl_name.frm(format,表格式定义文件));
并发(基于MVCC(multi version concurrent control多版本并发控制)来支持高并发,支持所有隔离级别(四个),默认为REPEATABLE READ(间隙锁,防止幻读));
索引(聚集索引,辅助索引);
性能(预读操作,支持自适应hash索引,插入缓存区);
支持行级锁(锁粒度为行级锁);
备份(支持热备,xtrabackup);
>CREATE TABLE ... ENGINE= #表类型,storageengine在表级别指定;
>SHOW GLOBAL VARIABLES LIKE‘innodb_file_per_table‘;
>SHOW ENGINES;
>SHOW TABLE STATUS\G
MyISAM:
不支持事务;
加锁和并发(表级锁);
修复(手工或自动修复,但可能会丢失数据,崩溃后无法完全恢复);
Aria(由MyISAM演变而来,支持崩溃后安全恢复,crash-safe);
索引(支持FULLTEXT index,非聚集索引);
延迟更新索引键;
支持压缩表;
空间函数(GIS);
适用场景(
只读(或写较少);
表较小(可接受长时间进行修复操作);
);
文件(
tbl_name.frm #表格式定义;
tbl_name.MYD #数据文件;
tbl_name.MYI #索引文件;
);
行格式(
dynamic
fixed
compressed
compact
redundent
);
生产中用于数据仓库,选MyISAM或ARCHIVE;
其它的storage engine:
CSV #将普通的CSV文件(字段通过逗号分隔)作为MySQL表使用;
MRG_MYISAM #将多个MyISAM表合并成为一个虚拟表;
BLACKHOLE #类似于/dev/null;
MEMORY #所有数据都保存在内存中,内存表,支持hash索引,表级锁,临时表就是通过此存储引擎实现;
PERFORMANCE_SCHEMA #伪存储引擎;
ARCHIVE #只支持SELECT和INSERT操作,支持行级锁和专用缓冲区,不支持事务;
FEDERATED #用于访问其它远程MySQL服务器一个代理,它通过创建一个到远程MySQL服务器的客户端连接,并将查询输出到远程服务器执行,而后完成数据存取,在MariaDB上叫FederatedX;
MariaDB支持的其它storage engine:
OQGraph;
sphinxSE #用于构建searchengine;
tokuDB;
cassandra;
connected;
squence;
cmake的重要特性之一是其独立于源码out-of-source的编译功能,即编译工作可在另一个指定的目录中,而非源码目录中进行,之可保证源码目录不受任何一次编译的影响,因此在同一个源码树上可进行多次不同的编译,如针对不同平台编译;
#cmake . #相当于./configure;
#cmake . -LH #或ccmake .相当于./configure --help;
#make clean #清理此前编译生成的文件;
#rm -f CMakeCache.txt