首页 > 代码库 > 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 基础(二)