首页 > 代码库 > MySQL 基础(二)
MySQL 基础(二)
MySQL 基础(二)
==============================================================================
概述:
==============================================================================
MySQL
1.数据结构:
★分类:
结构化数据: 关系型数据库
半结构化数据:YAML、XML、JSON
非结构化数据:日志文件,NoSQL
2.MySQL的体系结构:
★架构图:
图一:
图二:
★名词解析
⊙Connectors
指的是不同语言中与SQL的交互;
⊙Management Serveices & Utilities:
系统管理和控制工具
⊙Connection Pool: 连接池。
管理缓冲用户连接,线程处理等需要缓存的需求
⊙SQL Interface: SQL接口。
接受用户的SQL命令,并且返回用户需要查询的结果。比如select from就是调用SQL Interface
⊙Parser: 解析器。
SQL命令传递到解析器的时候会被解析器验证和解析。解析器是由Lex和YACC实现的,是一个很长的脚本。
主要功能:
将SQL语句分解成数据结构,并将这个结构传递到后续步骤,以后SQL语句的传递和处理就是基于这个结构的;
如果在分解构成中遇到错误,那么就说明这个sql语句是不合理的
⊙Optimizer: 查询优化器。
SQL语句在查询之前会使用查询优化器对查询进行优化。他使用的是“选取-投影-联接”策略进行查询。
用一个例子就可以理解: select uid,name from user where gender = 1;
这个select 查询先根据where 语句进行选取,而不是先将表全部查询出来以后再进行gender过滤;这个select查询先根据uid和name进行属性投影,而不是将属性全部取出以后再进行过滤,将这两个查询条件联接起来生成最终查询结果;
⊙Cache和Buffer: 查询缓存。
如果查询缓存有命中的查询结果,查询语句就可以直接去查询缓存中取数据。
这个缓存机制是由一系列小缓存组成的。比如表缓存,记录缓存,key缓存,权限缓存等
⊙Engine :存储引擎。
存储引擎是MySql中具体的与文件打交道的子系统。也是Mysql最具有特色的一个地方。
Mysql的存储引擎是插件式的。它根据MySql AB公司提供的文件访问层的一个抽象接口来定制一种文件访问机制(这种访问机制就叫存储引擎)
现在有很多种存储引擎,各个存储引擎的优势各不一样,最常用MyISAM,InnoDB,BDB
默认下MySql是使用MyISAM引擎,它查询速度快,有较好的索引优化和数据压缩技术。但是它不支持事务。
InnoDB支持事务,并且提供行级的锁定,应用也相当广泛。
Mysql也支持自己定制存储引擎,甚至一个库中不同的表使用不同的存储引擎,这些都是允许的。
3.MySQL的安装及配置文件
★版本:
mysql:5.1 --> 5.5 --> 5.6 --> 5.7 --> 8.0
mariadb:5.5.x --> 10.x
★特性:
插件式存储引擎;
单进程多线程
★安装MySQL:
☉OS Vendor:rpm
☉MySQL:
source code:cmake
binary package:
i686, x86_64;
glibc VERSION
prepackage:rpm, deb
os, arch,
★配置文件:
读取多处的多个配置文件,而且会以指定的次序的进行;
配置文件格式:ini风格的配置文件,能够为mysql的各种应用程序提供配置信息:
4.mysqld服务器程序:工作特性的定义方式
★工作特性的定义方式
命令行选项
配置文件参数
☉服务器参数/变量:设定MySQL的运行特性;
mysql> SHOW GLOBA|[SESSION] VARIABLES [LIKE clause];
☉状态(统计)参数/变量:保存MySQL运行中的统计数据或状态数据;
mysql> SHOW GLOBA|[SESSION] STATUS [LIKE clause];
☉显示单个变量(服务器)设定值的方法:
mysql> SELECT @@[global.|session.]system_var_name
%:匹配任意长度的任意字符;
_:匹配任意单个字符;
☉变量/参数级别:
全局:为所有会话设定默认;
会话:跟单个会话相关;会话建立会从全局继承;
☉服务器变量的调整方式:
运行时修改:
global:仅对修改后新建立的会话有效;
session:仅对当前会话有效,且立即生效;
启动前通过配置文件修改:
重启后生效;
☉运行时修改变量值操作方法:
mysql> HELP SET
SET [GLOBAL | SESSION] system_var_name = expr
SET [@@global. | @@session. | @@]system_var_name = expr
演示:
1.显示会话统计中有关线程相关的状态参数/变量;(like字句过滤)
MariaDB [(none)]> SHOW SESSION STATUS LIKE ‘Thread%‘\G *************************** 1. row *************************** Variable_name: Threadpool_idle_threads Value: 0 *************************** 2. row *************************** Variable_name: Threadpool_threads Value: 0 *************************** 3. row *************************** Variable_name: Threads_cached Value: 0 *************************** 4. row *************************** Variable_name: Threads_connected Value: 2 *************************** 5. row *************************** Variable_name: Threads_created Value: 3 *************************** 6. row *************************** Variable_name: Threads_running Value: 1 6 rows in set (0.01 sec)
2.显示单个变量(服务器)设定值的方法;
MariaDB [(none)]> SELECT @@global.tx_isolation; +-----------------------+ | @@global.tx_isolation | +-----------------------+ | REPEATABLE-READ | +-----------------------+ 1 row in set (0.00 sec) MariaDB [(none)]> SELECT @@session.tx_isolation; # session从全局继承 +------------------------+ | @@session.tx_isolation | +------------------------+ | REPEATABLE-READ | +------------------------+
3.运行时修改参数变量值的方法
MariaDB [(none)]> SELECT @@session.autocommit; +----------------------+ | @@session.autocommit | +----------------------+ | 1 | +----------------------+ 1 row in set (0.00 sec) MariaDB [(none)]> SET SESSION autocommit=0; # 设定会话中autocommit的值为0 Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]> SELECT @@session.autocommit; +----------------------+ | @@session.autocommit | +----------------------+ | 0 | +----------------------+ 1 row in set (0.00 sec) MariaDB [(none)]> SELECT @@global.autocommit; +---------------------+ | @@global.autocommit | +---------------------+ | 1 | +---------------------+ 1 row in set (0.00 sec) MariaDB [(none)]> SET SESSION autocommit=1; Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]> SET @@global.autocommit=0; # 设定全局中的为0 Query OK, 0 rows affected (0.01 sec) MariaDB [(none)]> SELECT @@global.autocommit; +---------------------+ | @@global.autocommit | +---------------------+ | 0 | +---------------------+ 1 row in set (0.00 sec) MariaDB [(none)]> SELECT @@session.autocommit; # 对当前会话无效,但是对新建立的会话有效 +----------------------+ | @@session.autocommit | +----------------------+ | 1 | +----------------------+
------------------------------------------------------------------------------------------
4.安装完成后的安全初始化及运行前修改参数
★安装完成后的安全初始化:
mysql_secure_installation
★运行前常修改的参数:
☉CentOS 7
innodb_file_per_table=ON
skip_name_resolve=ON
☉CentOS 6
innodb_file_per_table=ON
skip_name_resolve
5.SQL MODE:定义mysqld对约束等违反时的响应行为等设定;
★常用的MODE:
TRADITIONAL 传统的模式,违反数据定义的统统都不被允许;
STRICT_TRANS_TABLES 仅对事物型表严格限定;
STRICT_ALL_TABLES 对所有的表都做严格限定;
★修改方式:
mysql> SET GLOBAL sql_mode=‘MODE‘;
mysql> SET @@global.sql_mode=‘MODE‘;
注意:
默认为空模式,如果违反数据定义,会发出警报,会以允许的最大范围去修减数据
sql mode为必改参数,要想永久生效,要写入配置文件
演示:
1.在sql mode模式为空的时候(默认),向表中插入数据,可以插入成功,但对违反数据定义的会对数据进行修减到允许的最大范围,如下:
MariaDB [(none)]> SELECT @@session.sql_mode; +--------------------+ | @@session.sql_mode | +--------------------+ | | +--------------------+ 1 row in set (0.00 sec) MariaDB [(none)]> CREATE DATABASE testdb; Query OK, 1 row affected (0.00 sec) MariaDB [(none)]> use testdb; Database changed MariaDB [testdb]> create table tbl1(id tinyint unsigned,name CHAR(5)); Query OK, 0 rows affected (0.03 sec) MariaDB [testdb]> insert into tbl1 (id) values (16),(256); 默认最大为255 Query OK, 2 rows affected, 1 warning (0.00 sec) # 报错 Records: 2 Duplicates: 0 Warnings: 1 MariaDB [testdb]> select * from tbl1; +------+------+ | id | name | +------+------+ | 16 | NULL | | 255 | NULL | # 可以发现我们插入的256没有成功,只到允许插入的最大范围 +------+------+ 2 rows in set (0.00 sec) MariaDB [testdb]> insert into tbl1 (name) values (‘jerry‘),(‘taotaoxiuxiu‘); Query OK, 2 rows affected, 1 warning (0.00 sec) Records: 2 Duplicates: 0 Warnings: 1 MariaDB [testdb]> show Warnings; +---------+------+-------------------------------------------+ | Level | Code | Message | +---------+------+-------------------------------------------+ | Warning | 1265 | Data truncated for column ‘name‘ at row 2 | +---------+------+-------------------------------------------+ 1 row in set (0.00 sec) MariaDB [testdb]> select * from tbl1; +------+-------+ | id | name | +------+-------+ | 16 | NULL | | 255 | NULL | | NULL | jerry | | NULL | taota | # 我们定义的最大只能插入5个字符,多以多出来的将会被修减 +------+-------+ 4 rows in set (0.00 sec)
2.现在我们定义sql mode模式为TRADITIONAL(传统模式),即对数据进行严格的限定,对违反数据要求的统统不予许插入,如下:
MariaDB [testdb]> SET @@session.sql_mode=‘TRADITIONAL‘; # 设定当前会话为传统模式; Query OK, 0 rows affected (0.00 sec) MariaDB [testdb]> SELECT @@session.sql_mode; +------------------------------------------------------------------------------------------------------------------------------------------------------+ | @@session.sql_mode | +------------------------------------------------------------------------------------------------------------------------------------------------------+ | STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION | +------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) MariaDB [testdb]> insert into tbl1 (name) values (‘jerry‘),(‘taotaoxiuxiu‘); ERROR 1406 (22001): Data too long for column ‘name‘ at row 2 # 再次插入报错,不允许插入
SQL:DDL,DML补充
1.VIEW 视图
★虚表:存储下来的SELECT语句;
☉创建:
CREATE VIEW view_name [(column_list)] AS select_statement
☉修改:
ALTER VIEW view_name [(column_list)] AS select_statement
☉删除:
DROP VIEW [IF EXISTS] view_name [, view_name] ...
演示:
MariaDB [testdb]> create table tbl2 (id INT UNSIGNED,name VARCHAR(50),age TINYINT UNSIGNED); Query OK, 0 rows affected (0.04 sec) MariaDB [testdb]> insert into tbl2 VALUES (1,‘tom‘,21),(2,‘tao‘,15),(3,‘jing‘,22); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 MariaDB [testdb]> select * from tbl2; +------+------+------+ | id | name | age | +------+------+------+ | 1 | tom | 21 | | 2 | tao | 15 | | 3 | jing | 22 | +------+------+------+ 3 rows in set (0.00 sec) MariaDB [testdb]> CREATE VIEW testview AS SELECT id,name FROM tbl2; # 创建VIEW Query OK, 0 rows affected (0.02 sec) MariaDB [testdb]> SHOW TABLES; # 查看发现view也作为了一个表; +------------------+ | Tables_in_testdb | +------------------+ | tbl1 | | tbl2 | | testview | +------------------+ 3 rows in set (0.00 sec) MariaDB [testdb]> DESC testview; # 但是数据只有id和name段,和原表tbl2不同 +-------+------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+------------------+------+-----+---------+-------+ | id | int(10) unsigned | YES | | NULL | | | name | varchar(50) | YES | | NULL | | +-------+------------------+------+-----+---------+-------+ 2 rows in set (0.01 sec) MariaDB [testdb]> select * from testview; +------+------+ | id | name | +------+------+ | 1 | tom | | 2 | tao | | 3 | jing | +------+------+ 3 rows in set (0.00 sec) MariaDB [testdb]> show table status\G # 查看表的类型,可以看到第3张表为view类型的 *************************** 1. row *************************** Name: tbl1 Engine: InnoDB Version: 10 Row_format: Compact Rows: 0 Avg_row_length: 0 Data_length: 16384 Max_data_length: 0 Index_length: 0 Data_free: 0 Auto_increment: NULL Create_time: 2016-11-24 15:41:24 Update_time: NULL Check_time: NULL Collation: latin1_swedish_ci Checksum: NULL Create_options: Comment: *************************** 2. row *************************** Name: tbl2 Engine: InnoDB Version: 10 Row_format: Compact Rows: 3 Avg_row_length: 5461 Data_length: 16384 Max_data_length: 0 Index_length: 0 Data_free: 0 Auto_increment: NULL Create_time: 2016-11-24 16:43:04 Update_time: NULL Check_time: NULL Collation: latin1_swedish_ci Checksum: NULL Create_options: Comment: *************************** 3. row *************************** Name: testview Engine: NULL Version: NULL Row_format: NULL Rows: NULL Avg_row_length: NULL Data_length: NULL Max_data_length: NULL Index_length: NULL Data_free: NULL Auto_increment: NULL Create_time: NULL Update_time: NULL Check_time: NULL Collation: NULL Checksum: NULL Create_options: NULL Comment: VIEW 3 rows in set (0.00 sec) MariaDB [testdb]> DROP VIEW testview; # 删除view Query OK, 0 rows affected (0.00 sec) MariaDB [testdb]> show tables; +------------------+ | Tables_in_testdb | +------------------+ | tbl1 | | tbl2 | +------------------+ 2 rows in set (0.00 sec)
------------------------------------------------------------------------------------------
2.SELECT:
★Query Cache:缓存查询的执行结果;
key:查询语句的hash值;
value:查询语句的执行结果;
SQL语句的编写方式:
要养成同一种风格书写方式,要大写都大写,要小写都小写,方便查询缓存;
★查询执行路径:
请求-->查询缓存
请求-->查询缓存-->解析器-->预处理器-->优化器-->查询执行引擎-->存储引擎-->缓存-->响应
★SELECT语句的执行流程:
FROM --> WHERE(条件过滤)--> Group By(分组聚合)--> Having(对分组统计再加限制条件)--> Order BY(排序)--> SELECT --> Limit(限定数据处理后显示的行数)
select是用来挑选字段的,而where是用来挑选行的;mysql关系型数据库为一个行级数据库,所有数据先取行,然后对行过滤之后保留关键字段,
★单表查询:
☉SELECT
☉用法:
SELECT col1, col2, ... FROM tble_name;
挑选字段;
SELECT col1, col2, ... FROM tble_name WHERE clause;
以指定条件过滤行之后再挑选字段
SELECT col1, col2, ... FROM tble_name [WHERE clause] GROUP BY col_name [HAVING clause];
以指定的字段进行分组,分完组之后聚合,然后对聚合后的结果使用having子句进行过滤;
☉DISTINCT:数据去重;
☉SQL_CACHE:显式指定缓存查询语句的结果;
☉SQL_NO_CACHE:显式指定不缓存查询语句的结果;
☉query_cache_type服务器变量有三个值:
ON:启用;
SQL_NO_CACHE:不缓存;默认符合缓存条件都缓存;
OFF:关闭;
DEMAND:按需缓存;
SQL_CACHE:缓存;默认不缓存;
☉字段可以使用别名 :
col1 AS alias1, col2 AS alias2, ...
☉WHERE子句:指明过滤条件以实现“选择”功能;
☉GROUP BY:根据指定的字段把查询的结果进行“分组”以用于“聚合”运算;
avg(), max(), min(), sum(), count()
☉HAVING:对分组聚合后的结果进行条件过滤;
☉ORDER BY:根据指定的字段把查询的结果进行排序;
升序:ASC
降序:DESC
☉LIMIT:对输出结果进行数量限制
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
演示:
1.select挑选字段和where挑选行
MariaDB [testdb]> show tables; +------------------+ | Tables_in_testdb | +------------------+ | tbl1 | | tbl2 | +------------------+ 2 rows in set (0.00 sec) MariaDB [testdb]> select id from tbl2; # select仅挑选字段 +------+ | id | +------+ | 1 | | 2 | | 3 | +------+ 3 rows in set (0.00 sec) MariaDB [testdb]> select * from tbl2; # 显示所有的字段 +------+------+------+ | id | name | age | +------+------+------+ | 1 | tom | 21 | | 2 | tao | 15 | | 3 | jing | 22 | +------+------+------+ 3 rows in set (0.00 sec) MariaDB [testdb]> select * from tbl2 where age>=20; # where挑选行 +------+------+------+ | id | name | age | +------+------+------+ | 1 | tom | 21 | | 3 | jing | 22 | +------+------+------+ 2 rows in set (0.00 sec) MariaDB [testdb]> select name,age from tbl2 where age>=20; # 即挑选字段又挑选行 +------+------+ | name | age | +------+------+ | tom | 21 | | jing | 22 | +------+------+
2.对挑选出的数据分组 Group By,分组的目的在于聚合
MariaDB [testdb]> alter table tbl2 add gender enum(‘F‘,‘M‘); #增加一个gender字段 Query OK, 3 rows affected (0.03 sec) Records: 3 Duplicates: 0 Warnings: 0 MariaDB [testdb]> select * from tbl2; +------+------+------+--------+ | id | name | age | gender | +------+------+------+--------+ | 1 | tom | 21 | NULL | | 2 | tao | 15 | NULL | | 3 | jing | 22 | NULL | +------+------+------+--------+ 3 rows in set (0.00 sec) MariaDB [testdb]> update tbl2 set gender=‘M‘ where id=1; # 设定其值 Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 MariaDB [testdb]> update tbl2 set gender=‘M‘ where id=2; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 MariaDB [testdb]> update tbl2 set gender=‘F‘ where id=3; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 MariaDB [testdb]> select * from tbl2; +------+------+------+--------+ | id | name | age | gender | +------+------+------+--------+ | 1 | tom | 21 | M | | 2 | tao | 15 | M | | 3 | jing | 22 | F | +------+------+------+--------+ 3 rows in set (0.00 sec) MariaDB [testdb]> select * from tbl2 group by gender; # 按性别对tbl2进行分组(有几个值就分多少组) +------+------+------+--------+ | id | name | age | gender | +------+------+------+--------+ | 3 | jing | 22 | F | | 1 | tom | 21 | M | +------+------+------+--------+ 2 rows in set (0.01 sec) MariaDB [testdb]> select avg(age),gender from tbl2 group by gender; # 对各分组求其平均值 +----------+--------+ | avg(age) | gender | +----------+--------+ | 22.0000 | F | | 18.0000 | M | +----------+--------+ 2 rows in set (0.00 sec) MariaDB [testdb]> select sum(age),gender from tbl2 group by gender; # 对各分组求和 +----------+--------+ | sum(age) | gender | +----------+--------+ | 22 | F | | 36 | M | +----------+--------+ 2 rows in set (0.00 sec) MariaDB [testdb]> select avg(age) as avg_age,gender from tbl2 group by gender; #对avg_age定义别名 +---------+--------+ | avg_age | gender | +---------+--------+ | 22.0000 | F | | 18.0000 | M | +---------+--------+ 2 rows in set (0.01 sec)
3.对聚合后的结果指明过滤条件HAVING
MariaDB [testdb]> select avg(age) as avg_age,gender from tbl2 group by gender having avg_age >= 20; +---------+--------+ | avg_age | gender | +---------+--------+ | 22.0000 | F | +---------+--------+ 1 row in set (0.01 sec)
4.数据去重
MariaDB [testdb]> select gender from tbl2; +--------+ | gender | +--------+ | M | | M | | F | +--------+ 3 rows in set (0.00 sec) MariaDB [testdb]> select distinct gender from tbl2; # 去重 +--------+ | gender | +--------+ | M | | F | +--------+ 2 rows in set (0.00 sec) MariaDB [testdb]> SHOW VARIABLES LIKE ‘%cache%‘; # 和缓存cache相关的参数 +-------------------------------+----------------------+ | Variable_name | Value | +-------------------------------+----------------------+ | aria_pagecache_age_threshold | 300 | | aria_pagecache_buffer_size | 134217728 | | aria_pagecache_division_limit | 100 | | binlog_cache_size | 32768 | | binlog_stmt_cache_size | 32768 | | have_query_cache | YES | | join_cache_level | 2 | | key_cache_age_threshold | 300 | | key_cache_block_size | 1024 | | key_cache_division_limit | 100 | | key_cache_segments | 0 | | max_binlog_cache_size | 18446744073709547520 | | max_binlog_stmt_cache_size | 18446744073709547520 | | metadata_locks_cache_size | 1024 | | query_cache_limit | 1048576 | | query_cache_min_res_unit | 4096 | | query_cache_size | 0 | # 为0,没有缓存空间 | query_cache_strip_comments | OFF | | query_cache_type | ON | # 缓存为开启状态 | query_cache_wlock_invalidate | OFF | | stored_program_cache | 256 | | table_definition_cache | 400 | | table_open_cache | 400 | | thread_cache_size | 0 | +-------------------------------+----------------------+ 24 rows in set (0.00 sec)
本文出自 “逐梦小涛” 博客,请务必保留此出处http://1992tao.blog.51cto.com/11606804/1876369
MySQL 基础(二)