工作中MySQL數據庫涉及5.6.*/5.7.*/8.0.*版本,本文就日常使用羅列筆記(基於Linux系統、MySQL8)。
1. MySQL服務啓動與關閉
MySQL啓動腳本和支持的服務器選項組如下:
- mysqld,也稱爲MySQL Server,是在MySQL安裝中完成大部分工作的主程序,MySQL服務器管理包含數據庫和表的MySQL數據目錄的訪問,數據目錄也是其他信息(例如日誌文件和狀態文件)的默認位置;MySQL服務器啓動時,它將監聽來自客戶端程序的網絡連接,管理它們對數據庫的訪問。
MySQL Server包含一組系統變量,這些變量會影響其運行,可以在服務器啓動時設置系統變量,並且可以在運行時更改許多系統變量以實現動態服務器重新配置,具體參數參考如下命令:
[root@chengyu ~]# mysqld --verbose --help
有關MySQL Server命令選項,系統變量和狀態變量的完整說明參詳:https://dev.mysql.com/doc/refman/8.0/en/mysqld-server.html
- Unix環境下啓動 mysqld服務器推薦使用 mysqld_safe, 因爲它具備一些安全功能,例如將重啓服務器發生的錯誤信息以及運行時的信息記錄到錯誤日誌中;mysqld_safe的許多參數與mysqld的相同,mysqld_safe參數如下:
例如(其中–defaults-file是指定配置文件,&表示後臺啓動):
[root@chengyu ~]# /usr/local/mysql8/bin/mysqld_safe --defaults-file=/etc/my.cnf --port=3307 &
MySQL讀取配置文件的優先級:/etc/my.cnf → basedir/my.cnf→ datadir/my.cnf → --defaults-extra-file → ~/.my.cnf.
- Unix和類似Unix的系統上的MySQL發行版包括一個名爲mysql.server的腳本,該腳本使用mysqld_safe啓動MySQL服務器,它可以在使用System V樣式運行目錄來啓動和停止系統服務的系統(例如Linux和Solaris)上使用;mysql.server是MySQL源代碼樹中使用的腳本名稱,安裝的名稱可能不同(例如,mysqld或 mysql),一般在MySQL安裝目錄下的support-files中,可以將mysql.server腳本複製到/etc/init.d下並設置爲可執行自啓動,mysql.server參數可以添加至my.cnf中,如下:
示例:
[mysqld]
basedir =/usr/local/mysql8
datadir =/home/mysql8/data
port = 3307
pid-file = /usr/local/mysql8/mysqld.pid
socket = /usr/local/mysql8/mysql.sock
[mysql.server]
basedir=/usr/local/mysql8
datadir =/home/mysql8/data
pid-file = /usr/local/mysql8/mysqld.pid
service-startup-timeout = 900
systemd提供自動的MySQL服務器啓動和關閉,它還使用systemctl命令啓用手動服務器管理 ,例如:
systemctl {start|stop|restart|status} mysqld
或者,使用與System V系統兼容的service命令(具有相反的參數):
service mysqld {start|stop|restart|status}
2. MySQL數據庫與用戶創建
2.1 MySQL對象命名要求
MySQL中的某些對象,包括數據庫,表,索引,列,別名,視圖,存儲過程,分區,表空間,資源組和其他對象名,稱爲標識符。
- 每種標識符的最大長度:
- 限定符:用以明確解釋數據庫對象。
注意:默認情況下,表別名在Unix上區分大小寫,但在Windows或macOS上不區分大小寫,分區,子分區,列,索引,存儲的例程,事件和資源組名稱在任何平臺上都不區分大小寫,列別名也不區分大小寫;但是,日誌文件組的名稱區分大小寫,這與標準SQL不同,所以爲實現最大的可移植性和易用性,命名最好採用一致的約定,例如始終使用小寫名稱創建和引用數據庫和表。
對於MySQL的關鍵字和保留字,加引號用作標識符,例外:限定名稱中句點後的單詞必須是標識符,因此即使保留該單詞也無需加引號,不過最好避開使用關鍵字保留字。
- 未加引號的標識符中允許的字符:[0-9,az,AZ $ _],標識符可以以數字開頭,但除非加引號,否則不能僅由數字組成,數據庫,表和列的名稱不能以空格字符結尾。
2.2 創建數據庫
MySQL 8.0不支持通過在 數據目錄下手動創建目錄(例如,使用mkdir)來創建數據庫目錄 。
CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
[create_option] ...
create_option: {
[DEFAULT] CHARACTER SET [=] charset_name
| [DEFAULT] COLLATE [=] collation_name
| [DEFAULT] ENCRYPTION [=] {'Y' | 'N'}
}
# ENCRYPTION選項在MySQL 8.0.16中引入,定義了默認的數據庫加密,該默認加密由數據庫中創建的表繼承。允許的值爲'Y'(啓用加密)和 'N'(禁用加密)。
示例:
mysql> CREATE DATABASE IF NOT EXISTS dbcy DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
Query OK, 1 row affected (0.13 sec)
2.3 創建用戶
- 帳戶首次創建時沒有權限,默認角色爲NONE。要分配特權或角色,請使用以下GRANT語句;
- 帳戶名的主機名部分(如果省略)默認爲’%’;
- 對於每個帳戶,CREATE USER 在mysql.user系統表中創建一個新行。
語法如下:
CREATE USER [IF NOT EXISTS]
user [auth_option] [, user [auth_option]] ...
DEFAULT ROLE role [, role ] ...
[REQUIRE {NONE | tls_option [[AND] tls_option] ...}]
[WITH resource_option [resource_option] ...]
[password_option | lock_option] ...
[COMMENT 'comment_string' | ATTRIBUTE 'json_object']
示例1:創建一個使用默認身份驗證插件和給定密碼的帳戶。將密碼標記爲過期,以便用戶在與服務器的第一次連接時必須選擇一個新密碼:
mysql> CREATE USER 'cy'@'localhost' IDENTIFIED BY '123456' PASSWORD EXPIRE;
示例2:創建一個使用caching_sha2_password身份驗證插件和給定密碼的帳戶,要求每180天選擇一個新密碼,並啓用登錄失敗跟蹤,以使三個連續的錯誤密碼會導致兩天的臨時帳戶鎖定:
mysql> CREATE USER 'cy'@'localhost' IDENTIFIED WITH caching_sha2_password BY '123456'
PASSWORD EXPIRE INTERVAL 180 DAY
FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 2;
示例3:創建多個帳戶,並指定一些每個帳戶屬性和一些全局屬性:必須使用有效的X.509證書進行連接、每小時最多允許60個查詢、密碼更改不能重複使用五個最新密碼中的任何一個、該帳戶最初是被鎖定的,因此實際上是一個佔位符,只有在管理員將其解鎖後才能使用。
mysql> CREATE USER 'cy'@'localhost' IDENTIFIED WITH mysql_native_password BY 'cy123456', 'nn'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'nn123456'
REQUIRE X509 WITH MAX_QUERIES_PER_HOUR 60
PASSWORD HISTORY 5
ACCOUNT LOCK;
從MySQL 8.0.21開始,可以選擇創建具有用戶註釋或用戶屬性的用戶:
mysql> CREATE USER 'cy'@'localhost' COMMENT 'Some information about cy';
mysql> CREATE USER 'cy'@'localhost' ATTRIBUTE '{"name": "ChengYu", "city": "DongGuan", "phone": "123-456-7890"}';
2.4 創建表
語法如下:
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
(create_definition,...)
[table_options]
[partition_options]
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
[(create_definition,...)]
[table_options]
[partition_options]
[IGNORE | REPLACE]
[AS] query_expression
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
{ LIKE old_tbl_name | (LIKE old_tbl_name) }
示例1創建普通表:
mysql> CREATE TABLE `tb_wx_user` (
`userid` int(11) NOT NULL AUTO_INCREMENT,
`cellPhone` varchar(20) DEFAULT NULL COMMENT '手機號',
`nickname` varchar(100) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '暱稱',
`sex` int(1) DEFAULT '0' COMMENT '性別(1.男,2.女,0.未知)',
`addr` varchar(100) DEFAULT NULL COMMENT '城市',
`createDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`userid`),
UNIQUE KEY `uq_cellPhone` (`cellPhone`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用戶信息表'
示例2創建分區表:
# hash分區
mysql> CREATE TABLE tb_hash (col1 INT, col2 CHAR(5))
PARTITION BY HASH(col1);
# key分區
mysql> CREATE TABLE tb_key (col1 INT, col2 CHAR(5), col3 DATE)
PARTITION BY KEY(col3)
PARTITIONS 4;
# range分區
mysql> CREATE TABLE tb_range (
year_col INT,
some_data INT
)
PARTITION BY RANGE (year_col) (
PARTITION p3 VALUES LESS THAN (2002),
PARTITION p4 VALUES LESS THAN (2006),
PARTITION p5 VALUES LESS THAN MAXVALUE
);
# list分區
mysql> CREATE TABLE client_firms (
id INT,
name VARCHAR(35)
)
PARTITION BY LIST (id) (
PARTITION r2 VALUES IN (3, 7, 11, 15, 19, 23),
PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24)
);
2.5 創建函數
語法如下:
delimiter常應用在存儲過程、函數中定義結束符,默認情況下,delimiter 爲“;” ,而存儲過程中每個SQL語句的結尾都有個 “;”,如果每逢 “;” 就向 MySQL 提交的話會出問題,於是更改 MySQL 的delimiter。
mysql> CREATE
[DEFINER = user]
FUNCTION sp_name ([func_parameter[,...]])
RETURNS type
[characteristic ...] routine_body
示例,通過筆記編號tid獲取筆記內容詳情logmark:
DROP FUNCTION IF EXISTS get_cylog;
CREATE FUNCTION get_cylog(cid INT) RETURNS VARCHAR(200)
BEGIN
DECLARE cylog_detail VARCHAR(200);
SELECT logmark FROM tb_cylog WHERE tid=cid INTO cylog_detail;
RETURN cylog_detail;
END
# 使用這個函數
mysql> select get_cylog(1)\G
*************************** 1. row ***************************
get_cylog(1): 過去與未來有別,原因先於結果。先有傷口,後有疼痛,而非反之。杯子碎成千片,而這些碎片不會重新組成杯子。我們無法改變過去,我們會有遺憾、懊悔、回憶。而未來是不確定、慾望、擔憂、開放的空間,也許是命運。我們可以向未來而活,塑造它,因爲它還不存在。一切都還有可能……時間不是一條雙向的線,而是有着不同兩端的箭頭。
1 row in set (0.00 sec)
# 查看函數狀態
mysql> show function status like 'get_cylog'\G
*************************** 1. row ***************************
Db: dbcy
Name: get_cylog
Type: FUNCTION
Definer: cy@192.183.3.147
Modified: 2020-06-15 09:40:42
Created: 2020-06-15 09:40:42
Security_type: DEFINER
Comment:
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: utf8mb4_general_ci
1 row in set (0.00 sec)
# 也可以查看函數創建語句
mysql> show create function get_cylog;
*************************** 1. row ***************************
Function: get_cylog
sql_mode: STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
Create Function: CREATE DEFINER=`cy`@`192.183.3.147` FUNCTION `get_cylog`(cid INT) RETURNS varchar(200) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
BEGIN
DECLARE cylog_detail VARCHAR(200);
SELECT logmark FROM tb_cylog WHERE tid=cid INTO cylog_detail;
RETURN cylog_detail;
END
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: utf8mb4_general_ci
1 row in set (0.00 sec)
# 刪除函數
mysql> drop function get_cylog;
2.6 創建事件
語法如下:
CREATE
[DEFINER = user]
EVENT
[IF NOT EXISTS]
event_name
ON SCHEDULE schedule
[ON COMPLETION [NOT] PRESERVE]
[ENABLE | DISABLE | DISABLE ON SLAVE]
[COMMENT 'string']
DO event_body;
示例,定期更新tb_cylog的days字段:
mysql> delimiter //
mysql> CREATE DEFINER = `cy`@`192.183.147` EVENT `e_cylog_up`
-> ON SCHEDULE EVERY 1 DAY STARTS '2020-02-08 00:00:00' ON COMPLETION PRESERVE ENABLE DO
-> UPDATE tb_cylog SET days = days + 1;//
Query OK, 0 rows affected, 1 warning (0.09 sec)
mysql> delimiter ;
# 查看event是否開啓
mysql> SHOW VARIABLES LIKE '%event_sche%';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| event_scheduler | ON |
+-----------------+-------+
1 row in set (0.01 sec)
# 將事件計劃開啓
mysql> SET GLOBAL event_scheduler = 1;
# 將事件計劃關閉
mysql> SET GLOBAL event_scheduler = 0;
# 關閉事件任務
mysql> ALTER EVENT e_cylog_up ON COMPLETION PRESERVE DISABLE;
# 開啓事件任務
mysql> ALTER EVENT e_cylog_up ON COMPLETION PRESERVE ENABLE;
# 查看事件任務
mysql> SHOW EVENTS;
# 刪除事件
mysql> drop event e_cylog_up;
2.7 創建視圖
相關語法如下:
# 創建視圖
CREATE
[OR REPLACE]
[ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
[DEFINER = user]
[SQL SECURITY { DEFINER | INVOKER }]
VIEW view_name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
# 修改視圖
ALTER
[ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
[DEFINER = user]
[SQL SECURITY { DEFINER | INVOKER }]
VIEW view_name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
# 刪除視圖
DROP VIEW [IF EXISTS]
view_name [, view_name] ...
[RESTRICT | CASCADE]
# 查看視圖創建語句
SHOW CREATE VIEW view_name;
# 查看視圖狀態
SHOW TABLE STATUS LIKE 'view_name':
示例:
mysql> CREATE VIEW v_cylog AS SELECT tname,logmark FROM tb_cylog where tname='ChengYu';
Query OK, 0 rows affected (0.11 sec)
mysql> select * from v_cylog\G
*************************** 1. row ***************************
tname: ChengYu
logmark: 過去與未來有別。原因先於結果。先有傷口,後有疼痛,而非反之。杯子碎成千片,而這些碎片不會重新組成杯子。我們無法改變過去,我們會有遺憾、懊悔、回憶。而未來是不確定、慾望、擔憂、開放的空間,也許是命運。我們可以向未來而活,塑造它,因爲它還不存在。一切都還有可能……時間不是一條雙向的線,而是有着不同兩端的箭頭
*************************** 2. row ***************************
tname: ChengYu
logmark: 時間的缺失並不意味着一切都停滯不變。它只能說明,讓世界感到疲倦的不間斷的事件並不是按時間順序排列的,無法被一個巨大的鐘表測量.
2 rows in set (0.00 sec)
2.8 創建索引
語法如下:
CREATE [UNIQUE | FULLTEXT | SPATIAL] INDEX index_name
[index_type]
ON tbl_name (key_part,...)
[index_option]
[algorithm_option | lock_option] ...
示例:
mysql> CREATE UNIQUE INDEX ind_tid ON tb_cylog(tid);
mysql> CREATE FULLTEXT INDEX ind_logmark ON tb_cylog((logmark));
mysql> CREATE INDEX ind_log ON tb_cylog((tid, tname));
2.9 創建觸發器
語法如下:
CREATE
[DEFINER = user]
TRIGGER trigger_name
trigger_time trigger_event
ON tbl_name FOR EACH ROW
[trigger_order]
trigger_body
示例,當tb_cylog有insert操作時更新tb_notice表:
mysql> DELIMITER //
mysql> CREATE TRIGGER tri_cylog_insert
-> AFTER INSERT
-> ON tb_cylog FOR EACH ROW
-> BEGIN
-> insert into tb_notice(contents,createtime) values('成嶼更新啦',NOW());
-> END//
Query OK, 0 rows affected (0.10 sec)
mysql> DELIMITER ;
# 測試
mysql> insert into tb_cylog values(3,'ChengYu','生有時,死有時;哀慟有時,跳舞有時;殺戮有時,醫治有時;摧毀有時,建造有時.', now(),5300);
Query OK, 1 row affected (0.06 sec)
mysql> select * from tb_notice\G
*************************** 1. row ***************************
nid: 1
contents: 成嶼更新啦
createtime: 2020-06-15 15:20:16
1 row in set (0.00 sec)
2.10 創建存儲過程
語法如下:
CREATE
[DEFINER = user]
PROCEDURE sp_name ([proc_parameter[,...]])
[characteristic ...] routine_body
示例,通過筆記編號tid獲取筆記內容詳情logmark:
mysql> delimiter //
mysql> CREATE PROCEDURE pro_cylog (IN cid INT, OUT cylog_detail VARCHAR(200))
-> BEGIN
-> SELECT logmark into cylog_detail FROM tb_cylog WHERE tid=cid;
-> END
-> //
Query OK, 0 rows affected (0.08 sec)
mysql> delimiter ;
# 調用存儲過程
mysql> call pro_cylog(2,@cylog_detail)\G
Query OK, 1 row affected (0.00 sec)
mysql> select @cylog_detail\G
*************************** 1. row ***************************
@cylog_detail: 時間的缺失並不意味着一切都停滯不變。它只能說明,讓世界感到疲倦的不間斷的事件並不是按時間順序排列的,無法被一個巨大的鐘表測量.
1 row in set (0.00 sec)
# 查詢存儲過程
mysql> show create procedure pro_cylog\G
*************************** 1. row ***************************
Procedure: pro_cylog
sql_mode: STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
Create Procedure: CREATE DEFINER=`root`@`localhost` PROCEDURE `pro_cylog`(IN cid INT, OUT cylog_detail VARCHAR(200))
BEGIN
SELECT logmark into cylog_detail FROM tb_cylog WHERE tid=cid;
END
character_set_client: utf8mb4
collation_connection: utf8mb4_general_ci
Database Collation: utf8mb4_general_ci
1 row in set (0.00 sec)
# 查看存儲過程狀態
mysql> show procedure status like '%cylog%'\G
*************************** 1. row ***************************
Db: dbcy
Name: pro_cylog
Type: PROCEDURE
Definer: cy@192.183.3.147
Modified: 2020-06-15 10:24:44
Created: 2020-06-15 10:24:44
Security_type: DEFINER
Comment:
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: utf8mb4_general_ci
1 row in set (0.00 sec)
#刪除存儲過程
mysql> drop procedure pro_cylog;
Query OK, 0 rows affected (0.13 sec)