zoukankan      html  css  js  c++  java
  • MySQL的使用技巧

    MySQL的使用技巧

    欢迎来到 来到大浪涛天的博客

    一、MySQL的使用技巧

    1. GROUP BY的详细说明:

    GROUP BY 后接需要分组的列,添加该列执行后,数据库会先把该列的数据取出来先做一个排序,然后再去重,因此如果SELECT语句后面接着的该列如果没有被函数包裹进行运算或者没有GROUP_CONCAT做拼接的话会报错,这是为了保证查看的数据的完整性,如果不报错的话那去重后的值会丢失,这样显示的数据将没有任何意义,但这仅限于5.7的版本。
    报错的本质是sql_mode开启了only_full_group_by的功能。

    关于only_full_group_by的说明如下:

    1. 在5.7版本中MySQL sql_mode参数中自带,5.6和8.0都没有
    2. 在带有group by 字句的select中,select 后的条件列(非主键列),要么是group by后的列,要么需要在函数中包裹
    3. 如果需要开启或者关闭only_full_group_by则如下操作:
    1. 查看该参数在sql_mode中是否存在或者开启
    mysql> select @@sql_mode;
    +-------------------------------------------------------------------------------------------------------------------------------------------+
    | @@sql_mode                                                                                                                                |
    +-------------------------------------------------------------------------------------------------------------------------------------------+
    | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
    +-------------------------------------------------------------------------------------------------------------------------------------------+
    2. 在/etc/my.cnf中添加一行.
    sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION 
    3. systemctl restart mysqld3307.service 
    4. 再次登陆到MySQL查看如下:
    mysql> select @@sql_mode;
    +------------------------------------------------------------------------------------------------------------------------+
    | @@sql_mode                                                                                                             |
    +------------------------------------------------------------------------------------------------------------------------+
    | STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
    +------------------------------------------------------------------------------------------------------------------------+

    2. GROUP_CONCAT的说明

    group_concat配合group by使用是将直接将列转为行,因为group by后接着的列将会直接排序,去重(去重如果重复的列的多余的数据配合group_concat会转成行显示)。
    列转行聚合函数,简单的事例如下:

    mysql> SELECT user,host FROM mysql.user; (什么都没做,原本的数据)
    +---------------+-------------+
    | user          | host        |
    +---------------+-------------+
    | root          | 10.211.55.% |
    | mysql.session | localhost   |
    | mysql.sys     | localhost   |
    | root          | localhost   |
    +---------------+-------------+
    4 rows in set (0.02 sec)
    
    mysql> SELECT user,host FROM mysql.user GROUP BY user; (使用了GROUP BY对user列进行了排序并去重,结果是少了root的一行数据)
    +---------------+-------------+
    | user          | host        |
    +---------------+-------------+
    | mysql.session | localhost   |
    | mysql.sys     | localhost   |
    | root          | 10.211.55.% |
    +---------------+-------------+
    3 rows in set (0.01 sec)
    
    mysql> SELECT user,GROUP_CONCAT(host) FROM mysql.user GROUP BY user; (在SELECT的后面对host列进行了GROUP_CONCAT拼接)
    +---------------+-----------------------+
    | user          | GROUP_CONCAT(host)    |
    +---------------+-----------------------+
    | mysql.session | localhost             |
    | mysql.sys     | localhost             |
    | root          | localhost,10.211.55.% |
    +---------------+-----------------------+
    3 rows in set (0.02 sec)

    3. 关于多表查询连接规则

    1. 首先找涉及到的所有表
    2. 找到表和表之间的关联列
    3. 关联条件写在on后面
      A join B on 关联列
    4. 所有需要查询的信息放在select后
    5. 其他的过滤条件where group by having order by limit 网最后放
    6. select 执行顺序:select user ,count(name) from 表 where 列 group by user having 列 order by 列 ;
    7. 需要特别注意的是:对多表连接中,因为驱动表不走索引,所以一般数据行较少表放在左边作为驱动表。后续所有表的关联列尽量是主键或唯一键(表设计),至少建立一个索引。

    4. 关于distinct去重的说明

    MySQL中的distinct其实和SHELL里的uniq 一样的,直接在SELECT后跟着的列前面加上就可以直接去重,可以存在于函数包裹的括号里面。
    例如:

    mysql> SELECT count(distinct countrycode) from world.city;
    +-----------------------------+
    | count(distinct countrycode) |
    +-----------------------------+
    |                         232 |
    +-----------------------------+
    1 row in set (0.07 sec)
    mysql> SELECT count( countrycode) from world.city;        
    +---------------------+
    | count( countrycode) |
    +---------------------+
    |                4079 |
    +---------------------+

    5. 关于MySQL的视图说明:

    视图是一个虚拟表,是sql的查询结果,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据,在使用视图时动态生成。视图的数据变化会影响到基表,基表的数据变化也会影响到视图[insert update delete ] ; 创建视图需要create view 权限,并且对于查询涉及的列有select权限;使用create or replace 或者 alter修改视图,那么还需要改视图的drop权限。
    简单的来说视图类式于Linux里面的SHELL脚本,先把复杂的命令写好,然后每次需要查询的时候直接拿出来进行执行。

    mysql> create view unpass as SELECT t.tname as '教师名',GROUP_CONCAT(CONCAT(st.sname,":",s.score)) as '不及格的同学' FROM teacher as t JOIN course as c ON t.tno=c.tno JOIN score as s ON c.cno=s.cno JOIN student as st ON s.sno=st.sno WHERE s.score <60 GROUP BY t.tno;
    mysql> use school;
    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A
    
    Database changed
    mysql> select * from unpass;
    +-----------+--------------------+
    | 教师名    | 不及格的同学       |
    +-----------+--------------------+
    | hesw      | zhang3:59          |
    | oldguo    | li4:40,zh4:40      |
    +-----------+--------------------+

    6. MySQL的元数据的获取

    6-1. MySQL元数据介绍:

    1. 元数据是存储在"基表"中,不可以直接进行修改
    2. 通过专用的DDL语句,DCL语句进行修改
    3. 通过专用视图和命令进行元数据的查询
    4. information_schema中保存了大量元数据查询的试图
    5. show 命令是封装好功能,提供元数据查询基础功能

    6-2. information_schema的基本应用

    6-2-1. tables 视图的应用

    information_schema库里面包含了大量已经做好了的视图,而tables表里面又包含了大量非常有用的东西,如下所示:

    mysql> use information_schema;
    mysql> desc tables;
    
    TABLE_SCHEMA        表所在的库名
    TABLE_NAME			表名
    ENGINE				存储引擎
    TABLE_ROWS			数据行
    AVG_ROW_LENGTH		平均行长度
    INDEX_LENGTH        索引长度

    6-3. 重要的实例如下:

    USE information_schema;
    DESC TABLES;

    6-3-1. 显示所有的库和表的信息
    SELECT table_schema,table_name FROM information_schema.tables;
    6-3-2. 以以下模式 显示所有的库和表的信息
    world     city,country,countrylanguage
    
    SELECT table_schema,GROUP_CONCAT(table_name) 
    FROM information_schema.tables
    GROUP BY table_schema;
    6-3-3. 查询所有innodb引擎的表
    SELECT table_schema,table_name ,ENGINE
    FROM information_schema.tables 
    WHERE ENGINE='innodb';
    6-3-4. 统计world下的city表占用空间大小
    表的占用空间大小的计算方式如下
    表的数据量=平均行长度*行数+索引长度
    表的真实数据量占用大小=AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH
    SELECT table_name,(AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH)/1024
    FROM information_schema.TABLES
    WHERE table_schema='world' AND table_name='city';
    如果不除以1024的话单位是字节,除以1024以后的单位是k
    6-3-5. 统计world库数据量总大小
    SELECT table_schema,SUM((AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH))/1024
    FROM information_schema.TABLES
    WHERE table_schema='world';
    6-3-6. 统计每个库的数据量大小,并按数据量从大到小排序
    SELECT table_schema,SUM((AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH))/1024 AS total_KB
    FROM information_schema.TABLES
    GROUP BY table_schema
    ORDER BY total_KB DESC ;
    6-3-7. 配合concat()函数拼接语句或命令
    1. 如模仿以下语句,进行数据库的分库分表备份
      mysqldump -uroot -p123 world city >/bak/world_city.sql
    SELECT
    CONCAT("mysqldump -uroot -p123 ",table_schema," ",table_name
    ," >/bak/",table_schema,"_",table_name,".sql")
    FROM information_schema.tables;
    1. 模仿以下语句,进行批量生成对world库下所有表进行操作
      ALTER TABLE world.city DISCARD TABLESPACE;
    SELECT 
    CONCAT("ALTER TABLE ",table_schema,".",table_name," DISCARD TABLESPACE;")
    FROM information_schema.tables
    WHERE table_schema='world';

    注意这个语句删除当前.ibd文件,常用于.ibd文件已经备份,用来快速导入数据,步骤如下:

    • ALTER TABLE tbl_name DISCARD TABLESPACE;
    • 把备份的.ibd文件放回到恰当的数据库目录。
    • ALTER TABLE tbl_name IMPORT TABLESPACE;

    6-4. show命令查看MySQL的元数据信息

    show databases;        		查看数据库名
    show tables; 		   		查看表名
    show create database xx;  	查看建库语句
    show create table xx;		查看建表语句
    show processlist;			查看所有用户连接情况
    show charset;				查看支持的字符集
    show collation;				查看所有支持的校对规则
    show grants for xx;			查看用户的权限信息
    show variables like '%xx%'  查看参数信息
    show engines;				查看所有支持的存储引擎类型
    show index from xxx			查看表的索引信息
    show engine innodb statusG 查看innoDB引擎详细状态信息
    show binary logs 			查看二进制日志的列表信息
    show binlog events in ''	查看二进制日志的事件信息
    show master status ;		查看mysql当前使用二进制日志信息
    show slave statusG 		查看从库状态信息
    show relaylog events in ''	查看中继日志的事件信息
    show status like ''			查看数据库整体状态信息
  • 相关阅读:
    Python 两个list合并成一个字典
    python 取列表(数组)偶数和奇数位置的值
    爬虫-Xpath语法笔记-转载
    详解Python requests 超时和重试的方法-转载
    6种负载均衡算法-转载
    python学习点滴记录-Day22
    python学习点滴记录-Day21-项目
    python学习点滴记录-Day20(分页、cookie/session、ajax)
    vimrc
    使用 find 命令实现高级排除需求
  • 原文地址:https://www.cnblogs.com/chacha51/p/13715078.html
Copyright © 2011-2022 走看看