本文共 58526 字,大约阅读时间需要 195 分钟。
主流的数据库有:Postegres、sqlserver,mysql,Oracle、SQLite、Access、MS SQL Server等
a. 将数据保存到文件或内存
b. 接收特定的命令,然后对文件进行相应的操作
登录MYSQL:mysql -u root -p
一、脚本创建数据库demodb,并制定默认的字符集是utf8mb4。CREATE DATABASE demodb DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
二、授权
grant all privileges on demodb.* to jiashiyi@'%' identified by 'db123';flush privileges; //刷新系统权限表
常用sql语句
select count(*) from mysql.user; 查看这个表的行数,库和表中间有一个.作为分隔符。select * from mysql.db; 查看所有内容,如果一个表内容很多,不建议使用*查看所有。select db from mysql.db; 查看字段select db,user from mysql.db; 查看2个字段select * from mysql.db where host like '192.168.%'; 模糊查询,使用这样方式可以树形显示insert into db1.t1 values (1, 'abc'); 插入字段内容update db1.t1 set name='aaa' where id=1; 更新字段内容truncate table db1.t1; 清空一个表里面的内容,但是表的结构框架还会保留。drop table db1.t1; 彻底清空一个表drop database db1; 彻底清空一个数据库
root 登陆,执行如下步骤:
shell> groupadd mysqlshell> useradd -g mysql mysqlshell> cd /home/mysqlshell>tar -xzvf /home/mysql/mysql-VERSION-OS.tar.gzshell> ln -s mysql-VERSION-OS.tar.gz mysqlshell> cd mysqlshell> scripts/mysql_install_db --user=mysqlshell> chown -R root:mysql .shell> chown -R mysql:mysql datashell> bin/mysqld_safe --user=mysql &
root 登陆,执行如下步骤:
shell> groupadd mysqlshell> useradd -g mysql mysqlshell> gunzip < mysql-VERSION.tar.gz | tar -xvf -shell> cd mysql-VERSIONshell> ./configure --prefix=/usr/local/mysqlshell> makeshell> make installshell> cp support-files/my-medium.cnf /etc/my.cnfshell> cd /usr/local/mysqlshell> bin/mysql_install_db --user=mysqlshell> chown -R root .shell> chown -R mysql varshell> chgrp -R mysql .bin/mysql_install_db --user=mysql
源码安装由于可以灵活的进行数据库的定制编译,因此有更强的灵活性。某些编译
选项可以大大增强我们数据库的性能。执行如下命令可以看到所有编译的配置选项:
shell> ./configure --help
如果只安装客户端,可以执行如下命令:
shell> .e /configure --without-server
如果你不想要位于“/usr/local/var”目录下面的日志(log)文件和数据库,使用类
似于下列 configure 命令的一个:shell>./configure--prefix=/usr/local/mysqlshell>./configure--prefix=/usr/local localstatedir=/usr/local/mysql/data
第一个命令改变安装前缀以便将所有内容安装到“/usr/local/mysql”下面而非
默认的“/usr/local”。第二个命令保留默认安装前缀,但是覆盖了数据库目录默 认目录(通常是“/usr/local/var”)并且把它改为/usr/local/mysql/data 。编译 完 MySQL 后,可以通过选项文件更改这些选项 修改 socket 的默认位置:shell> - ./configure\-- with-unix-socket-path=/usr/local/mysql/tmp/mysql.sock
改变安装后的默认字符集和排序规则:
shell> ./configure - -- with-charset= CHARSETe ./configure --with-collation= COLLATION
选择需要安装的字符集:
shell> ./configure --with-extra-charsets= LIST
list 可以是下面任何一项:
空格间隔的一系列字符集名 complex -,以包括不能动态装载的所有字符集 all –,以将所有字符集包括进二进制shell>./configure --with-client-ldflags=-all-static\--with-mysqld-ldflags=-all-static
方法 1 最简单,适合于任何存储引擎(不一定速度最快)
安装新数据库 将老数据库导出为文本,导入到新数据库上shell> mysqladmin -h hostname -P port -u user -p passwd create db_nameshell> mysqldump --opt db_name | mysql -h hostname -P port -u user -ppasswd db_name
注:如果网络较慢,可以在导出选项中加上–compress 来减少网络传输
升级权限表 将原库中的 mysql 数据库目录全部 cp 过来覆盖新库中 mysql 数据库 在 shell 里面执行 mysql_fix_privilege_tables 命令升级权限表shell>mysql_fix_privilege_tables
重启数据库服务
方法 2 适合于任何存储引擎,速度较快
安装新数据库 旧库中创建保存输出文件的目录并备份数据库:shell> mkdir DUMPDIRshell>mysqldump --tab=DUMPDIR db_name
将 DUMPDIR 目录中的文件转移到目标机上相应的目录中并将文件装载到 MySQL:
shell> mysqladmin create db_name # create databaseshell> cat DUMPDIR/*.sql | mysql db_name # create tables in databaseshell> mysqlimport db_name DUMPDIR/*.txt # load data into tables
(实际测试的时候,发现 txt 要放到 data 下才能执行,否则提示文件找不到)
升级权限表 将原库中的 mysql 数据库目录全部 cp 过来覆盖新库中 mysql 数据库 在 shell 里面执行 mysql_fix_privilege_tables 命令升级权限表shell>mysql_fix_privilege_tables
重启数据库服务
方法 3 适合于 myisam 表,速度最快安装新数据库
将原库中的数据目录下的所有文件(.frm,.MYD,MYI)cp 到新库下的相应目录下 升级权限表 将原库中的 mysql 数据库目录全部 cp 过来覆盖新库中 mysql 数据库 在 shell 里面执行 mysql_fix_privilege_tables 命令升级权限表shell>mysql_fix_privilege_tablesflush tables 或者重启数据库服务生效
Mysql查看数据库信息常见命令
1,查看所有数据库show databases;
2,查看当前使用的数据库
select database();
3,查看数据库使用端口
show variables like ‘port’;
4,查看当前数据库大小
use information_schema;select concat(round(sum(data_length)/(1024*1024),2) + round(sum(index_length)/(1024*1024),2),'MB') as 'DB Size' from tables where table_schema=’数据库名’;
5,查看数据所用空间大小
use information_schema;select concat(round(sum(data_length)/(1024*1024),2),'MB') as 'DB Size' from tables where table_schema=’数据库名’;
6,查看索引所用空间大小
use information_schema;select concat(round(sum(index_length)/(1024*1024),2) ,'MB') as 'DB Size' from tables where table_schema=’数据库名’;
7,查看数据库编码
show variables like ‘character% ‘;character_set_client 为客户端编码方式;character_set_connection 为建立连接使用的编码;character_set_database 为数据库的编码;character_set_results 为结果集的编码;character_set_server 为数据库服务器的编码;
只要保证以上采用的编码方式一样,就不会出现乱码问题。
8,查看数据库表信息
show tables;
9,查看数据库所有用户信息
select distinct concat('user: ',user,'@',host,';') as query from mysql.user;
10,查看某个具体用户权限
show grants for ‘用户’@‘地址’;
11,查看数据库最大连接数
show variables like ‘%max_connections%’;
12,查看数据库当前连接数,并发数
show starts like ’Threads%’;
Threads_cached : 代表当前此时此刻线程缓存中有多少空闲线程。
Threads_connected :代表当前已建立连接的数量,因为一个连接就需要一个线程,所以也可以看成当前被使用的线程数。
Threads_created :代表从最近一次服务启动,已创建线程的数量。
Threads_running :代表当前激活的(非睡眠状态)线程数。并不是代表正在使用的线程数,有时候连接已建立,但是连接处于sleep状态,这里相对应的线程也是sleep状态。
13,查看数据文件存放路径
show variables like ‘%datadir%’;
14,创建数据库
1、create schema [数据库名称] default character set utf8 collate utf8_general_ci;–创建数据库
采用create schema和create database创建数据库的效果一样。
2、create user ‘[用户名称]’@’%’ identified by ‘[用户密码]’;–创建用户
密码8位以上,包括:大写字母、小写字母、数字、特殊字符
%:匹配所有主机,该地方还可以设置成‘localhost’,代表只能本地访问,例如root账户默认为‘localhost‘
3、grant select,insert,update,delete,create on [数据库名称].* to [用户名称];–用户授权数据库
*代表整个数据库
4、flush privileges ;–立即启用修改
5、revoke all on . from tester;–取消用户所有数据库(表)的所有权限
6、delete from mysql.user where user=‘tester’;–删除用户
7、drop database [schema名称|数据库名称];–删除数据库
mysqld --verbose --help
shell> mysqladmin variables或者mysql> SHOW VARIABLES;
shell> mysqladmin extended-status或者mysql>SHOW STATUS;
说明:数据库中打开表的缓存数量。table_cache 与 max_connections 有关。例如,对于 200 个并行运行的连接,应该让表的缓存至少有 200 * N,这里 N 是可以执行的查询的一个联接中表的最大数量。还需要为临时表和文件保留一些额外的文件描述符。
设置技巧: 可以通过检查 mysqld 的状态变量 Opened_tables 确定表缓存是否太小:mysql> SHOW STATUS LIKE 'Opened_tables';+---------------+-------+| Variable_name | Value |+---------------+-------+| Opened_tables | 2741 |+---------------+-------+
如果值很大,即使你没有发出许多 FLUSH TABLES 语句,也应增加表缓存的大小
作用:查询缓存存储 SELECT 查询的文本以及发送给客户端的相应结果。如果随后收到一个相同的查询,服务器从查询缓存中重新得到查询结果,而不再需要解析和执行查询。
适用范围:不发生数据更新的表。当表更改(包括表结构和表数据)后,查询缓存值的相关条目被清空。 查询缓存的主要参数设置:show variables like ‘%query_cache%’;have_query_cache 表明服务器在安装使已经配置了高速缓存query_cache_size 表明缓存区大小,单位为 Mquery_cache_type 的变量值从 0 到 2,含义分别为0 或者 off(缓存关闭)
1 或者 on(缓存打开,使用 sql_no_cache 的 select 除外)
2 或者 demand(只有带 sql_cache 的 select 语句提供高速缓存) 在 SHOW STATUS 中,你可以监视查询缓存的性能:在操作系统层面,可以通过free命令查看系统内存资源使用情况,通过top -c命令查看进程使用内存占用情况。
root:~# free -mt total used free shared buff/cache availableMem: 16046 14928 201 13 917 753Swap: 0 0 0Total: 16046 14928 201
free命令显示内存占用情况:
总内存: 16046MB ≈ 16GB 已用内存: 14928MB ≈ 14.9GB 可用内存: free + buff/cache = 1118MB ≈ 1.1GB 即可用内存比例: 1.1GB / 16GB = 6.8%,通常我们系统监控内存低于10%就会告警。查看系统进程,检查内存占用情况。
top - 16:11:01 up 71 days, 7:23, 1 user, load average: 0.09, 0.07, 0.20Tasks: 188 total, 1 running, 187 sleeping, 0 stopped, 0 zombie%Cpu(s): 2.1 us, 0.6 sy, 0.0 ni, 97.2 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 stKiB Mem : 16431688 total, 208716 free, 15291936 used, 931036 buff/cacheKiB Swap: 0 total, 0 free, 0 used. 766408 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 6626 mysql 20 0 16.064g 0.014t 6436 S 12.0 91.0 66694:13 /usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --basedir=/usr/local/mysql --datadir=/data/mysql --plugin-dir=/usr/local/mysql/lib/plugin --user=mysq+
通过top -c命令发现mysql进程占用内存%MEM (91.0%),接下来检查下mysql是哪些线程和事件占用较高内存的。 首先检查实例的共享内存分配情况几个参数配置:
共享内存
mysql> select VARIABLE_NAME, VARIABLE_VALUE, concat(VARIABLE_VALUE/1024/1024,' MB') AS VARIABLE_VALUE_MB from information_schema.SESSION_VARIABLES where variable_name in ('innodb_buffer_pool_size','innodb_log_buffer_size','innodb_additional_mem_pool_size','key_buffer_size','query_cache_size');+-------------------------+----------------+-------------------+| VARIABLE_NAME | VARIABLE_VALUE | VARIABLE_VALUE_MB |+-------------------------+----------------+-------------------+| KEY_BUFFER_SIZE | 33554432 | 32 MB || QUERY_CACHE_SIZE | 1048576 | 1 MB || INNODB_LOG_BUFFER_SIZE | 67108864 | 64 MB || INNODB_BUFFER_POOL_SIZE | 10737418240 | 10240 MB |+-------------------------+----------------+-------------------+4 rows in set, 1 warning (0.00 sec)
检查了Innodb buffer的内存参数设置值10240MB = 10G, 占总内存 10G/16GB = 62.5%,该值设置在合理的范围内,详细的参数介绍可以参考官方文档,当系统内存严重不足时, 快速恢复可以降低共享内存,调整该参数后,内存会立马释放:
mysql> set global innodb_buffer_pool_size=8589934592;Query OK, 0 rows affected (0.00 sec)mysql> select VARIABLE_NAME, VARIABLE_VALUE, concat(VARIABLE_VALUE/1024/1024,' MB') AS VARIABLE_VALUE_MB from information_schema.SESSION_VARIABLES where variable_name in ('innodb_buffer_pool_size','innodb_log_buffer_size','innodb_additional_mem_pool_size','key_buffer_size','query_cache_size');+-------------------------+----------------+-------------------+| VARIABLE_NAME | VARIABLE_VALUE | VARIABLE_VALUE_MB |+-------------------------+----------------+-------------------+| KEY_BUFFER_SIZE | 33554432 | 32 MB || QUERY_CACHE_SIZE | 1048576 | 1 MB || INNODB_LOG_BUFFER_SIZE | 67108864 | 64 MB || INNODB_BUFFER_POOL_SIZE | 8589934592 | 8192 MB |+-------------------------+----------------+-------------------+4 rows in set, 1 warning (0.00 sec)mysql> system free -mt total used free shared buff/cache availableMem: 16046 13020 2081 13 944 2666Swap: 0 0 0Total: 16046 13020 2081
这里我们为了快速释放系统内存,调整了INNODB_BUFFER_POOL_SIZE值后,可用内存恢复2G。
Session私有内存
共享内存中介绍的内存空间是实例创建时即分配的内存空间,并且是所有连接共享的。而出现 OOM 异常的实例通常都是由于下面各个连接私有的内存造成的。
mysql> select VARIABLE_NAME, VARIABLE_VALUE, concat(VARIABLE_VALUE/1024/1024,' MB') AS VARIABLE_VALUE_MB from information_schema.SESSION_VARIABLES where variable_name in ('read_buffer_size','read_rnd_buffer_size','sort_buffer_size','join_buffer_size','binlog_cache_size','tmp_table_size');+----------------------+----------------+-------------------+| VARIABLE_NAME | VARIABLE_VALUE | VARIABLE_VALUE_MB |+----------------------+----------------+-------------------+| SORT_BUFFER_SIZE | 33554432 | 32 MB || READ_RND_BUFFER_SIZE | 33554432 | 32 MB || READ_BUFFER_SIZE | 16777216 | 16 MB || BINLOG_CACHE_SIZE | 32768 | 0.03125 MB || TMP_TABLE_SIZE | 67108864 | 64 MB || JOIN_BUFFER_SIZE | 134217728 | 128 MB |+----------------------+----------------+-------------------+6 rows in set, 1 warning (0.00 sec)
这里的私有内存JOIN_BUFFER_SIZE=128MB, 默认值是256KB。用于普通索引扫描、范围索引扫描和不使用索引而执行全表扫描的联接的缓冲区的最小大小。通常获得快速连接的最佳方法是添加索引。在无法添加索引时,增加join_buffer_size的值,以获得更快的完全连接。为两个表之间的每个完整连接分配一个连接缓冲区。对于没有使用索引的几个表之间的复杂联接,可能需要多个联接缓冲区。
除非使用块嵌套循环或批处理键访问算法,否则设置大于保存每个匹配行所需的缓冲区不会有任何好处,并且所有连接至少分配最小的大小,因此在全局将该变量设置为大值时要小心。最好保持全局设置较小,只在执行大型连接的会话中将会话设置更改为较大的值。如果全局大小大于使用它的大多数查询所需要的大小,那么内存分配时间可能会导致显著的性能下降。
通过检查私有内存,我们发现这是的JOIN_BUFFER_SIZE全局设置较大。
内存监控
MySQL5.7版本通过performance_schema可以方便的查看内存占用情况, 前提是要打开监控,执行如下SQL语句,打开内存监控。mysql> update performance_schema.setup_instruments set enabled = 'yes' where name like 'memory%';mysql> select * from performance_schema.setup_instruments where name like 'memory%innodb%' limit 20;+-------------------------------------------+---------+-------+| NAME | ENABLED | TIMED |+-------------------------------------------+---------+-------+| memory/innodb/adaptive hash index | YES | NO || memory/innodb/buf_buf_pool | YES | NO || memory/innodb/dict_stats_bg_recalc_pool_t | YES | NO || memory/innodb/dict_stats_index_map_t | YES | NO || memory/innodb/dict_stats_n_diff_on_level | YES | NO || memory/innodb/other | YES | NO || memory/innodb/row_log_buf | YES | NO || memory/innodb/row_merge_sort | YES | NO || memory/innodb/std | YES | NO || memory/innodb/trx_sys_t::rw_trx_ids | YES | NO || memory/innodb/partitioning | YES | NO || memory/innodb/api0api | YES | NO || memory/innodb/btr0btr | YES | NO || memory/innodb/btr0bulk | YES | NO || memory/innodb/btr0cur | YES | NO || memory/innodb/btr0pcur | YES | NO || memory/innodb/btr0sea | YES | NO || memory/innodb/buf0buf | YES | NO || memory/innodb/buf0dblwr | YES | NO || memory/innodb/buf0dump | YES | NO |+-------------------------------------------+---------+-------+20 rows in set (0.00 sec)
该命令是在线打开内存统计,所以只会统计打开后新增的内存对象,打开前的内存对象不会统计,建议您打开后等待一段时间再执行后续步骤,便于找出内存使用高的线程。
内存相关表
这里我们查看performance_schema相关的内存监控表有哪些,分别可以统计哪些信息。
mysql> show tables like '%memory%';+-----------------------------------------+| Tables_in_performance_schema (%memory%) |+-----------------------------------------+| memory_summary_by_account_by_event_name || memory_summary_by_host_by_event_name || memory_summary_by_thread_by_event_name || memory_summary_by_user_by_event_name || memory_summary_global_by_event_name |+-----------------------------------------+5 rows in set (0.00 sec)
mysql> select event_name, SUM_NUMBER_OF_BYTES_ALLOC from performance_schema.memory_summary_global_by_event_name order by SUM_NUMBER_OF_BYTES_ALLOC desc LIMIT 10;+---------------------------------------+---------------------------+| event_name | SUM_NUMBER_OF_BYTES_ALLOC |+---------------------------------------+---------------------------+| memory/sql/JOIN_CACHE | 966665202302976 || memory/memory/HP_PTRS | 304457132043176 || memory/innodb/mem0mem | 29273314618616 || memory/sql/thd::main_mem_root | 18376092762472 || memory/sql/Filesort_buffer::sort_keys | 3155343016712 || memory/sql/String::value | 2708659513792 || memory/sql/test_quick_select | 2146347475648 || memory/sql/QUICK_RANGE_SELECT::alloc | 1961041015680 || memory/mysys/IO_CACHE | 1463097599496 || memory/sql/TABLE | 635194922117 |+---------------------------------------+---------------------------+10 rows in set (0.01 sec)
注意到 “memory/sql/JOIN_CACHE” 消耗的内存最大。
(二)统计线程消耗内存
mysql> select thread_id, event_name, SUM_NUMBER_OF_BYTES_ALLOC from performance_schema.memory_summary_by_thread_by_event_name order by SUM_NUMBER_OF_BYTES_ALLOC desc limit 10; +-----------+-----------------------+---------------------------+| thread_id | event_name | SUM_NUMBER_OF_BYTES_ALLOC |+-----------+-----------------------+---------------------------+| 1922626 | memory/innodb/mem0mem | 1984233347055 || 1922439 | memory/innodb/mem0mem | 1404615671548 || 1954681 | memory/innodb/mem0mem | 1375641196768 || 1922431 | memory/innodb/mem0mem | 1350354644688 || 1954682 | memory/innodb/mem0mem | 1099479913383 || 1922625 | memory/innodb/mem0mem | 1097551130366 || 2686170 | memory/innodb/mem0mem | 992829979036 || 1922433 | memory/innodb/mem0mem | 874412348141 || 1922438 | memory/innodb/mem0mem | 863348539942 || 1922432 | memory/innodb/mem0mem | 754779357792 |+-----------+-----------------------+---------------------------+10 rows in set (0.02 sec)
(三)统计账户消耗内存
mysql> select USER, HOST, EVENT_NAME, SUM_NUMBER_OF_BYTES_ALLOC from performance_schema.memory_summary_by_account_by_event_name order by SUM_NUMBER_OF_BYTES_ALLOC desc limit 10; +-------------------+---------------+-----------------------+---------------------------+| USER | HOST | EVENT_NAME | SUM_NUMBER_OF_BYTES_ALLOC |+-------------------+---------------+-----------------------+---------------------------+| c********** | 192.168.*.* | memory/sql/JOIN_CACHE | 638622579556352 || c********** | 192.168.*.* | memory/sql/JOIN_CACHE | 276949456912384 || b********** | 192.168.*.* | memory/memory/HP_PTRS | 166067384571544 || b********** | 192.168.*.* | memory/memory/HP_PTRS | 76145767762936 || b********** | 192.168.*.* | memory/sql/JOIN_CACHE | 42176612401152 || z********** | 192.168.*.* | memory/memory/HP_PTRS | 30219030003816 || s********** | 192.168.*.* | memory/innodb/mem0mem | 16114310343537 || b********** | 192.168.*.* | memory/sql/JOIN_CACHE | 9070736048128 || c********** | 192.168.*.* | memory/innodb/mem0mem | 4787044880366 || a********** | 192.168.*.* | memory/memory/HP_PTRS | 4764584763968 |+-------------------+---------------+-----------------------+---------------------------+10 rows in set (0.16 sec)
这里把相关敏感信息脱敏了,从上面发现用户 c* 占用内存最大。 事件还是memory/sql/JOIN_CACHE
(四)统计主机消耗内存
mysql > select HOST, EVENT_NAME, SUM_NUMBER_OF_BYTES_ALLOC from performance_schema.memory_summary_by_host_by_event_name order by SUM_NUMBER_OF_BYTES_ALLOC desc limit 10; +---------------+-------------------------------+---------------------------+| HOST | EVENT_NAME | SUM_NUMBER_OF_BYTES_ALLOC |+---------------+-------------------------------+---------------------------+| 192.168.*.* | memory/sql/JOIN_CACHE | 681148560703488 || 192.168.*.* | memory/sql/JOIN_CACHE | 286124345917440 || 192.168.*.* | memory/memory/HP_PTRS | 166777472915704 || 192.168.*.* | memory/memory/HP_PTRS | 76851688652536 || 192.168.*.* | memory/memory/HP_PTRS | 30227900416896 || 192.168.*.* | memory/innodb/mem0mem | 16117796446781 || 192.168.*.* | memory/memory/HP_PTRS | 7457591548256 || 192.168.*.* | memory/innodb/mem0mem | 6596914688112 || 192.168.*.* | memory/sql/thd::main_mem_root | 5979929501808 || 192.168.*.* | memory/sql/thd::main_mem_root | 4795924383312 |+---------------+-------------------------------+---------------------------+10 rows in set (0.07 sec)
通过上面的主机,也能快速定位是哪台主机占用内存大,有必要时可以重启该主机的应用。
(五)统计用户消耗内存
mysql> select USER, EVENT_NAME, SUM_NUMBER_OF_BYTES_ALLOC from performance_schema.memory_summary_by_user_by_event_name order by SUM_NUMBER_OF_BYTES_ALLOC desc limit 10; +-------------------+-------------------------------+---------------------------+| USER | EVENT_NAME | SUM_NUMBER_OF_BYTES_ALLOC |+-------------------+-------------------------------+---------------------------+| c**************** | memory/sql/JOIN_CACHE | 915572036468736 || b**************** | memory/memory/HP_PTRS | 242213179169888 || b**************** | memory/sql/JOIN_CACHE | 51247348449280 || z**************** | memory/memory/HP_PTRS | 30225123465960 || b**************** | memory/memory/HP_PTRS | 21863256050496 || s**************** | memory/innodb/mem0mem | 16116655699153 || e**************** | memory/sql/thd::main_mem_root | 9554995144176 || c**************** | memory/innodb/mem0mem | 6360931505366 || a**************** | memory/memory/HP_PTRS | 4765617785408 || s**************** | memory/sql/thd::main_mem_root | 3074066885016 |+-------------------+-------------------------------+---------------------------+10 rows in set (0.06 sec)
找到问题事件或线程后,您可以排查业务代码和环境,解决内存高的问题。上面统计结果发现到 “memory/sql/JOIN_CACHE” 事件消耗的内存最大。调整全局JOIN_BUFFER_SIZE=32MB,再观察内存占用情况。
mysql> set global join_buffer_size=33554432;Query OK, 0 rows affected (0.00 sec)mysql> quitmysql> select VARIABLE_NAME, VARIABLE_VALUE, concat(VARIABLE_VALUE/1024/1024,' MB') AS VARIABLE_VALUE_MB from information_schema.SESSION_VARIABLES where variable_name in ('read_buffer_size','read_rnd_buffer_size','sort_buffer_size','join_buffer_size','binlog_cache_size','tmp_table_size');+----------------------+----------------+-------------------+| VARIABLE_NAME | VARIABLE_VALUE | VARIABLE_VALUE_MB |+----------------------+----------------+-------------------+| SORT_BUFFER_SIZE | 33554432 | 32 MB || READ_RND_BUFFER_SIZE | 33554432 | 32 MB || READ_BUFFER_SIZE | 16777216 | 16 MB || BINLOG_CACHE_SIZE | 32768 | 0.03125 MB || TMP_TABLE_SIZE | 67108864 | 64 MB || JOIN_BUFFER_SIZE | 33554432 | 32 MB |+----------------------+----------------+-------------------+6 rows in set, 1 warning (0.00 sec)mysql> select * from information_schema.processlist where COMMAND='sleep' and Time>1000 order by Time desc;
这里会话参数调整后,需同时调整/etc/my.cnf的配置,下次服务启动永久生效,另外之前连接的会话线程由于已分配了该buffer大小,调整后内存并不会马上释放。
1.创建索引
这是最基本的索引,它没有任何限制。它有以下几种创建方式: CREATE INDEX indexName ON mytable(username(length)); 如果是 CHAR,VARCHAR 类型,length 可以小于字段实际长度;如果是 BLOB 和 TEXT 类型,必须指定 length。2.修改表结构
ALTER mytable ADD INDEX [indexName] ON (username(length))
3.创建表的时候直接指定
CREATE TABLE mytable(ID INT NOT NULL,username VARCHAR(16) NOT NULL,INDEX [indexName] (username(length)));
4.删除索引的语法
DROP INDEX [indexName] ON mytable;
它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值
的组合必须唯一。它有以下几种创建方式:1.创建索引
REATE UNIQUE INDEX indexName ON mytable(username(length))
2.修改表结构
ALTER mytable ADD UNIQUE [indexName] ON (username(length))
3.创建表的时候直接指定
CREATE TABLE mytable(ID INT NOT NULL,username VARCHAR(16) NOT NULL,UNIQUE [indexName] (username(length)));
有四种方式来添加数据表的索引:
1. ALTER TABLE tbl_name ADD PRIMARY KEY (column_list): 该语句添加一个主键,这意味着索引值必须是唯一的,且不能为 NULL。 2. ALTER TABLE tbl_name ADD UNIQUE index_name (column_list): 这条语句创建索引的值必须是唯一的(除了 NULL 外,NULL 可能会出现多次)。 3. ALTER TABLE tbl_name ADD INDEX index_name (column_list): 添加普通索引,索引值可出现多次。 4. ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list): 该语句指定了索引为 FULLTEXT ,用于全文索引。你可以使用 SHOW INDEX 命令来列出表中的相关的索引信息。可以通过添加 \G 来格式化输出
信息。 尝试以下实例: mysql> SHOW INDEX FROM table_name\GMySQL 中你可以使用 SELECT…INTO OUTFILE 语句来简单的导出数据到文本文件上。
1).使用 SELECT … INTO OUTFILE 语句导出数据
以下实例中我们将数据表 w3cschool_tbl 数据导出到 /tmp/tutorials.txt 文件中:mysql> SELECT * FROM tutorials_tbl-> INTO OUTFILE '/tmp/tutorials.txt';
你可以通过命令选项来设置数据输出的指定格式,以下实例为导出 CSV 格式:
mysql> SELECT * FROM passwd INTO OUTFILE '/tmp/tutorials.txt'-> FIELDS TERMINATED BY ',' ENCLOSED BY '"'-> LINES TERMINATED BY '\r\n';
在下面的例子中,生成一个文件,各值用逗号隔开。这种格式可以被许多程序使用。
SELECT a,b,a+b INTO OUTFILE '/tmp/result.text'FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'LINES TERMINATED BY '\n'FROM test_table;
如果你需要导出整个数据库的数据,可以使用以下命令:
$ mysqldump -u root -p W3CSCHOOL > database_dump.txt password ****** 如果需要备份所有数据库,可以使用以下命令: $ mysqldump -u root -p --all-databases > database_dump.txt password ****** –all-databases 选项在 MySQL 3.23.12 及以后版本加入。 该方法可用于实现数据库的备份策略。如果你需要将数据拷贝至其他的 MySQL 服务器上, 你可以在 mysqldump 命令中指定数据库名及数据表。
在源主机上执行以下命令,将数据备份至 dump.txt 文件中:$ mysqldump -u root -p database_name table_name > dump.txtpassword *****
如果完整备份数据库,则无需使用特定的表名称。
如果你需要将备份的数据库导入到 MySQL 服务器中,可以使用以下命令,使用以下命令你需要确认数据库已经创建:$ mysql -u root -p database_name < dump.txt password *****
你也可以使用以下命令将导出的数据直接导入到远程的服务器上,但请确保两台服务器是相通的,是可以相互访问的:
$ mysqldump -u root -p database_name \| mysql -h other-host.com database_name
以上命令中使用了管道来将导出的数据导入到指定的远程主机上。
通过MySQL的 information_schema 数据库,可查询数据库中每个表占用的空间、表记录的行数;该库中有一个 TABLES 表,这个表主要字段分别是:
TABLE_SCHEMA : 数据库名TABLE_NAME:表名ENGINE:所使用的存储引擎TABLES_ROWS:记录数DATA_LENGTH:数据大小INDEX_LENGTH:索引大小
其他字段请参考MySQL的手册,查看一个表占用空间的大小,那就相当于是 数据大小 + 索引大小 。
(1)单位是GB
#SELECT CONCAT(ROUND(SUM(index_length)/(1024*1024*1024), 2), ' GB') AS 'Total Index Size' FROM information_schema.TABLES WHERE table_schema LIKE 'database';+------------------+| Total Index Size |+------------------+| 1.70 GB |+------------------+
(2)单位是MB
SELECT CONCAT(ROUND(SUM(index_length)/(1024*1024), 2), ' MB') AS 'Total Index Size' FROM information_schema.TABLES WHERE table_schema LIKE 'database';
其中“database”为你所要查看的数据库
#SELECT CONCAT(ROUND(SUM(data_length)/(1024*1024*1024), 2), ' GB') AS 'Total Data Size'FROM information_schema.TABLES WHERE table_schema LIKE 'database';+-----------------+| Total Data Size |+-----------------+| 3.01 GB |+-----------------+
>show processlist
查看当前数据库应该/“肯定”存在未提交的事务
>show engine innodb status \G
SELECT CONCAT(table_schema,'.',table_name) AS 'Table Name',CONCAT(ROUND(table_rows/1000000,2),'M') AS 'Number of Rows',CONCAT(ROUND(data_length/(1024*1024*1024),2),'G') AS 'Data Size',CONCAT(ROUND(index_length/(1024*1024*1024),2),'G') AS 'Index Size' ,CONCAT(ROUND((data_length+index_length)/(1024*1024*1024),2),'G') AS'Total'FROM information_schema.TABLES WHERE table_schema LIKE 'database';
mysql> use information_schema;Database changedmysql> select concat(round(sum(DATA_LENGTH/1024/1024),2),'MB') as data from TABLES;+----------+| data |+----------+| 104.21MB |+----------+row in set (0.11 sec)
mysql> select concat(round(sum(DATA_LENGTH/1024/1024),2),'MB') as data from TABLES where table_schema='jishi';+---------+| data |+---------+| 26.17MB |+---------+row in set (0.01 sec)
mysql> select concat(round(sum(DATA_LENGTH/1024/1024),2),'MB') as data from TABLES where table_schema='jishi' and table_name='a_ya';+--------+| data |+--------+| 0.02MB |+--------+row in set (0.00 sec)
mysql> SELECT CONCAT(ROUND(SUM(index_length)/(1024*1024), 2), ' MB') AS 'Total Index Size' FROM TABLES WHERE table_schema = 'jishi'; +------------------+| Total Index Size |+------------------+| 0.94 MB |+------------------+row in set (0.01 sec)
mysql> SELECT CONCAT(ROUND(SUM(index_length)/(1024*1024), 2), ' MB') AS 'Total Index Size' FROM TABLES WHERE table_schema = 'test' and table_name='a_yuser'; +------------------+| Total Index Size |+------------------+| 21.84 MB |+------------------+row in set (0.00 sec)mysql> show create table test.a_yuser\G;*************************** 1. row *************************** Table: a_yuserCreate Table: CREATE TABLE `a_yuser` ( `email` varchar(60) NOT NULL DEFAULT '', `user_name` varchar(60) NOT NULL DEFAULT '', KEY `cc` (`email`(5)), KEY `ccb` (`user_name`(5)), KEY `ccbc` (`email`(5),`user_name`(5))) ENGINE=MyISAM DEFAULT CHARSET=utf8row in set (0.00 sec) ERROR: No query specified mysql> select count(*) from test.a_yuser;+----------+| count(*) |+----------+| 1073607 |+----------+row in set (0.00 sec)
mysql> SELECT CONCAT(table_schema,'.',table_name) AS 'Table Name', CONCAT(ROUND(table_rows/1000000,4),'M') AS 'Number of Rows', CONCAT(ROUND(data_length/(1024*1024*1024),4),'G') AS 'Data Size', CONCAT(ROUND(index_length/(1024*1024*1024),4),'G') AS 'Index Size', CONCAT(ROUND((data_length+index_length)/(1024*1024*1024),4),'G') AS'Total'FROM information_schema.TABLES WHERE table_schema LIKE 'test';+---------------+----------------+-----------+------------+---------+| Table Name | Number of Rows | Data Size | Index Size | Total |+---------------+----------------+-----------+------------+---------+| test.a_br | 0.4625M | 0.0259G | 0.0171G | 0.0431G || test.a_skuclr | 0.7099M | 0.0660G | 0.0259G | 0.0919G || test.a_yuser | 1.0736M | 0.0497G | 0.0213G | 0.0710G || test.test | 0.0000M | 0.0000G | 0.0000G | 0.0000G |+---------------+----------------+-----------+------------+---------+rows in set (0.13 sec)
SELECT TABLE_NAME,DATA_LENGTH,INDEX_LENGTH,(DATA_LENGTH+INDEX_LENGTH) as length,TABLE_ROWS,concat(round((DATA_LENGTH+INDEX_LENGTH)/1024/1024,3), 'MB') as total_size FROM information_schema.TABLES WHERE TABLE_SCHEMA='database_name' order by length desc
结果:
+------------------------------+-------------+--------------+------------+------------+------------+| TABLE_NAME | DATA_LENGTH | INDEX_LENGTH | length | TABLE_ROWS | total_size |+------------------------------+-------------+--------------+------------+------------+------------+| log | 959226404 | 932541440 | 1891767844 | 19966020 | 1804.130MB || articles | 1528283112 | 6710272 | 1534993384 | 459585 | 1463.884MB || category_aticles| 24895262 | 85363712 | 110258974 | 1778233 | 105.151MB ||user | 43867824 | 489472 | 44357296 | 47476 | 42.302MB |
说明:
TABLE_NAME :表名字;
DATA_LENGTH : 数据大小; INDEX_LENGTH :索引大小; TABLE_ROWS : 记录数量; TABLE_SCHEMA : 数据库名字; ENGINE:所使用的存储引擎; information_schema : 是mysql自带的,它提供了访问数据库元数据的方式,元数据是关于数据的数据, 如数据库名或表名,列的数据类型,或访问权限等。有些时候用于表述该信息的其他术语包括“数据词典”和“系统目录”。一个表占用空间的大小,相当于是 数据大小 + 索引大小;
mysql 账户权限查询
1.查询当前登录用户权限mysql> show grants; //(linux)show grants; //(windows)
mysql> show grants for zjjxjy; //(linux)show grants for zjjxjy; //(windows)
mysql> select * from mysql.user where user='zjjxjy'\G; //(linux)select * from mysql.user where user='zjjxjy'; //(windows)
All/All Privileges权限代表全局或者全数据库对象级别的所有权限Alter权限代表允许修改表结构的权限,但必须要求有create和insert权 限配合。如果是rename表名,则要求有alter和drop原表,create和 insert新表的权限Alter routine权限代表允许修改或者删除存储过程、函数的权限Create权限代表允许创建新的数据库和表的权限Createroutine权限代表允许创建存储过程、函数的权限Createtablespace权限代表允许创建、修改、删除表空间和日志组的权 限Create temporary tables权限代表允许创建临时表的权限Createuser权限代表允许创建、修改、删除、重命名user的权限Createview权限代表允许创建视图的权限Delete权限代表允许删除行数据的权限Drop权限代表允许删除数据库、表、视图的权限,包括truncatetable命令Event权限代表允许查询,创建,修改,删除MySQL事件Execute权限代表允许执行存储过程和函数的权限File权限代表允许在MySQL可以访问的目录进行读写磁盘文件操作,可使用 的命令包括load data infile,select … into outfile,load file()函数Grant option权限代表是否允许此用户授权或者收回给其他用户你给予的权 限Index权限代表是否允许创建和删除索引Insert权限代表是否允许在表里插入数据,同时在执行analyze table,optimize table,repair table语句的时候也需要insert权限Lock权限代表允许对拥有select权限的表进行锁定,以防止其他链接对此表 的读或写Process权限代表允许查看MySQL中的进程信息,比如执行showprocesslist,Reference权限是在5.7.6版本之后引入,代表是否允许创建外键Reload权限代表允许执行flush命令,指明重新加载权限表到系统内存中, refresh命令代表关闭和重新开启日志文件并刷新所有的表Replication client权限代表允许执行show master status,show slave status,show binary logs命令Replication slave权限代表允许slave主机通过此用户连接master以便建立主从 复制关系Select权限代表允许从表中查看数据,某些不查询表数据的select执行则不需 要此权限,如Select 1+1,Select PI()+2;而且select权限在执行update/delete 语句中含有where条件的情况下也是需要的Showdatabases权限代表通过执行showdatabases命令查看所有的数据库名Show view权限代表通过执行show create view命令查看视图创建的语句mysqladmin processlist, show engine等命令
新建一个表,结构和数据来源于某表:
CREATE TABLE test SELECT * FROM t_user WHERE Id>5;
新建一个表,结构来源于某表:
CREATE TABLE TBNAME1 LIKE TBNAME2;
删除一个表:drop table {tablename};
更新一个表:
alter table { tablename} add age int(5); --添加字段ALTER TABLE { tablename} ADD ({ column_name1} VARCHAR(100),{ column_name2} CHAR(20)); --一次性添加几个字段alter table { tablename} drop [column] age; --删除字段alter table { tablename} change { old_column_name} { new_column_name} varchar(30); --修改字段alter table { tablename} modify { column_name} varchar(20) after { column_name}; --调整顺序alter table { tablename} modify { column_name} varchar(5) ; -- 修改字段的字段定义 alter table { tablename} rename { tablename2}; --更改表名为tablename2alter table { tablename} add unique (column_name); --给字段添加唯一值约束
对数据的操作:
插入数据:
insert into t_user (username,password,nick) values ('张三','888889','zha3gsan');insert into t_user values (2,'李四','888888','zhangsan');insert into t_user values (3,'王武','888888','zhangsan');insert into t_user values (4,'赵六','888888','zhangsan');insert into t_user values (5,'田七','888888','zhangsan');INSERT INTO user (id,name,age,adress,date) value('1','唐僧','20','科技二路','2015-11-17 14:19');INSERT INTO user (id,name,age,adress,date) value('2','孙悟空','520','科技二路','2015-11-17 14:19');INSERT INTO user (id,name,age) value('3','孙悟空','520');
删除数据:
DELETE FROM { tablename} WHERE { column}={ value}
清空表数据:
TRUNCATE table { tablename};
更新数据:
UPDATE { tablename} SET { column}={ value} WHERE { column}={ value};
查询一个表数据:
select * from { tablename}; ---查询表数据SELECT [DISTINCT] column FROM { tablename} WHERE CONDITION; --DISTINCT 去掉重复--组合条件,可以使用AND,OR,IS NULL,IS NOT NULL,in ,not in 组合多个条件
模糊查询:
select * from { tablename} where name like '%小%'(包含小)赵%,第一个字符为赵_小% 第二个字符为小
–将查询的结果进行排序,用,分开可多字段查询
SELECT * FROM { tablename} ORDER BY Name { ASC|DESC};
–查询结果别名显示
SELECT Name AS Stu_Name FROM { tablename};select * from tablename limit 2,4
–从第3条开始取4条数据
–即取出第3(从0开始)条至第6条,4条记录SELECT AVG(age) FROM { tablename};
–求平均数:AVG(),最大值:MAX() 最小值MIN() 数量:COUNT() 求和:SUM()
SELECT Age, Gender FROM students GROUP BY Gender;
–分组GROUP BY
SELECT COUNT(Age) AS Num,Age FROM students GROUP BY Age;--别名:ASSELECT COUNT(Age) AS Num,Age FROM students GROUP BY Age HAVING Num>2;
–过滤:HAVING,当查询出来的数据再过滤就需要用having
多表查询:1.以前的写法
select * from t_cla t1,t_stu t2 where t1.id=t2.cla_id and t1.id in (1,2,3);
2.常用的方式是使用join 和 on来连接的,join表示将表连接起来,on(连接的字段关系)
select t1.name,t2.name from t_cla t1 join t_stu t2 on(t1.id=t2.cla_id) where t2.id in (1,2,3);
3.左连接 left join
左连接是将左边的这张表设置为主表来连接右边的表,左表的数据会全部显示,如果左表边表中的数据在右表中没有出现,会自动使用null来替代。select t1.name count(t2.id) from t_cla t1 left join s_stu t2 on(t2.cla_id=t1.id) group by t1.id
4.右连接right join
右连接是将右边的这张表设置为主表来连接左边的表,右边的数据会全部显示,如果右边表中的数据在左表中没有出现,会自动使用null来替代。MySQL中的参数general_log用来控制开启、关闭MySQL查询日志,参数general_log_file用来控制查询日志的位置。所以如果你要判断MySQL数据库是否开启了查询日志,可以使用下面命令。general_log为ON表示开启查询日志,OFF表示关闭查询日志。
mysql> show variables like '%general_log%';+------------------+------------------------------+| Variable_name | Value |+------------------+------------------------------+| general_log | OFF || general_log_file | /var/lib/mysql/DB-Server.log |+------------------+------------------------------+2 rows in set (0.00 sec)
另外,MySQL的查询日志支持写入文件或写入数据表两种形式,这个由参数log_output控制,如下所示:
mysql> show variables like 'log_output';+---------------+-------+| Variable_name | Value |+---------------+-------+| log_output | FILE |+---------------+-------+1 row in set (0.00 sec)
开启MySQL查询日志
mysql> set global general_log = on;Query OK, 0 rows affected (0.11 sec)mysql> show variables like 'general_log';+---------------+-------+| Variable_name | Value |+---------------+-------+| general_log | ON |+---------------+-------+1 row in set (0.02 sec)
关闭MySQL查询日志
mysql> show variables like 'general_log';+---------------+-------+| Variable_name | Value |+---------------+-------+| general_log | ON |+---------------+-------+1 row in set (0.01 sec)mysql> set global general_log=off;Query OK, 0 rows affected (0.01 sec)mysql> show variables like 'general_log';+---------------+-------+| Variable_name | Value |+---------------+-------+| general_log | OFF |+---------------+-------+1 row in set (0.00 sec)
设置日志输出方式为表
如果设置log_output=table的话,则日志结果会记录到名为gengera_log的表中,这表的默认引擎是CSV)。
mysql> show variables like 'log_output';+---------------+-------+| Variable_name | Value |+---------------+-------+| log_output | FILE |+---------------+-------+1 row in set (0.00 sec)mysql> set global log_output='table';Query OK, 0 rows affected (0.00 sec)mysql> show variables like 'log_output';+---------------+-------+| Variable_name | Value |+---------------+-------+| log_output | TABLE |+---------------+-------+1 row in set (0.01 sec)
查看查询日志信息。
mysql> select * from mysql.general_log;+---------------------+---------------------------+-----------+-----------+--------------+----------------------------------+| event_time | user_host | thread_id | server_id | command_type | argument |+---------------------+---------------------------+-----------+-----------+--------------+----------------------------------+| 2017-07-06 12:32:05 | root[root] @ localhost [] | 1 | 1 | Query | show variables like 'general%' || 2017-07-06 12:32:28 | root[root] @ localhost [] | 1 | 1 | Query | show variables like 'log_output' || 2017-07-06 12:32:41 | root[root] @ localhost [] | 1 | 1 | Query | select * from MyDB.test || 2017-07-06 12:34:36 | [root] @ localhost [] | 3 | 1 | Connect | root@localhost on || 2017-07-06 12:34:36 | root[root] @ localhost [] | 3 | 1 | Query | KILL QUERY 1 || 2017-07-06 12:34:36 | root[root] @ localhost [] | 3 | 1 | Quit | || 2017-07-06 12:34:51 | root[root] @ localhost [] | 1 | 1 | Query | select * from mysql.general_log |+---------------------+---------------------------+-----------+-----------+--------------+----------------------------------+7 rows in set (0.02 sec)
create database db1 DEFAULT CHARSET utf8 COLLATE utf8_general_ci; # utf8编码create database db1 DEFAULT CHARACTER SET gbk COLLATE gbk_chinese_ci; # gbk编码
创建用户
create user '用户名'@'IP地址' identified by '密码';
删除用户
drop user '用户名'@'IP地址';
修改用户
rename user '用户名'@'IP地址'; to '新用户名'@'IP地址';
修改密码
set password for '用户名'@'IP地址' = Password('新密码');
mysql对于权限这块有以下限制:
all privileges:除grant外的所有权限select:仅查权限select,insert:查和插入权限...usage:无访问权限alter:使用alter tablealter routine:使用alter procedure和drop procedurecreate:使用create tablecreate routine:使用create procedurecreate temporary tables:使用create temporary tablescreate user:使用create user、drop user、rename user和revoke all privilegescreate view:使用create viewdelete:使用deletedrop:使用drop tableexecute:使用call和存储过程file:使用select into outfile 和 load data infilegrant option:使用grant 和 revokeindex:使用indexinsert:使用insertlock tables:使用lock tableprocess:使用show full processlistselect:使用selectshow databases:使用show databasesshow view:使用show viewupdate:使用updatereload:使用flushshutdown:使用mysqladmin shutdown(关闭MySQL)super:使用change master、kill、logs、purge、master和set global。还允许mysqladmin调试登陆replication client:服务器位置的访问replication slave:由复制从属使用
用户授权给数据库
1、创建用户(修改密码)CREATE USER '用户名'@'%' IDENTIFIED BY '密码';
update user set password=password('新密码') where user='username'; //修改密码
2、授权数据库权限给用户
grant all privileges on 数据库名.* to '用户名'@'%'; // '%'代表可以在任何主机登陆,可以替换为具体ip地址all 可以替换为 select,delete,update,create,drop
3、刷新权限
操作完毕的时候最好使用 flush privileges 命令刷新一下权限。否则可能会修改不生效flush privileges
对于数据库及内部其他权限如下:
数据库名.* 数据库中的所有数据库名.表 指定数据库中的某张表数据库名.存储过程 指定数据库中的存储过程*.* 所有数据库
对于用户和IP的权限如下:
用户名@IP地址 用户只能在改IP下才能访问用户名@192.168.1.% 用户只能在改IP段下才能访问(通配符%表示任意)用户名@% 用户可以再任意IP下访问(默认IP地址为%)
1、查看权限:
show grants for '用户'@'IP地址'
2、授权
grant 权限 on 数据库.表 to '用户'@'IP地址'
3、取消授权
revoke 权限 on 数据库.表 from '用户名'@'IP地址'
授权实例如下:
grant all privileges on db1.tb1 TO '用户名'@'IP'grant select on db1.* TO '用户名'@'IP'grant select,insert on *.* TO '用户名'@'IP'revoke select on db1.tb1 from '用户名'@'IP'
1、查看表
show tables; # 查看数据库全部表select * from 表名; # 查看表所有内容
2、创建表
create table 表名( 列名 类型 是否可以为空, 列名 类型 是否可以为空)ENGINE=InnoDB DEFAULT CHARSET=utf8
来一个实例好详解
CREATE TABLE `tab1` ( `nid` int(11) NOT NULL auto_increment, `name` varchar(255) DEFAULT zhangyanlin, `email` varchar(255), PRIMARY KEY (`nid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
注:
3、删除表
drop table 表名
4、清空表内容
delete from 表名truncate table 表名
5、修改表
添加列: alter table 表名 add 列名 类型删除列: alter table 表名 drop column 列名修改列: alter table 表名 modify column 列名 类型; -- 类型alter table 表名 change 原列名 新列名 类型; -- 列名,类型添加主键: alter table 表名 add primary key(列名);删除主键: alter table 表名 drop primary key;alter table 表名 modify 列名 int, drop primary key;添加外键: alter table 从表 add constraint 外键名称(形如:FK_从表_主表) foreign key 从表(外键字段) references 主表(主键字段);删除外键: alter table 表名 drop foreign key 外键名称修改默认值:ALTER TABLE testalter_tbl ALTER i SET DEFAULT 1000;删除默认值:ALTER TABLE testalter_tbl ALTER i DROP DEFAULT;
对于上述这些操作是不是看起来很麻烦,很浪费时间,别慌!有专门的软件能提供这些功能,操作起来非常简单,这个软件名字叫Navicat Premium ,大家自行在网上下载,练练手,但是下面的即将讲到表内容操作还是建议自己写命令来进行
6、基本数据类型
MySQL的数据类型大致分为:数值、时间和字符串
bit[(M)] 二进制位(101001),m表示二进制位的长度(1-64),默认m=1tinyint[(m)] [unsigned] [zerofill] 小整数,数据类型用于保存一些范围的整数数值范围: 有符号: -128 ~ 127. 无符号: 0 ~ 255 特别的: MySQL中无布尔值,使用tinyint(1)构造。int[(m)][unsigned][zerofill] 整数,数据类型用于保存一些范围的整数数值范围: 有符号: -2147483648 ~ 2147483647 无符号: 0 ~ 4294967295 特别的:整数类型中的m仅用于显示,对存储范围无限制。例如: int(5),当插入数据2时,select 时数据显示为:00002bigint[(m)][unsigned][zerofill] 大整数,数据类型用于保存一些范围的整数数值范围: 有符号: -9223372036854775808 ~ 9223372036854775807 无符号: 0 ~ 18446744073709551615decimal[(m[,d])] [unsigned] [zerofill] 准确的小数值,m是数字总个数(负号不算),d是小数点后个数。 m最大值为65,d最大值为30。 特别的:对于精确数值计算时需要用此类型 decaimal能够存储精确值的原因在于其内部按照字符串存储。FLOAT[(M,D)] [UNSIGNED] [ZEROFILL] 单精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数。 无符号: -3.402823466E+38 to -1.175494351E-38, 0 1.175494351E-38 to 3.402823466E+38 有符号: 0 1.175494351E-38 to 3.402823466E+38 **** 数值越大,越不准确 ****DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL] 双精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数。 无符号: -1.7976931348623157E+308 to -2.2250738585072014E-308 0 2.2250738585072014E-308 to 1.7976931348623157E+308 有符号: 0 2.2250738585072014E-308 to 1.7976931348623157E+308 **** 数值越大,越不准确 ****char (m) char数据类型用于表示固定长度的字符串,可以包含最多达255个字符。其中m代表字符串的长度。 PS: 即使数据小于m长度,也会占用m长度 varchar(m) varchars数据类型用于变长的字符串,可以包含最多达255个字符。其中m代表该数据类型所允许保存的字符串的最大长度,只要长度小于该最大值的字符串都可以被保存在该数据类型中。 注:虽然varchar使用起来较为灵活,但是从整个系统的性能角度来说,char数据类型的处理速度更快,有时甚至可以超出varchar处理速度的50%。因此,用户在设计数据库时应当综合考虑各方面的因素,以求达到最佳的平衡text text数据类型用于保存变长的大字符串,可以组多到65535 (2**16 − 1)个字符。mediumtext A TEXT column with a maximum length of 16,777,215 (2**24 − 1) characters.longtext A TEXT column with a maximum length of 4,294,967,295 or 4GB (2**32 − 1) characters.enum 枚举类型, An ENUM column can have a maximum of 65,535 distinct elements. (The practical limit is less than 3000.) 示例: CREATE TABLE shirts ( name VARCHAR(40), size ENUM('x-small', 'small', 'medium', 'large', 'x-large') ); INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), ('t-shirt','medium'),('polo shirt','small');set 集合类型 A SET column can have a maximum of 64 distinct members. 示例: CREATE TABLE myset (col SET('a', 'b', 'c', 'd')); INSERT INTO myset (col) VALUES ('a,d'), ('d,a'), ('a,d,a'), ('a,d,d'), ('d,a,d');DATE YYYY-MM-DD(1000-01-01/9999-12-31)TIME HH:MM:SS('-838:59:59'/'838:59:59')YEAR YYYY(1901/2155)DATETIME YYYY-MM-DD HH:MM:SS(1000-01-01 00:00:00/9999-12-31 23:59:59 Y)TIMESTAMP YYYYMMDD HHMMSS(1970-01-01 00:00:00/2037 年某时)
表内容操作无非就是增删改查,当然用的最多的还是查,而且查这一块东西最多,用起来最难,当然对于大神来说那就是so easy了,对于我这种小白还是非常难以灵活运用的,下面咱来一一操作一下
1、增
insert into 表 (列名,列名...) values (值,值,...)insert into 表 (列名,列名...) values (值,值,...),(值,值,值...)insert into 表 (列名,列名...) select (列名,列名...) from 表例: insert into tab1(name,email) values('zhangyanlin','zhangyanlin8851@163.com')
2、删
delete from 表 # 删除表里全部数据delete from 表 where id=1 and name='zhangyanlin' # 删除ID =1 和name='zhangyanlin' 那一行数据
3、改
update 表 set name = 'zhangyanlin' where id>1
4、查
select * from 表select * from 表 where id > 1select nid,name,gender as gg from 表 where id > 1
查这块的条件太多太多我给列举出来至于组合还得看大家的理解程度哈
a、条件判断where
select * from 表 where id > 1 and name != 'aylin' and num = 12;select * from 表 where id between 5 and 16;select * from 表 where id in (11,22,33)select * from 表 where id not in (11,22,33)select * from 表 where id in (select nid from 表)
b、通配符like
select * from 表 where name like 'zhang%' # zhang开头的所有(多个字符串)select * from 表 where name like 'zhang_' # zhang开头的所有(一个字符)
c、限制limit
select * from 表 limit 5; - 前5行select * from 表 limit 4,5; - 从第4行开始的5行select * from 表 limit 5 offset 4 - 从第4行开始的5行
d、排序asc,desc
select * from 表 order by 列 asc - 根据 “列” 从小到大排列select * from 表 order by 列 desc - 根据 “列” 从大到小排列select * from 表 order by 列1 desc,列2 asc - 根据 “列1” 从大到小排列,如果相同则按列2从小到大排序
e、分组group by
select num from 表 group by numselect num,nid from 表 group by num,nidselect num,nid from 表 where nid > 10 group by num,nid order nid descselect num,nid,count(*),sum(score),max(score),min(score) from 表 group by num,nidselect num from 表 group by num having max(id) > 10特别的:group by 必须在where之后,order by之前
并发数是指同一时刻数据库能处理多少个请求,由max_connections和max_user_connections决定。max_connections是指MySQL实例的最大连接数,上限值是16384,max_user_connections是指每个数据库用户的最大连接数。
MySQL会为每个连接提供缓冲区,意味着消耗更多的内存。如果连接数设置太高硬件吃不消,太低又不能充分利用硬件。一般要求两者比值超过10%,计算方法如下:
max_used_connections / max_connections * 100% = 3/100 *100% ≈ 3%
查看最大连接数与响应最大连接数:
show variables like '%max_connections%';show variables like '%max_user_connections%';
在配置文件my.cnf中修改最大连接数
[mysqld]max_connections = 100max_used_connections = 20
>show binlog events\G>show master status;>show slave staus\G
查看其他库中所有的表:show tables from 库名;
mysql> show tables from seata;
查看表的创建语句:show create table 表名;
mysql> show create table biz_tags;
查看表结构:desc 表名;
mysql> desc biz_tags;
查看当前mysql⽀持的存储引擎:SHOW ENGINES;
mysql> SHOW ENGINES;
查看系统变量及其值:SHOW VARIABLES;
mysql> SHOW VARIABLES;
查看某个系统变量:SHOW VARIABLES like ‘变量名’;
mysql> SHOW VARIABLES like 'wait_timeout';
撤销⽤户的权限
语法 revoke privileges ON database.table FROM ‘⽤户名’[@‘主机’]; 可以先通过 show grants 命令查询⼀下⽤户对于的权限,然后使⽤ revoke 命令撤销⽤户 对应的权限,⽰例:mysql> show grants for 'test1'@'localhost';+--------------------------------------------------------------------+| Grants for test1@localhost |+--------------------------------------------------------------------+| GRANT USAGE ON *.* TO 'test1'@'localhost' || GRANT SELECT (host, user) ON `mysql`.`user` TO 'test1'@'localhost' |+--------------------------------------------------------------------+2 rows in set (0.00 sec)mysql> revoke select(host) on mysql.user from test1@localhost;Query OK, 0 rows affected (0.00 sec)mysql> show grants for 'test1'@'localhost';+--------------------------------------------------------------+| Grants for test1@localhost |+--------------------------------------------------------------+| GRANT USAGE ON *.* TO 'test1'@'localhost' || GRANT SELECT (user) ON `mysql`.`user` TO 'test1'@'localhost' |+--------------------------------------------------------------+2 rows in set (0.00 sec)
CURTIME() 和 CURRENT_TIME() 函数的作⽤相同,将当前时间以“HH:MM:
SS”或“HHMMSS”格式返回,具体格式根据函数⽤在字符串或数字语境中⽽定, 返回 time 类型。mysql> select curtime(),current_time(),current_time()+1;+-----------+----------------+------------------+| curtime() | current_time() | current_time()+1 |+-----------+----------------+------------------+| 16:11:25 | 16:11:25 | 161126 |+-----------+----------------+------------------+1 row in set (0.00 sec)
now 和 sysdate:获取当前时间⽇期
NOW() 和 SYSDATE() 函数的作⽤相同,都是返回当前⽇期和时间值,格式为 “YYYY-MM-DD HH:MM:SS”或“YYYYMMDDHHMMSS”,具体格式根据函数⽤在 字符串或数字语境中⽽定,返回 datetime 类型mysql> select now(),sysdate();+---------------------+---------------------+| now() | sysdate() |+---------------------+---------------------+| 2019-09-17 16:13:28 | 2019-09-17 16:13:28 |+---------------------+---------------------+1 row in set (0.00 sec)
unix_dmestamp:获取UNIX时间戳
UNIX_TIMESTAMP(date) 若⽆参数调⽤,返回⼀个⽆符号整数类型的 UNIX 时间 戳('1970-01-01 00:00:00’GMT之后的秒数)mysql> selectunix_timestamp(),unix_timestamp(now()),now(),unix_timestamp('2019-09-17 12:00:00');+------------------+-----------------------+---------------------+---------------------------------------+| unix_timestamp() | unix_timestamp(now()) | now() |unix_timestamp('2019-09-17 12:00:00') |+------------------+-----------------------+---------------------+---------------------------------------+| 1568710893 | 1568710893 | 2019-09-17 17:01:33 |1568692800 |+------------------+-----------------------+---------------------+---------------------------------------+1 row in set (0.00 sec)
month:获取指定⽇期的⽉份
MONTH(date) 函数返回指定 date 对应的⽉份,范围为 1~12。mysql> select month('2017-12-15'),month(now());+---------------------+--------------+| month('2017-12-15') | month(now()) |+---------------------+--------------+| 12 | 9 |+---------------------+--------------+1 row in set (0.00 sec)
monthname:获取指定⽇期⽉份的英⽂名称
MONTHNAME(date) 函数返回⽇期 date 对应⽉份的英⽂全名。mysql> select monthname('2017-12-15'),monthname(now());+-------------------------+------------------+| monthname('2017-12-15') | monthname(now()) |+-------------------------+------------------+| December | September |+-------------------------+------------------+1 row in set (0.00 sec)
dayname:获取指定⽇期的星期名称
DAYNAME(date) 函数返回 date 对应的⼯作⽇英⽂名称,例如 Sunday、Monday 等。mysql> select now(),dayname(now());+---------------------+----------------+| now() | dayname(now()) |+---------------------+----------------+| 2019-09-17 17:13:08 | Tuesday |+---------------------+----------------+1 row in set (0.00 sec)
dayofweek:获取⽇期对应的周索引
DAYOFWEEK(d) 函数返回 d 对应的⼀周中的索引(位置)。1 表⽰周⽇,2 表⽰ 周⼀,……,7 表⽰周六。这些索引值对应于ODBC标准。mysql> select now(),dayofweek(now());+---------------------+------------------+| now() | dayofweek(now()) |+---------------------+------------------+| 2019-09-17 17:14:21 | 3 |+---------------------+------------------+1 row in set (0.00 sec)
year:获取年份
YEAR() 函数可以从指定⽇期值中来获取年份值mysql> select now(),year(now()),year('2019-01-02');+---------------------+-------------+--------------------+| now() | year(now()) | year('2019-01-02') |+---------------------+-------------+--------------------+| 2019-09-17 17:28:10 | 2019 | 2019 |+---------------------+-------------+--------------------+1 row in set (0.00 sec)
timetosec:将时间转换为秒值
TIMETOSEC(time) 函数返回将参数 time 转换为秒数的时间值,转换公式为“⼩时 ×3600+ 分钟 ×60+ 秒”。mysql> select time_to_sec('15:15:15'),now(),time_to_sec(now());+-------------------------+---------------------+--------------------+| time_to_sec('15:15:15') | now() | time_to_sec(now()) |+-------------------------+---------------------+--------------------+| 54915 | 2019-09-17 17:30:44 | 63044 |+-------------------------+---------------------+--------------------+1 row in set (0.00 sec)
查看隔离级别
mysql> show variables like 'transaction_isolation';+-----------------------+----------------+| Variable_name | Value |+-----------------------+----------------+| transaction_isolation | READ-COMMITTED |+-----------------------+----------------+1 row in set, 1 warning (0.00 sec)
清空test1表数据:
delete from test1;select * from test1;
删除存储过程
DROP PROCEDURE IF EXISTS proc8;
创建索引
我们在id上⾯创建⼀个索引,感受⼀下:mysql> create index idx1 on test1 (id);Query OK, 0 rows affected (2.82 sec)Records: 0 Duplicates: 0 Warnings: 0mysql> select * from test1 a where a.id = 1;+----+-----------+-----+-------------------+| id | name | sex | email |+----+-----------+-----+-------------------+| 1 | javacode1 | 1 | javacode1@163.com |+----+-----------+-----+-------------------+1 row in set (0.00 sec)上面的查询是不是非常快,耗时1毫秒都不到。我们在name上也创建个索引,感受⼀下查询的神速,如下:mysql> create unique index idx2 on test1(name);Query OK, 0 rows affected (9.67 sec)Records: 0 Duplicates: 0 Warnings: 0mysql> select * from test1 where name = 'javacode1';+----+-----------+-----+-------------------+| id | name | sex | email |+----+-----------+-----+-------------------+| 1 | javacode1 | 1 | javacode1@163.com |+----+-----------+-----+-------------------+1 row in set (0.00 sec)查询快如闪电,有没有,索引是如此的神奇。
查看表中的索引
mysql> show index from test1;+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+| Table | Non_unique | Key_name | Seq_in_index | Column_name |Collation | Cardinality | Sub_part | Packed | Null | Index_type |Comment | Index_comment |+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+| test1 | 0 | idx2 | 1 | name | A| 1992727 | NULL | NULL | | BTREE | ||| test1 | 1 | idx1 | 1 | id | A| 1992727 | NULL | NULL | | BTREE | ||| test1 | 1 | idx3 | 1 | email | A| 1992727 | 15 | NULL | YES | BTREE | ||+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+3 rows in set (0.00 sec)
删除索引
我们删除idx1,然后再列出test1表所有索引,如下mysql> drop index idx1 on test1;Query OK, 0 rows affected (0.01 sec)Records: 0 Duplicates: 0 Warnings: 0mysql> show index from test1;
创建用户
create user 'chuan'@'%' identified by '123456';
用户授权
grant all privileges on *.* to 'chuan'@'%'
更改密码加密的方法
alter user 'chuan'@'%' identified with mysql_native_password by '123456';
刷新权限
flush privileges;
尴尬的提示
有时候,当你执行了上面的操作, 还是提示上述异常时,不要慌,有可能是你输错了用户名或者密码,不代表上面没有生效。1、模拟概要:看有没有锁等待,哪个事务在等待,谁锁的我,锁源thread_id,锁源SQL
2、3其他两个方法
一、故障模拟(具体解决办法)
2、获取正在等待语句,kill 锁源语句,锁源ID,锁源线程ID
2、获取正在等待的语句,kill 锁源语句,锁源ID
MySQL语句中
SELECT COUNT(*) FROM information_schema.TABLES WHERE table_name ='查询的表名';
存储过程中
DECLARE tableExists INT DEFAULT 0;SELECT COUNT(*) INTO tableExists FROM INFORMATION_SCHEMA.TABLES WHERE table_name = '查询的表名';IF tableExists > 0 THEN -- 表存在ELSE -- 表不存在END IF;
查询
-- 语法SELECT * from student WHERE <条件> or <条件> ...;-- 例如,查询姓名为张三的或者姓名为小刘的数据SELECT * from student WHERE name="张三" or name="小刘"; 条件> 条件>
执行结果
-- 语法SELECT * from student WHERE <条件> ;-- 例如,查询姓名不是张三的其他人,排除张三SELECT * from student WHERE name!="张三"; 条件>
执行结果
SELECT * from student WHERE age=19 or age=20 or age=21;
执行结果
- 语法SELECT * from student WHERE <列名> in (值1,值2,...) ...;-- 例如,需求同上SELECT * from student WHERE age in (19,20,21); 列名>
执行结果
-- 查询年龄不在19,20,21范围的数据SELECT * from student WHERE age not in (19,20,21);
执行结果
between适合进行范围查询!
-- 语法select * from 表 where <列> between <开始范围> and <结束范围> ;-- 例如,查询年龄时20-22岁的学生SELECT * from student WHERE age BETWEEN 20 and 22; 结束范围> 开始范围> 列>
执行结果
select * from <表名> where <时间列> between <开始时间> and <结束时间>结束时间> 开始时间> 时间列> 表名>
模糊查询(like)
假设现在数据如下,有三个姓张的。所以就要用到like模糊查询。
-- 语法 %表示匹配一个或多个字符select * from 表 where <列> like '[%] <字符串> [%]'-- 例如,查询,以张开头的SELECT * from student WHERE name like "张%"; 字符串> 列>
执行结果
... WHERE name like "张%丰";匹配:张三丰WHERE name like "%鱼";匹配:张甲鱼WHERE name like "李%";匹配:李四...
限制(limit)
-- 前两行SELECT * from student LIMIT 2;
-- 从第2行开始后,再取4行SELECT * from student LIMIT 2,4;-- 同上,写法不同SELECT * from student LIMIT 4 OFFSET 2
不知道你有没有发现,我们之前查找的顺序都是正向的。
所以,应该是倒序的是最好的。
-- 语法select * from <表名> order by <列> asc -- 从小到大排序select * from <表名> order by <列> desc -- 从大到小排序select * from <表名> order by <列1> desc, <列2> asc -- 先根据 列1 排序,如果数据相同,按照 列2 排序 列2> 列1> 表名> 列> 表名> 列> 表名>
根据id正向排序
SELECT * from student ORDER BY id ASC;
执行结果
SELECT * from student ORDER BY id desc;
执行结果
SELECT <列> ,COUNT( <列> ) from student GROUP BY <列> ;-- 因为分组了某个列,所以就不能再展示其他列的信息了,因为压在一块了,显示不了-- 但是可以通过count,sum等函数计算压缩的个数,或者总值 列> 列> 列>
例如
统计男女各多少人
SELECT gender,COUNT(gender) from student GROUP BY gender;
执行结果
SELECT age,COUNT(age) as "数量" from student GROUP BY age;
执行结果
参考链接 :
MySQL判断表是否存在 :https://www.jianshu.com/p/9a947acb4b87
MySQL查看线程内存占用情况 : https://www.jianshu.com/p/a81de8ddbe1b
(21)mysql锁监控及处理 : https://www.jianshu.com/p/b3b8fe4b620b
查看mysql库大小,表大小,索引大小 :https://www.cnblogs.com/lukcyjane/p/3849354.html
MySQL表空间及索引的查看 :https://www.cnblogs.com/jiaxiaoai/archive/2011/07/18/2109298.html
mysql用户管理、常用sql语句、mysql数据库备份恢复 : https://www.cnblogs.com/lms0755/p/9205642.html
http://www.oschina.net/question/12_3673
http://blog.sina.com.cn/s/blog_4c197d420101fbl9.htmlmysql 账户权限查询 : https://mp.weixin.qq.com/s/LO22Lhxm4KmepXGSqywo-A
mysql查看数据库操作记录 :https://www.jianshu.com/p/58a091f61d90
mysql慢查询 :https://www.jianshu.com/p/6c77aa446cdd
MYSQL 入门全套 : https://mp.weixin.qq.com/s/NdXgXeygrrujzOYsl7AnSQ
运维管理,写一手好SQL很有必要 :
作者:编码砖家 链接:https://www.cnblogs.com/xiaoyangjia/p/11267191.html究竟是哪个会话造成了"Waiting for table metadata lock"现象 : https://mp.weixin.qq.com/s/cA9jIbsE21DxYRBakF97qQ
Mysql查询语句进阶知识集锦 : https://mp.weixin.qq.com/s/nh8mkPg7zOq-it0MRXKMuA