MySQL語句和命令大全


前言

這里記錄的是這兩年學習工作過程中遇到的常用的 MySQL 語句和命令,部分是網上收集來的,出處已經不記得了,這里先謝過這些大佬。本文包括常見 SQL 語句,還有部分運維語句和命令,沒有做詳細的說明,更多是給出一個例子。就這點語句當然還不能說是全,但是后續也會陸續增加完善。記錄得有些亂,有需要的可以酌情提取。

一、用戶連接、創建、權限、刪除

1. 連接MySQL操作

mysql -h 主機地址 -u 用戶名 -P端口號 -p

使用 SSL 連接

mysql --ssl-ca=ca.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem -h主機地址 -u用戶名 -p

2. 創建用戶

CREATE USER 'username'@'host' IDENTIFIED BY 'password';

  • host 指定該用戶在哪個主機上可以登陸,如果是本地用戶可用localhost, 如果想讓該用戶可以從任意遠程主機登陸,可以使用通配符%.

3. 授權

GRANT [all privileges/某個權限] ON databasename.tablename TO 'username'@'host';

如果想讓該用戶可以授權,用以下命令:

GRANT all privileges ON databasename.tablename TO 'username'@'host' WITH GRANT OPTION;

4. 鎖定用戶

ALTER USER 'username'@'host' ACCOUNT LOCK;

解鎖

ALTER USER 'username'@'host' ACCOUNT UNLOCK;

常見場景:

1 創建讀寫權限的用戶

GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, EXECUTE, CREATE VIEW, SHOW VIEW ON databasename.tablename TO 'username'@'host';

2 創建只讀權限用戶

GRANT SELECT,SHOW VIEW ON databasename.tablename TO 'username'@'host';

4. 設置與更改用戶密碼

方法一

SET PASSWORD FOR 'username'@'host' = PASSWORD('newpassword');

如果是當前登陸用戶用

SET PASSWORD = PASSWORD("newpassword");

方法二

ALTER USER 'root'@'localhost' IDENTIFIED BY 'password';

5. 撤銷用戶權限

REVOKE [ALL/某個權限] ON databasename.tablename FROM 'username'@'host';

某個用戶權限可以用命令SHOW GRANTS FOR 'username'@'host'; 查看.

5. 重命名用戶

rename user 'old_name'@'host' to 'new_name'@'host';

7. 刪除用戶

DROP USER 'username'@'host';

8. 要求使用ssl登陸

# 修改已存在用戶 ALTER USER 'username'@'%' REQUIRE SSL; # 創建用戶 create user username_ssl@'%' identified by 'password' require ssl;

刷新權限表

flush privileges;

二、數據庫與表顯示、創建、刪除

1. 數據庫查看&創建&刪除

-- 查看數據庫 show databases; -- 創建庫 create database [IF NOT EXISTS] <庫名> [character set='utf8']; -- 刪除庫 drop database <庫名>; 

2. 表查看、創建、刪除

-- 顯示數據表 use <庫名>; show tables; -- 創建表: create table 表名 (字段設定列表) [engine=InnoDB] [charset=utf8mb4]; -- 查看創建表的 DDL 語句 show create table <表名>; -- 顯示表結構 desc <表名>; -- 刪除表 drop table [IF EXISTS] <表名>; -- 臨時表 CREATE TEMPORARY TABLE <表名>(<字段定義>);

e.g.

CREATE TABLE USER ( id INT NOT NULL AUTO_INCREMENT, stu_id INT NOT NULL, name VARCHAR(30) NOT NULL, phone VARCHAR(20), address VARCHAR(30) NOT NULL, age INT NOT NULL, PRIMARY KEY (id), UNIQUE KEY `un_stu_id` (stu_id), KEY `idx_name` (`name`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

注意: 為 text 等建立索引時要指定長度 e.g. KEY idx_text (f_text(64))

三、表復制、備份還原及清除

1. 復制表結構

含有主鍵等信息的完整表結構:

CREATE table 新表名 LIKE book;

只有表結構,沒有主鍵等信息:

create table 新表名 select * from books; 或 create table 新表名 as(select * from book); 或 create table 新表名 select * from books where1=2;

注: create table <t> select ... 會造成索引丟失

2. 將舊表中的數據灌入新表

INSERT INTO <新表> SELECT * FROM <舊表>;

3. 顯示創建表的DDL語句

show create table <表名>;

4. 清空表數據

truncate table <表名>;

5. 備份數據庫

備份單個庫

shell> mysqldump --single-transaction --master-data=2 --default-character-set=utf8 -u root -p <database_name> >database_name.sql

備份一個表

shell> mysqldump --single-transaction --master-data=2 --default-character-set=utf8 -u root -p <database_name> <table_name> > table_name.sql

備份多個庫

shell> mysqldump --single-transaction --master-data=2 --default-character-set=utf8 -u username -p --databases <dbname1> <dbname2> > Backup.sql

備份所有庫

shell> mysqldump --single-transaction --master-data=2 --default-character-set=utf8 -A -u root -p > back.sql

忽略某些庫表

--ignore-table=performance_schema.* --ignore-table=information_schema.* --ignore-table=sys.* --ignore-table=test.*

帶上壓縮

shell> mysqldump -A | gzip >> backup.sql.gz

6. 還原數據庫

shell> mysql -u root -p -f [database_name] < backup.sql

7. 從備份文件抽取數據

提取某個庫的所有數據

shell> sed -n '/^-- Current Database: `test_restore`/,/^-- Current Database:/p' mysql_back.sql

只提取建表語句

shell> sed -e'/./{H;$!d;}' -e 'x;/CREATE TABLE `test1`/!d;q' mysql_back.sql

只提取數據

shell> grep -i 'INSERT INTO `test1`' mysql_back.sql

提取所有建庫表語句

shell> grep -iv 'INSERT INTO `' mysql_back.sql

8. 導出數據

<select語句> into outfile "dest_file";

9. 導入數據

load data infile "<file_name>" into table <table_name>;

四、修改表的列與表名

1. 給列更名

alter table <表名稱> change <舊字段名稱> <新字段名稱>

2. 給表更名

alter table <舊表名稱> rename <新表名稱>

3. 修改某個表的字段類型及指定為空或非空

alter table <表名稱> change <字段名稱> <字段名稱> <字段類型> [not null];

alter table <表名稱> modify <字段名稱> <字段類型> [not null];

4. 增加一個字段(一列)

alter table 表名稱 add column 字段名稱 字段類型;

加在某個字段后面

alter table 表名稱 add column 字段名稱 字段類型 after 某個字段;

加在最前

alter table 表名稱 add column 字段名稱 字段類型 first;

5. 更改一個字段名字(也可以改變類型和默認值)

alter table <表名稱> change <原字段名稱> <新字段名稱 字段類型>;

6. 改變一個字段的默認值

alter table 表名稱 alter 字段名稱 set default 值;

該方法不會鎖表

7. 改變一個字段的數據類型

alter table <表名稱> change column <字段名稱> <字段名稱> <字段類型>;

8. 刪除字段

alter table <表名稱> drop column <列名>;

五 查詢表

SELECT [DISTINCT] <字段名稱,用逗號隔開/*> FROM <left_table> [<join_type> JOIN <right_table> ON <連接條件>] WHERE <where條件> GROUP BY <分組字段> HAVING <篩選條件> ORDER BY <排序條件> [desc/asc] LIMIT n[, m]

1. GROUP BY 與聚合函數 使用注意點

1 在不使用聚合函數的時候,group by 子句中必須包含所有的列,否則會報錯

正確: select name,age from test group by name,age; //和 select 一樣

2 在 group by 子句中不要加上聚合函數處的列名

2. having

SQL 標准
要求 having 必須引用 group 子句中的列或者用聚合函數處理過
后的列。

mysql 對這一標准進行了一些擴展,它允許 having 引
用 select 中檢索的列和外部查詢中的列。

having 中用到的條件要
么在 group by 中出現,要么在 select 的列中出現,要么在外查
詢中出現。

3. from

from 子查詢時要給數據表指定一個別名。from (select ..) [as] 別名 where...

4. union

select 語句 union [all] select 語句

union 會去重

5. join 外連接查詢

select * from tableA A [left、right] join tableB B on A.id = B.id

6. join 交叉連接

select * from tableA,tableB

select * from tableA cross join tableB

逗號與 cross join 區別是逗號不能使用 on

結果會有 n * n 條記錄(笛卡爾乘積)

7. join 內連接

select * from tableA A inner join tableB B on A.id = B.id

select * from tableA A inner join tableB B using(id)

using(字段) 可以合並相同字段,並且符合 A.id = B.id

內連接在沒有條件時和交叉連接沒有區別。

STRAIGHT_JOIN 可以手動指定驅動表

六 索引的創建、刪除和查看

1. 創建索引

方法一

-- 普通索引 ALTER TABLE 表名稱 ADD INDEX index_name (column_list) -- 唯一索引 ALTER TABLE 表名稱 ADD UNIQUE (column_list) -- 主鍵索引 ALTER TABLE 表名稱 ADD PRIMARY KEY (column_list)

方法二

CREATE INDEX index_name ON 表名稱 (column_list) CREATE UNIQUE INDEX index_name ON 表名稱 (column_list)

column_list 指出對哪些列進行索引,多列時各列之間用逗號分隔。
索引名index_name可選,缺省時,MySQL將根據第一個索引列賦一個名稱。
另外,ALTER TABLE允許在單個語句中更改多個表,因此可以在同時創建多個索引。

2. 刪除索引

-- 刪除索引 DROP INDEX index_name ON 表名稱; ALTER TABLE 表名稱 DROP INDEX index_name; -- 刪除主鍵 ALTER TABLE 表名稱 DROP PRIMARY KEY;

3. 查看索引

show index from 表名稱; show keys from 表名稱;

4. 手動選擇索引

  • USE INDEX : 向優化器提示如何選擇索引
  • IGNORE INDEX : 忽略索引
  • FORCE INDEX : 強制使用索引
select * from tableA USE INDEX (key1, key2) where key1=and key2=2

七 外鍵

1. 增加外鍵

建表時

constraint 外鍵名 foreign key(外鍵字段) references 關聯表名(關聯字段);

修改表

alter table 表名 add constraint 外鍵名 foreign key(外鍵字段名) references 外表表名(對應的表的主鍵字段名);

2. 刪除外鍵

ALTER TABLE table-name DROP FOREIGN KEY key-id;

八 流程控制&函數

1 內置函數&方法

1.1 if

IF(expr1,expr2,expr3)

如果 expr1 是TRUE (expr1 <> 0 and expr1 <> NULL),則 IF()的返回值為expr2; 否則返回值則為 expr3。

1.2 CASE when

SELECT CASE 1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 'more' END as testCol

1.3 IFNULL

IFNULL(expr1,expr2)

假如expr1 不為 NULL,則 IFNULL() 的返回值為 expr1; 否則其返回值為 expr2。

2 自定義存儲過程&函數

2.1 查看

查詢數據庫中的存儲過程和函數

- 存儲過程
show procedure status; select `name` from mysql.proc where db = '<dbname>' and `type` = 'PROCEDURE'; -- 函數 show function status; select `name` from mysql.proc where db = '<dbname>' and `type` = 'FUNCTION'

查看存儲過程或函數的創建代碼

show create procedure <proc_name>; show create function <func_name>;

九 視圖

1. 創建

create or replace view <視圖名>(<列名 1>,<列名 2>...) as <select 語句>;

2. 刪除

drop view <視圖 1> [,視圖 2....視圖 n];

十 觸發器

trigger_time: { BEFORE | AFTER } -- 事件之前還是之后觸發 trigger_event: { INSERT | UPDATE | DELETE } -- 三個類型 trigger_order: { FOLLOWS | PRECEDES } other_trigger_name

假設定義一個觸發器,每次插入把 ctime 設為當前時間

delimiter // -- 更改結束符 create trigger <觸發器名字> before insert on <表名> for each row begin set new.ctime=now(); end;// delimiter ;

假設定義一個觸發器,每次更新把 mtime 設為當前時間

delimiter // -- 更改結束符 create trigger <觸發器名字> before update on <表名> for each row begin set new.mtime=now(); end;// delimiter ;

十一 查看狀態

# 查看狀態 status; show status; # innodb 狀態 show innodb status; # 查看參數 show variables like '%參數名稱%'; # 查看隔離級別 select @@tx_isolation; +-----------------+ | @@tx_isolation | +-----------------+ | REPEATABLE-READ | +-----------------+

十二 導出導入

1. 導出到文件

select * into outfile 文件地址 [控制格式] form tableA;

導出到 csv,並壓縮

shell> mysql -B -u賬號 -p -e "SELECT語句" | sed "s/'/\'/;s/\t/\",\"/g;s/^/\"/;s/$/\"/;s/\n//g" | gzip > data.csv.gz

控制格式同導入文件

2. 導入文件

load data infile 文件名 [replace|ignore] into table 表名 [控制格式]
  • replace 和 ignore: 表示對主鍵重復的數據處理方式
  • 控制格式 fields terminated by '\t' enclosed by '' escaped by '\\'

e.g.

SELECT * INTO OUTFILE '/tmp/data.txt' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' FROM tableA;

十三 統計語句

1. 計算最大可能使用內存

MySQL >= 8

select
(@@key_buffer_size + @@query_cache_size + @@tmp_table_size + @@innodb_buffer_pool_size + @@innodb_additional_mem_pool_size + @@innodb_log_buffer_size + @@max_connections * ( @@read_buffer_size + @@read_rnd_buffer_size + @@sort_buffer_size+ @@join_buffer_size + @@binlog_cache_size + @@thread_stack ) )/1024/1024/1024 as max_mem_G;

MySQL < 8

select
(@@key_buffer_size + @@query_cache_size + @@tmp_table_size + @@innodb_buffer_pool_size + @@innodb_log_buffer_size + @@max_connections * ( @@read_buffer_size + @@read_rnd_buffer_size + @@sort_buffer_size+ @@join_buffer_size + @@binlog_cache_size + @@thread_stack ) )/1024/1024/1024 as max_mem_G;

2. 數據大小

數據總大小

SELECT ROUND(SUM(DATA_LENGTH)/1024/1024/1024,2) as data_size_G,ROUND(SUM(INDEX_LENGTH)/1024/1024/1024,2) as index_G, ROUND(SUM(DATA_LENGTH+INDEX_LENGTH)/1024/1024/1024,2) as total_size_G,SUM(TABLE_ROWS) as rows FROM information_schema.TABLES;

某個庫大小

SELECT ROUND(SUM(DATA_LENGTH)/1024/1024/1024,2) as data_size_G,ROUND(SUM(INDEX_LENGTH)/1024/1024/1024,2) as index_G, ROUND(SUM(DATA_LENGTH+INDEX_LENGTH)/1024/1024/1024,2) as total_size_G,SUM(TABLE_ROWS) as rows FROM information_schema.TABLES WHERE TABLE_SCHEMA='庫名';

統計所有庫按大小排序

SELECT TABLE_SCHEMA, ROUND(SUM(DATA_LENGTH)/1024/1024/1024,2) as data_size_G,ROUND(SUM(INDEX_LENGTH)/1024/1024/1024,2) as index_G, ROUND(SUM(DATA_LENGTH+INDEX_LENGTH)/1024/1024/1024,2) as total_size_G,SUM(TABLE_ROWS) as rows FROM information_schema.TABLES group by TABLE_SCHEMA order by data_size_G desc;

3. 統計連接IP

select SUBSTRING_INDEX(host,':',1) as ip , count(*) from information_schema.processlist group by ip;

4. 查看鎖

mysql5.6

SELECT r.trx_id waiting_trx_id, r.trx_mysql_thread_id waiting_thread, r.trx_query waiting_query, b.trx_id blocking_trx_id, b.trx_mysql_thread_id blocking_thread, b.trx_query blocking_query FROM information_schema.innodb_lock_waits w INNER JOIN information_schema.innodb_trx b ON b.trx_id = w.blocking_trx_id INNER JOIN information_schema.innodb_trx r ON r.trx_id = w.requesting_trx_id; waiting_trx_id -- 請求的事物ID waiting_thread -- 請求的線程ID waiting_query -- 等待的SQL語句 blocking_trx_id -- 阻塞上面請求的事物的ID blocking_thread -- 阻塞的線程ID blocking_query -- 阻塞的當前的SQL,這個是無法看到的,除非SQL還沒有執行完成(不一定是該事物當中的最后一條SQL語句)

mysql5.7

select * from sys.innodb_lock_waits;

5. 查看沒有主鍵的表

SELECT table_schema, table_name FROM information_schema.TABLES WHERE table_name NOT IN ( SELECT DISTINCT TABLE_NAME FROM information_schema.COLUMNS WHERE COLUMN_KEY = 'PRI') AND table_schema NOT IN ('mysql' , 'information_schema','sys', 'performance_schema');

6. 索引合理性

SELECT t.TABLE_SCHEMA,t.TABLE_NAME,INDEX_NAME, CARDINALITY, TABLE_ROWS, CARDINALITY/TABLE_ROWS AS SELECTIVITY FROM information_schema.TABLES t, ( SELECT table_schema, table_name, index_name, cardinality FROM information_schema.STATISTICS WHERE (table_schema,table_name,index_name,seq_in_index) IN ( SELECT table_schema, table_name, index_name, MAX(seq_in_index) FROM information_schema.STATISTICS GROUP BY table_schema , table_name , index_name ) ) s WHERE t.table_schema = s.table_schema AND t.table_name = s.table_name AND t.table_schema = '數據庫名' -- 指定某一個庫名 ORDER BY SELECTIVITY;
  • SELECTIVITY越接近1,越合理
  • 因為聚合索引會在 statistics 表中產生多條數據,所以 MAX(seq_in_index) 可以拿到完整索引那條

7. 統計processlist各個狀態數量

shell> mysql -uroot -p<password> -e 'show processlist \G' | grep 'State:' | sort | uniq -c | sort -rn

十四 運維語句&命令

1. 更新統計信息

analyze table <table_name>;

2. 重新整理表

optimize table <table_name>;

3. 檢查表(MyISAM)

check table <table_name>;

4. 修復表(MyISAM)

repair table <table_name>;

5. 批量檢查或修復表

# 檢查所有表 shell> mysqlcheck -u root -p<password> -A -c  # 修復所有表 shell> mysqlcheck -u root -p<password> -A -c 

6. 統計每秒慢日志

shell> awk '/^# Time:/{print $3, $4, c;c=0}/^# User/{c++}' slowquery.log

7. 查看binlog日志

基於position

mysqlbinlog --no-defaults -v -v --base64-output=DECODE-ROWS --start-position=<start_pos> --stop-position=<stop_pos> <mysql binlog文件> > result.sql

基於時間點

mysqlbinlog --no-defaults -v -v --base64-output=DECODE-ROWS --start-datetime='<開始時間>' --stop-datetime='<結束時間>' <mysql binlog文件> > result.sql

查看某個pos的日志

mysqlbinlog --no-defaults -v -v --base64-output=DECODE-ROWS <mysql binlog文件> | grep -A '20' <pos>

8. 打開句柄數

統計各進程打開句柄數:

lsof -n|awk '{print $2}'|sort|uniq -c|sort -nr | head -n 10 # 某個進程 lsof -n|awk '$2=="<某個進程的PID>" {print $2}'|sort|uniq -c|sort -nr | head -n 10

統計各用戶打開句柄數

lsof -n|awk '{print $3}'|sort|uniq -c|sort -nr # mysql用戶 lsof -n|awk '$3 == "mysql" {print $3}'|sort|uniq -c|sort -nr

統計各命令打開句柄數

lsof -n|awk '{print $1}'|sort|uniq -c|sort -nr

9. 導出用戶權限(shell腳本)

#/bin/bash user='username' pass='password' sock='socket' expgrants() { mysql -B -u"${user}" -p"${pass}" -S"${sock}" -N $@ -e "SELECT CONCAT( 'SHOW CREATE USER ''', user, '''@''', host, ''';' ) AS query FROM mysql.user" | \ mysql -u"${user}" -p"${pass}" -S"${sock}" -f $@ | \ sed 's#$#;#g;s/^\(CREATE USER for .*\)/-- \1 /;/--/{x;p;x;}' mysql -B -u"${user}" -p"${pass}" -S"${sock}" -N $@ -e "SELECT CONCAT( 'SHOW GRANTS FOR ''', user, '''@''', host, ''';' ) AS query FROM mysql.user" | \ mysql -u"${user}" -p"${pass}" -S"${sock}" -f $@ | \ sed 's/\(GRANT .*\)/\1;/;s/^\(Grants for .*\)/-- \1 /;/--/{x;p;x;}' } 

然后執行腳本

10. 批量殺連接

方法一

select concat('KILL ',id,';') from information_schema.processlist where user='某個用戶' into outfile '/tmp/kill.txt'; source /tmp/kill.txt;

方法二

mysqladmin -uroot -p processlist|awk -F "|" '{if($3 == "要殺的連接的用戶")print $2}'|xargs -n 1 mysqladmin -uroot -p kill


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM