MySql 入門.md

MySql 入門

數據庫(database)就是存儲數據的倉庫。爲了方便數據的存儲和管理,將數據按照特定的規律在磁盤上,經過數據庫管理系統,有效地組織和管理存儲在數據庫中的數據。
數據庫系統和數據庫不是一個概念,數據庫系統(DBS),比數據庫大不少,由數據庫、數據庫管理系統,應用開發工具構成。
數據庫管理系統(DataBase Management System,簡稱 DBMS),是用來定義數據,管理和維護數據的軟件。它是數據庫系統的一種重要組成部分。
常見的數據庫系統:甲骨文Oracle數據庫,IBM的DB2,微軟SQL Server、Access,PostgreSql、MySQL。html

MySql 數據庫

MySQL數據庫特色:開放源代碼的數據庫,MySQL的跨平臺性(Unix、Linux、Windows等),開源免費,功能強大使用方便。
SQL:(Structured Query Language),結構化查詢語句,數據庫管理系統經過 SQL 語言來管理數據庫中的數據。
SQL 語言組成部分:mysql

  • DDL(Data Defination Language),數據定義語言,主要用於定義數據庫、表、數據、索引和觸發器等,像 DROP、CREATE、ALTER 等語句。
  • DML(Data Manipulation Language),主要包括對數據的增刪改。INSERT 插入數據、UPDATA 更新數據、DELETE 刪除數據。
  • DQL(Data Query Language),數據檢索語句,用來從表中得到數據,肯定數據怎樣在應用程序中給出,像 SELECT 查詢數據。
  • DCL(Data Control Language),數據控制語言,主要用於控制用戶的訪問權限,像 GRANT、REVOKE、COMMIT、ROLLBACK 等語句。

安裝與配置

官網下載 有兩個版本,一個是二進制分發版(.msi 安裝文件),一個是 免安裝版(.zip 壓縮文件)。二進制分發版和安裝普通軟件同樣的,在選擇須要安裝的文件時,若是隻是學習 MySql,能夠只選擇安裝 MySQL Server。默認安裝路徑是:C:\Program Files\MySQL\MySQL Server 5.6。8.x 版本的壓縮包版本沒有 .ini 文件,和 5.x 版本的不同,配置方式也不同,如下內容以 5.x 版本爲例。正則表達式

目錄 備註    
bin目錄 存儲可執行文件    
data 目錄 存儲數據文件    
include 目錄 存儲包含的頭文件    
lib 目錄 存儲庫文件    
docs 目錄 文檔    
share 目錄 錯誤信息和字符集文字    
my.ini文件 MySQL的配置文件,默認的是 my-default.ini,須要複製並重命名爲 my.ini 設置字符集 客戶端字符集[mysql]:default-character-set=utf8
      服務器端字符集[masqld]:character-set-server=utf8

運行 MySql 的步驟:算法

  1. 配置環境變量,在 Path 中添加一條數據,即 MySql 的 bin 目錄,C:\Program Files\MySQL\MySQL Server 5.6\bin
  2. 開啓 MySql 服務,安裝的時候默認會添加一個名爲MySQL56的服務,開啓服務有兩個方式,一是打開系統的服務,手動開啓;二是在控制檯輸入:net start mysql56,關閉服務是:net stop mysql56
  3. 配置編碼字符集,避免顯示亂碼。須要在 my.ini 中添加兩行:客戶端[mysql] default-character-set=utf8 ,服務器端[mysqld] character-set-server=utf8
  4. 鏈接 MySql,須要在控制檯輸入:mysql -u root -p

登陸與退出

登陸命名:mysql [參數][參數值],好比 mysql -uroot -psql

經常使用參數 備註
-u 用戶名
-p 密碼
-h 服務器名稱,-h localhost ,-h 127.0.0.1
-P 端口號,默認安裝端口號 3306
-D,--database=name 打開指定數據庫
--prompt=name 設置命令提示符,--prompt=>>> ,登陸以後也能夠設置,prompt \h~\u~\D~\d,服務器名稱當前用戶名完整的日期~當前數據庫
--delimiter=name 指定分隔符,登陸以後也能夠修改,DELIMITER //,輸入語句後以//結束,默認分隔符;\g
-V,--version 輸出版本信息而且退出

退出命名:exit | quit | \qshell

擴展語句:數據庫

  • SELECT VERSION(); select v()\g 查看當前數據庫版本號,\g等同於;
  • SELECT USER(); 查看當前用戶
  • SELECT NOW(); 查看當前時間
  • SELECT VERSION()\c 不會執行這個命令
  • \T C:\Develop\mysql1.txt 輸出日誌文件到 mysql1.txt ,結束日誌\t
  • SHOW WARNINGS; 查看語句的警告
  • SELECT {DATABASE() | SCHEMA()} :獲得當前打開的數據庫名稱
  • help [要查詢的內容],好比 help CREATE DATABASE

數據庫操做(DDL)

MySql 語句規範:編程

  • 關鍵字與函數名稱所有大寫
  • 數據庫名稱、表名稱、字段名稱等所有小寫
  • SQL語句必須以分隔號結尾(或\g)
  • SQL語句支持折行操做,只要不把單詞、標記或引號字符串分割爲兩部分,能夠在下一行繼續寫
  • 數據庫名稱、表名稱、字段名稱等儘可能不要使用MySQL的保留字,若是須要使用的時候須要用反引號(``)將名稱括起來

1.建立數據庫,數據庫保存在 data 文件夾中緩存

CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name [[DEFAULT] CHARACTER SET [=] charset_name]

數據庫名稱:DATABASE 或 SCHEMA;
{ }表明必需要出現的,[ ]表明能夠選的;
db_name表示數據庫名稱;
CHARACTER SET [=] charset_name 表示編碼方式,如 utf8安全

2.查看當前服務器下的數據庫列表:SHOW {DATABASES | SCHEMAS}

3.查看制定數據庫的定義:SHOW CREATE {DATABASE | SCHEMA} db_name

4.修改制定數據庫的編碼方式:ALTER {DATABASE | SCHEMA} db_name [DEFAULT] CHARACTER SET [=] character_name

5.打開指定數據庫:USE db_name

6.刪除指定數據庫:DROP {DATABASE | SCHEMA} [IF EXISTS] db_name

數據表相關操做

數據表

  • 是數據庫最重要的組成部分之一,是其餘對象的基礎
  • 是存儲數據的數據結構
  • 是包含了特定實體類型的數據
  • 由行(row)和列(column)構成的二維網絡
  • 必定先有表結構,再有數據
  • 至少有一列,能夠沒有行或者多列
  • 數據表名稱要求惟一,並且不要包含特殊字符

建立數據表

CREATE TABLE [IF NOT EXISTS] tbl_name(
字段名稱 字段類型 [完整性約束條件]
...
)ENGINE=引擎名稱 CHARSET='編碼方式';

CREATE TABLE [IF NOT EXISTS] tbl_name(
字段名稱 字段類型 [UNSIGNED | ZEROFILL] [NOT NULL] [DEFAULT 默認值] [[PRIMARY] KEY] [UNIQUE [KEY]]
)ENGINE=INNODB CHARSET=UTF8 AUTO_INCREMENT=數值;

CREATE TABLE IF NOT EXISTS `user`(
id SMALLINT,
username VARCHAR(20),
age TINYINT,
sex ENUM('男','女','保密'),
email VARCHAR(50),
addr VARCHAR(20),
birth YEAR,
salary FLOAT(8,2),
tel INT,
# COMMENT 是給字段添加註釋
married TINYINT(1) COMMENT '0表明未結婚,非0表明結婚'
)ENGINE=INNODB CHARSET=UTF8;

註釋:# 註釋內容 或者 -- 註釋內容

完整性約束條件

  • PRIMARY KEY 主鍵
  • AUTO_INCREMENT 自增
  • FOREIGN KEY 外鍵
  • NOT NULL 非空
  • UNIQUE KEY 惟一
  • DEFAULT 默認值
  • ZEROFILL 零填充
  • UNSIGNED 無符號

字段類型:查看數據類型help [數據類型]\h [數據類型]

  • 整數類型:

    • TINYINT :長度 1 字節,有符號值 -128 到 127(-2^7 到 2^7 - 1),無符號 0 - 255(2^8 - 1)
    • SMALLINT :2 字節
    • MEDIUMINT : 3 字節
    • INT :4 字節
    • BIGINT :8 字節
    • BOOL,BOOLEAN :1 字節,等價於 TINYINT(1) ,0 爲 false,其他爲 true
  • 浮點類型:

    • FLOAT[(M, D)] :4 字節,負數取值範圍爲 -3.40E+38 到 -1.17E-3八、0 和 1.175E-38 到 3.40E+38,M 是數字總位數,D 是小數點後面的位數。若是 M 和 D 被省略,根據硬件容許的限制類保存值。單精度浮點數精度大約 7 位小數位。
    • DOUBLE[(M, D)] :8 字節
    • DECIMAL[(M, D)] : M+2 字節,和 DOUBLE 同樣,內部以字符串形式存儲數值
  • 字符串類型:

    • CHAR(M) :M 個字節,0<=M<=255,CHAR 在保存的時候,前面會用空格填充到指定的長度,在檢索的時候後面的空格會去掉
    • VARCHAR(M) : L+1 個字節,其中 L<=M 且 0<=M<=65535,L 爲長度,VARCHAR在保存的時候,不進行填充。當值保存和檢索時尾部的空格仍保留
    • TINYTEXT :L+1 字節,其中 L<2^8
    • TEXT : L+2 字節,其中 L<2^16,只能保存字符數據,並且不能有默認值
    • MEDIUMTEXT :L+3 字節
    • LONGTEXT :L+4 字節
    • ENUM('value1', 'value2', ...) :1 或 2 個字節,取決於枚舉值的個數(最多 65535 個值)
    • SET('value1', 'value2', ...) :一、二、三、4 或 8 個字節,取決於 set 成員的數目(最多 64 個成員)
  • 日期時間類型:

    • TIME :3 字節
    • DATE :3 字節,1000-01-01 ~ 9999-12-31
    • DATETIME :8 字節,1000-01-01 00:00:00
    • TIMESTAMP :4字節,1970-01-01 00:00:01 UTC ~ 2038-01-19 03:14:07,通常用整型保存時間戳
    • YEAR : 1 字節,1901 - 2155
    • 標準時間轉爲時間戳: $dateline=strtotime($nowtime);
    • 時間戳轉爲標準時間:$nowtime=date('H:i:s',$dateline);

存儲引擎
存儲引擎就是指表的類型。數據庫的存儲類型決定了表在計算機中的存儲方式。用戶能夠根據不一樣的存儲方式,是否進行事務處理等來選擇合適的存儲引擎。

查看數據庫的存儲引擎:

  • 查看支持的存儲引擎:SHOW ENGINES; 或者 SHOW ENGINES\G
  • 查看顯示支持的存儲引擎信息:SHOW VARIABLES LIKE 'have%'
  • 查看默認的存儲引擎:SHOW VARIABLES LIKE 'storage_engine'

經常使用存儲引擎及特色:

  • InnoDB :事務,回滾,多版本併發控制,支持外鍵約束,表結構存儲在 .frm 文件內
  • MyISAM :保存到三個文件中,.frm .MYD .MYI,
  • MEMORY :存儲到內存中,hash 索引

查看數據表

1.查看數據庫下的數據表:SHOW TABLES
2.查看指定表的表結構:DESC tbl_name, DESCRIBE tbl_name, SHOW COLUMNS FROM tbl_name
3.查看建立表的定義:SHOW CREATE TABLE tbl_name;

修改數據表

1.修改表名:ALTER TABLE tbl_name RENAME [TO | AS] new_name 或者 RENAME TABLE tbl_name TO new_name

2.添加字段:ALTER TABLE tbl_name ADD 字段名稱 字段類型 [完整性約束條件] [FIRST | AFTER 字段名稱]

3.刪除字段:ALTER TABLE tbl_name DROP 字段名稱,或者 ALTER TABLE tbl_name DROP 字段1,DROP 字段2,...;

4.修改字段:ALTER TABLE tbl_name MODIFY 字段名稱 [完整性約束條件] [FIRST | AFTER 字段名稱] ,主鍵有自增加不能直接刪除主鍵,須要先去掉自增加,修改字段能夠去掉自增加

5.修改字段名稱:ALTER TABLE tbl_name CHANGE 舊字段名稱 新字段名稱 字段類型 [完整性約束條件] [FIRST | AFTER 字段名稱]

6.添加刪除默認值:ALTER TABLE tbl_name ALTER 字段名稱 SET DEFAULT 默認值 , ALTER TABLE tbl_name ALTER 字段名稱 DROP DEFAULT

7.添加主鍵:ALTER TABLE tbl_name ADD [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (字段名稱, ...)

8.刪除主鍵:ALTER TABLE tbl_name DROP PRIMARY KEY;

9.添加惟一:ALTER TABLE tbl_name ADD [CONSTRAINT [symbol]] UNIQUE [INDEX | KEY] [索引名稱](字段名稱, ...) ,索引名稱不能帶有單引號,可使用反引號。

10.刪除惟一:ALTER TABLE tbl_name DROP {INDEX | KEY} index_name

11.修改表的存儲引擎:ALTER TABLE tbl_name ENGINE=存儲引擎名稱

12.設置自增加的值:ALTER TABLE tbl_name AUTO_INCREMENT=值

13.刪除數據表:DROP TABLE [IF EXISTS] tbl_name[, tbl_name...]

數據的操做(DML)

1.插入數據:

  • 不指定具體的字段名:INSERT [INTO] tbl_name VALUES|VALUE(值,...)
  • 列出指定字段:INSERT [INTO] tbl_name(字段名稱1, ...) VALUES|VALUE(值1,...)
  • 同時插入多條記錄:INSERT [INTO] tbl_name[(字段名稱 ...)] VALUES(值 ...), (值 ...)...
  • 經過 SET 形式插入記錄:INSERT [INTO] tnl_name SET 字段名稱=值,...
  • 將查詢結果插入到表中:INSERT [INTO] tbl_name[(字段名稱, ...)] SELECT 字段名稱 FROM tbl_name [WHERE 條件]

2.更新數據:UPDATE tbl_name SET 字段名稱=值,... [WHERE 條件] [ORDER BY 字段名稱] [LIMIT 限制條數]

  • LIMIT 限制條數只能有一個數,不能由兩個數包含偏移量

3.刪除數據:

  • DELETE FROM tbl_name [WHERE 條件] [ORDER BY 字段名稱] [LIMIT 條數],沒有條件會刪除全部記錄,可是DELETE刪除不會重置AUTO_INCREMENT的值
    • LIMIT 條數只能有一個數,不能包含偏移量
  • 完全清空數據表: TRUNCATE [TABLE] tbl_name;

查詢數據操做(DQL)

普通查詢

1.查詢記錄:

SELECT select_expr[,select_expr...] 
[
  FROM table_references
  [WHERE 條件]
  [GROUP BY {col_name | position} [ASC | DESC],...分組]
  [HAVING 條件 對分組結果進行二次篩選]
  [ORDER BY {col_name | position} [ASC | DESC],...排序]
  [LIMIT 限制顯示條數]
]

2.查詢表達式:

  • 每一個表達式表示想要的一列,必須至少有一列,多個列之間以逗號分隔
  • * 表示全部列,tbl_name.* 表示命名錶的全部列,tb_name.tbl_name.* 表示哪一個數據庫中的哪一個表裏的全部列
  • 查詢表達式可使用 [AS]alias_name 爲表賦予別名

3.WHERE 條件:

查詢條件 符號
比較 = 、< 、<= 、> 、>= 、!= 、<> 、!> 、!< 、<=> (能夠判斷是否是 NULL)
指定範圍 BETWEEN AND 、NOT BETWEEN AND
指定集合 IN 、 NOT IN
匹配字符 LIKE 、 NOT LIKE (模糊查詢,%表明0個一個或者多個任意字符,_表明1個任意字符)
是否爲空值 IS NULL 、 IS NOT NULL
多個查詢條件 AND 、 OR

4.GROUP BY 查詢結果分組

  • SELECT * FROM tbl_name GROUP BY 字段1,字段2... :先按照 字段1 分組,分完組以後再按照 字段2 分組
  • 配合 GROUP_CONCAT() 獲得分組詳情 --- 默認下獲取的分組是不全的,只能看到組裏的一條記錄
    • SELECT id,sex,GROUP_CONCAT(username) FROM cms_user GROUP BY sex;
  • 配合聚合函數:
    • COUNT() ,COUNT(字段) 不統計 NULL 值,COUNT(*)就能統計技術
    • MAX()
    • AVG()
    • SUM()
  • 配合 WITH ROLLUP 記錄上面全部記錄的總和,會在查詢到的數據中增長一行數據
    • SELECT * FROM tbl_name GROUP BY 字段名稱 WITH ROLLUP

5.HAVING 子句
經過 HAVING 子句對分組結果進行二次篩選,和 WHERE 差很少,只能用於分組以後進行篩選。SELECT * FROM tbl_name GROUP BY 字段名稱 HAVING 條件1 [[AND | OR...] 條件2]
若是沒有 GROUP BY 進行分組,結果可能和 WHERE 同樣的。

6.ORDER BY 排序
ORDER BY 對查詢結果進行排序,默認排序是 ASC 升序排序,DESC 是降序排列。SELECT * FROM tbl_name ORDER BY 字段名稱 [ASC|DESC]
SELECT * FROM tbl_name ORDER BY RAND(); 隨機數排序

7.LIMIT 限制查詢結果顯示條數
對查詢結果,限制顯示條數,SELECT * FROM tbl_name LIMIT 條數
SELECT * FROM tbl_name LIMIT 起始條數偏移量(以0開始), 每頁顯示條數

鏈接查詢

鏈接查詢是將兩個或兩個以上的表按某個條件鏈接起來,從中選取須要的數據。鏈接查詢是同時查詢兩個或兩個以上的表時使用的,當不一樣的表中存在相贊成義的字段時,能夠經過該字段鏈接這幾個表。

SELECT cms_user.id,username,proName FROM cms_user,provinces
WHERE cms_user.proId=provinces.id;

 SELECT u.id,u.username,u.email,u.sex,p.proName
 FROM cms_user AS u
 INNER JOIN provinces AS p
 ON u.proId=p.id;
 
SELECT u.id,u.username,u.regTime,a.proName,u.sex,COUNT(*) AS totalUsers,GROUP_CONCAT(username)
FROM cms_user AS u
LEFT JOIN
provinces AS a
ON u.proId=a.id
WHERE sex='女'
GROUP BY a.proName
HAVING COUNT(*)>=1
ORDER BY u.id DESC
LIMIT 0,2;

1.內鏈接查詢:

  • JOIN|CROSS JOIN 、INNER JOIN
  • 經過 ON 鏈接條件
  • 顯示兩個表中符合鏈接條件的記錄

2.外鏈接查詢

  • 左外鏈接: LEFT [OUTER] JOIN ,顯示左表的所有記錄及右表符合鏈接條件的記錄
  • 右外鏈接: RIGHT [OUTER] JOIN ,顯示右表的所有記錄以及左表符合條件的記錄

3.外鍵
外鍵是表的一個特殊字段。被參照的表是主表,外鍵所在字段的表爲子表。設置外鍵的原則:就是依賴於數據庫中已存在的表的主鍵。外鍵的做用是創建該表與其父表的關聯關係。父表中對記錄作操做時,子表中與之對應的信息也應有相應的改變。

外鍵的做用保持數據的一致性和完整性;能夠實現一對一或一對多的關係。

注意:

  • 父表和子表必須使用相同的存儲引擎,並且禁止使用臨時表;
  • 數據表的存儲引擎只能爲InnoDB;
  • 外鍵列和參照列必須具備類似的數據類型。其中數字的長度或是否有符號位必需相同;而字符的長度則能夠不一樣;
  • 外鍵列和參照列必須建立索引。若是外鍵列不存在索引的話,MYSQL將自動建立索引。

外鍵約束的參照操做:

  • CASCADE : 從父表刪除或更新且自動刪除或更新子表中匹配的行;
    • CONSTRAINT 父表_fk_子表 FOREIGN KEY(鏈接子表字段名稱) REFERENCES 父表名(鏈接父表字段名稱) ON DELETE CASCADE ON UPDATE CASCADE;
  • SET NULL : 從父表刪除或更新行,並設置子表中的外鍵列爲NULL,若是使用該選項,必須保證子表列沒有指定NOT NULL。
    • CONSTRAINT 父表_fk_子表 FOREIGN KEY(鏈接子表字段名稱) REFERENCES 父表名(鏈接父表字段名稱) ON DELETE SET NULL ON UPDATE SET NULL;
  • RESTRICT : 拒絕對父表的刪除或更新操做。
  • NO ACTION : 標準SQL的關鍵字,在MySQL中與RESTRICT相同。

在鏈接查詢中,若是一個字段在父表和子表中有關聯,則不能直接用DELETE FROM tbl_name [ WHERE 條件 ]去刪除父表中的字段(由於子表還會存在該字段),因此爲了完全刪除,此時須要給子表建立一個外鍵,當須要刪除一個字段時,必需先刪除子表中的字段才能刪除父表中的字段。

CREATE TABLE IF NOT EXISTS department(
id TINYINT AUTO_INCREMENT KEY,
dep VARCHAR(20) NOT NULL UNIQUE
)ENGINE=INNODB;

CREATE TABLE IF NOT EXISTS employee(
id SMALLINT AUTO_INCREMENT KEY,
username VARCHAR(20) NOT NULL,
depId TINYINT,
CONSTRAINT em_fk_dep FOREIGN KEY(depId) REFERENCES department(id)
)ENGINE=INNODB;

4.聯合查詢:查詢的數目要一致

  • UNION :SELECT username FROM tbl_name1 UNION SELECT username FROM tbl_name2;
  • UNION ALL :SELECT username FROM tbl_name1 UNION ALL SELECT username FROM tbl_name2;
  • 區別: UNION 去掉相同記錄,UNION ALL 是簡單的合併

子查詢

子查詢是將一個查詢語句嵌套在另外一個查詢語句中。內層查詢語句的查詢結果,能夠爲外層查詢語句提供條件。由內向外執行

引起子查詢的狀況:

  • 使用 [NOT] IN 的字查詢
  • 使用比較運算符的子查詢:=、>、<、>=、<=、<>、!=、<=>
  • 使用 [NOT] EXISTS 的子查詢,SELCT * FROM tbl_name WHERE EXISTS(SELECT ...) 條件是真纔會有結果
  • 使用 ANY | SOME 或者 ALL 的子查詢
運算符 ANY SOME ALL
>、>= 最小值 最小值 最大值
<、<= 最大值 最大值 最小值
= 任意值 任意值  
<>、!=     任意值

將查詢結果寫入到數據表:

-- 向已經存在的表中插入數據
INSERT [INTO] tbl_name [(col_name,...)] SELECT ...

INSERT employee(username) 
SELECT username FROM department

-- 在存儲過程當中向變量插入數據
SELECT value1 INTO var_anem FROM tbl_name

建立數據表同時將查詢結果寫入到數據表:

CREATE TABLE [IF NOT EXISTS] tbl_name[(create_definition,...)] select_statement

CREATE TABLE test(
id TINYINT UNSIGNED AUTO_INCREMENT KEY,
num TINYINT UNSIGNED
)SELECT id,score FROM student;

正則表達式查詢

1.REGEXP '匹配模式'

SELECT * FROM cms_user WHERE username REGEXP '^A';
SELECT * FROM cms_user WHERE username REGEXP '[^ABC]';

2.經常使用匹配方式

模式字符 含義
^ 匹配字符開始的部分
$ 匹配字符串結尾部分
. 表明字符串中的任意一個字符,包括回車和換行,至關於 LIKE 語句中的_
[字符集合] 匹配字符集合中的任何一個字符
[^字符集合] 匹配除了字符集合之外的任何一個字符
s1 s2
* 表明0個1個或者多個其前的字符,至關於 LIKE 語句中的 %
+ 表明1個或者多個其前的字符
String{N} 字符串出現 N 次
字符串{M, N} 字符串至少出現 M 次,最多 N 次

運算符和函數

運算符

1.算數運算符:SELECT 3/0;

符號 表達式 做用
+ X1+X2 加法
- X1-X2 減法
* X1*X2 乘法
/ X1/X2 除法
DIV X1 DIV X2 除法
% X1 % X2 取餘
MOD MOD(X1,X2) 取餘

2.比較運算符:結果只能爲真或假,1爲真,0爲假

符號 形式 做用
= X1=X2 判斷是否相等
<>或!= X1<>X2或 X1!=X2 判斷是否不相等
<=> X1<=>X2 判斷是否相等,能夠判斷是否等於NULL
>、>= X1>X2或 X1>=X2 判斷是否大於等於
<、<= X1<X2或 X1<=X2 判斷是否小於等於
IS NULL或IS NOT NULL X1 IS NULL 或 X1 IS NOT NULL 判斷是否等於NULL
BETWEEN AND或NOT BETWEEN AND X1 BETWEEN m AND n 判斷是否在範圍內
IN 或 NOT IN X1 IN(值,...) 判斷是否在某一固定範圍內
LIKE 或 NOT LIKE X1 LIKE 表達式 判斷是否撇配
REGEXP REGEXP 正則表達式 判斷是否正則匹配

3.邏輯運算符

符號 形式 做用
&&或者AND 而且
    或者OR
!或者NOT 取反
XOR 異或 不一樣爲真

4.運算符的優先級:經過括號()改變優先級

優先級 運算符 優先級 運算符
1 ! 8  
2 ~ 9 =、<=>、<、<=、>、>=、!=、<>、IN、IS NULL、LIKE、REGEXP
3 ^ 10 BETWEEN AND、CASE、WHEN、THEN、ELSE
4 *、/、DIV、%、MOD 11 NOT
5 +、- 12 &&、AND
6 >>、<< 13  
7 & 14 ;=

函數

1.數學函數

名稱 描述
CEIL() 進一取整
MOD 取餘數(取模)
ROUND() 四捨五入,SELECT ROUND(3.123,2); 3.12
ABS() 取絕對值
FLOOR() 舍一取整
POWER(X,n) 冪運算
TRUNCATE() 數字截取,SELECT TRUNCATE(43.125,1); 43.1
PI() 圓周率
RAND()和RAND(X) 返回0~1之間的隨機數,RAND(X),X相同時返回的隨機數相同
SIGN(X) 返回X的符號,X爲負數、0、正數,分別返回-1和0和1
EXP(X) 計算e的幾回方

2.字符串函數

名稱 描述
CHAR_LENGTH (S) 返回字符串的字符數
LENGTH 返回字符串的長度
CONCAT (S1,S2,...) 將字符串合併爲一個字符串
CONCAT_WS (X,S1,S2,...) 以指定分隔符鏈接字符串
UPPER (S) /UCASE (S) 將字符串轉換爲大寫
LOWER (S) /LCASE (S) 將字符串轉換爲小寫
LEFT(S,N) /RIGHT(S,N) 返回字符串的前/後n個字符
LPAD (S1,LEN,S2) /RPAD (S1,LEN,S2) 將字符串S1用S2填充到指定的LEN
LTRIM(S)/RTRIM(S)/TRIM(S) 去掉字符串中的空格
TRIM(S1 FROM S) 去掉字符串S中開始出現和結尾處的字符串S1
REPEAT(S,N) 重複字符串指定次數
SPACE(N) 返回N個空格
REPLACE(S,S1,S2) 將字符串S中搜索S1替換成S2 ,會區分大小寫
STRCMP(S1,S2) 比較字符串,>=<分別返回1,0,-1 ,比較不會區分大小寫
SUBSTRING(S,P,LEN) 截取字符串,從第P個位置截取LEN個字符,包括截取字符
REVERSE(S) 反轉字符串
ELT(N,S1,S2) 返回指定位置的字符串,字符串起始點從1開始

3.日期時間函數

名稱 描述
CURDATE(),CURRENT_DATE() 返回當前日期
CURTIME(),CURRENT_TIME() 返回當前時間
NOW() 返回當前日期和時間
MONTH(D) 返回日期中月份的值 *MONTH(NOW())
MONTHNAME(D) 返回日期中月份名稱,January *MONTHNAME(NOW())
DAYNAME(D) 返回日期是幾,Monday *MONTHNAME(NOW())
DAYOFWEEK(D) 返回一週內的第幾天,1表明星期日 *DAYOFWEEK(NOW())
WEEKDAY(D) 返回日期是星期幾,0表明是星期一 *WEEKDAY(NOW())
WEEK(D) 一年中的第多少個星期 *WEEK(NOW())
YEAR(D) 返回年份值
HOUR(T) 返回小時值
MINUTE() 返回分鐘值
SECOND(T) 返回秒數
DATEDIFF(D1,D2) 計算兩個日期之間的相隔的天數

4.條件判斷函數

名稱 描述
IF(EXPR,V1,V2) 若是表達式EXPR成立,返回結果v1;不然v2
IFNULL (V1,V2) *IFNULL間沒有空格 若是v1的不爲空,就顯示v1的值;不然v2
CASE WHEN exp1 CASE表示函數開始,END表示函數結束。
THEN v1[ WHEN exp2 若是exp1成立時,返回v1。若是表達式exp2成立時,返回v2值。
THEN v2 ] [ ELSE vn ] END 依次類推,最後遇到ELSE時,返回vn的值

5.系統函數

名稱 描述
VERSION() 返回數據庫版本號
CONNECTION_ID() 返回服務器的鏈接數
DATABASE(),SCHEMA() 返回當前數據庫名
USER(),SYSTEM_USER() 返回當前用戶
CURRENT_USER(),CURENT_USER 返回當前用戶
CHARSET(STR) 返回字符串STR的字符集
COLLATION(STR) 返回字符串STR的校驗字符集
LAST_INSERT_ID() 返回最近生成的AUTO_INCREMENT值

6.其餘

名稱 描述
MD5(str) 信息摘要算法
PASSWORD(str) 密碼算法
ENCODE(str,pwd,str)  
   
DECODE(crypt_str,pwd_str) 對經過ENCODE加密以後的內容解密
FORMAT(x,n) 將數字x進行格式化,將x保留到小數點後n 位
ASCII(s) 返回字符串s的第一個字符的ASCII碼
BIN(x) 返回x的二進制編碼
HEX(x) 返回x的十六進制編碼
OCT(x) 返回x的八進制編碼
CONV(x,f1,f2) 將x從f1進制數變成f2進制數
INET_ATON(IP) 將IP地址轉換成數字
INET_NTOA(n) 將數字轉換成IP地址
GET_LOCT(name,time) 定義鎖,IS_FREE_LOCK(name)判斷是否使用鎖,0表示存在鎖,1表示不存在鎖
RELEASE_LOCK(name) 解鎖

索引

索引由數據庫中一列或多列組合而成,其做用是提升對錶中數據的查詢速度。優勢是能夠提升檢索數據的速度,缺點是建立和維護索引須要耗費時間,索引能夠提升查詢速度,會減慢寫入速度。

索引分類:

  • 普通索引 :至關於書籤
  • 惟一索引 :UNIQUE KEY、PRIMARY KEY是一種特殊的惟一索引
  • 全文索引 :用FULLTEXT,只能建立在CHAR、VARCHAR、text等字符字段上
  • 單列索引 :在一個字段上建立索引
  • 多列索引 :在多個字段上建立索引
  • 空間索引 :搜索引擎爲MyISAM ,數據類型GEOMETRY

建立索引

1.建立表的時候建立索引

CREATE TABLE tbl_name(
字段名稱 字段類型 [完整性約束條件],
...,
[UNIQUE | FULLTEXT |SPATIAL] INDEX | KEY [索引名稱](字段名稱[(長度)]
[ASC | DESC])
);

2.在已經存在的表上建立索引

CREATE [UNIQUE | FULLTEXT | SPATIAL] INDEX 索引名稱 ON 表名{字段名稱[(長度)] [ASC | DESC] }

ALTER TABLE tbl_name ADD [UNIQUE | FULLTEXT | SPATIAL] INDEX 索引名稱(字段名稱[(長度)] [ASC | DESC]);

刪除索引

刪除索引

DROP INDEX 索引名稱 ON tbl_name;

ALTER TABLE tbl_name DROP INDEX 索引名稱

MySql 編碼設定 和 變量

編碼設定

1.服務器編碼設定:爲解決客戶端鏈接亂碼
net start mysql56開啓mysql服務,mysql -u root -h 127.0.0.1 -p root打開mysql。

導入數據庫:source 數據庫所在路徑.數據庫名加後綴,如 source C:/Develop/mysql/test.sql,\變爲/

查看數據庫建立方式SHOW CREATE TABLE tbl_name,若是編碼方式是CHARSET=latin1,在插入中文和在CMD上查看是能夠看到,但在客戶端鏈接工具中查看是亂碼的。

打開命令窗口,SHOW VARIABLES LIKE 'CHAR%',查看客戶端編碼方式,若是不是utf8方式則進行修改。在my.ini文件中修改客戶端編碼 default-character-set=utf8 ,服務端編碼 character-set-server=utf8 。
若是配置文件中修改了不能生效,則用下面的方法,但只在當前狀態下有效,當重啓數據庫服務後失效

SET character_set_client = utf8;
SET character_set_connection = utf8;
SET character_set_database = utf8;
SET character_set_results = utf8;
SET character_set_server = utf8;

或 SET names 'utf8';

若是已經修改了my.ini,重啓了服務仍是不能生效,能夠查看服務可執行文件的路徑

"C:\Program Files\MySQL\MySQL Server 5.6\bin\mysqld.exe" --defaults-file="C:\ProgramData\MySQL\MySQL Server 5.6\my.ini" MySQL56

這裏顯示my.ini文件不是執行Program Files裏添加的,而是ProgramData裏的。則有兩種方式讓本身添加的數據生效。

1、修改ProgramData裏的my.ini文件
2、修改服務裏的可執行文件的路徑,這個須要在運行裏輸入regedit,打開註冊表,找到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MySQL56,修改ImagePath

2.數據表的編碼設定:已存在的表

  • 更改數據表編碼格式:ALTER TABLE tbl_name CHARACTER SET utf8;
  • 更改數據表裏列的編碼格式:ALTER TABLE tbl_name CHANGE 舊字段名 新字段名 字段類型 CHARACTER SET utf8 NOT NULL,更改先後字段類型要類似
  • 解決多張表的字符編碼問題:
    1. 導出表結構:mysqldump -u root - p --default-character-set=utf8 -d db_name > 存放路徑/文件名.sql
    2. 導出數據表的數據:mysqldump -u root -p --quick --no-create-info --extended-insert --default-character-set=utf8 db_name > 存放路徑/文件名.sql
    3. 刪除原有的數據庫
    4. 以新的編碼格式建立數據庫:
      • 導入結構:mysql -u root -p test < C:/Develop/mysql/test.sql
      • 導入數據,須要在數據中添加 set names 'utf8' ,mysql -u root -p test < C:/Develop/mysql/test_data.sql
備份命令:mysqldump -h [ip地址] -P [端口號] -u [用戶名] -p [數據庫] > [sql腳本文件]

還原命令:mysql -h [ip地址] -P [端口號] -u [用戶名] -p [數據庫] < [sql腳本文件]

注意:導入導出不要使用 powershell ,直接使用 cmd。

變量

1.會話變量

  • 查看會話變量:
    • SHOW SESSION VARIABLES; SHOW SESSION VARIABLES LIKE 'auto%';
    • 查看指定的變量:SELECT @@SESSION.變量名
  • 設置會話變量:SET @@SESSION.變量名=值 或者 SET 變量名=值

2.全局變量

  • 查看全局變量:
    • SHOW global VARIABLES; SHOW GLOBAL VARIABLES;
    • SELECT @@global.變量名;
  • 設置全局變量:SET global 變量名=值 或者 SET @@global.變量名=值

3.區別:會話變量只針對當前用戶有效,全局變量是針對整個mysql數據庫。

存儲過程

經常使用的操做數據庫語言SQL語句在執行的時候須要先編譯,而後執行,而存儲過程(Stored Procedure)是一組爲了完成特定功能的SQL語句集,經編譯後存儲在數據庫中,用戶經過指定的存儲過程的名字並給定參數(若是該存儲過程帶有參數)來調用執行它。

一個存儲過程是一個可編程的函數,它在數據庫中建立並保存。它能夠有SQL語句和一些特殊的控制結構組成。當但願在不一樣的應用程序或平臺上執行相同的函數,或者封裝特定功能時,存儲過程是很是有用的。數據庫中的存儲過程能夠看作是對編程中的面向對象方法的模擬。它容許控制數據的訪問方式。

存儲過程的優勢:加強了SQL語言的功能和靈活性;存儲過程容許標準組件是編程;存儲過程能實現較快的執行速度。

1.建立存儲過程:

  1. 選中一個數據庫
  2. 改變分隔符,不要讓分號;做爲執行結束的標記,DELIMITER 新的分隔符,好比DELIMITER ~
  3. 建立存儲過程:
CREATE PROCEDURE p_name()
BEGIN
語句1;
語句2;
END~

-- 調用存儲過程
CALL p_name~

2.參數和變量

  • 局部變量:DECLARE 變量名 數據類型 DEFAULT 默認值;
  • 三種參數
    • IN :輸入參數,表示該參數的值必須在調用存儲過程以前指定,在存儲過程當中修改的值不能被返回
    • OUT :輸出參數,該值可在存儲過程內部改變,並能夠返回
    • INOUT :輸入輸出參數,該值能夠在調用時指定,並可修改和返回
CREATE PROCEDURE p_vartest1(IN p_var INT)
BEGIN
SELECT p_var;
SET p_var=p_var+1;
SELECT p_var;
END~

-- 建立一個名爲@P的變量,沒有@符號是不能建立成功的
SET @P=3~

-- 調用存儲過程,並傳遞參數
CALL p_vartest1(@P)~

-- 查看調用存儲過程後的@P值,是否有變化
SELECT @P;

3.流程控制

  • 選擇語句(IF ELSEIF ELSE CASE分支):ELSEIF是挨着寫的,在SQL語句中除了IF、CASE,還有IFNULL
IF search_condition THEN statement_list 
[ELSEIF search_condition THEN statement_list] ... 
[ELSE statement_list] 
END IF

CREATE PROCEDURE p_if(in age INT)
BEGIN
IF age>=18 && age<30 THEN 
    SELECT '成年人';
ELSEIF age>=30 && age<60 THEN 
    SELECT '中年人';
ELSE 
    SELECT '老年人';
END IF;
END~

-- case_value即是條件判斷的變量,when_value表示變量的取值
CASE case_value
WHEN when_value THEN statement_list
[WHEN when_value THEN statement_list] ...
[ELSE statement_list]
END CASE;

CREATE PROCEDURE p_case(in salaryId INT)
BEGIN
DECLARE addS INT;
CASE salaryId
WHEN 1001 THEN SET addS = 1500;
WHEN 1002 THEN SET addS = 2000;
WHEN 1003 THEN SET addS = 2500;
ELSE SET addS=1000;
END CASE;
UPDATE salaries SET salary=addS WHERE id=salaryId;
END~
  • 循環語句
    • while 語句: WHILE 條件 DO ... END WHILE;
    • repeat 語句: REPEAT ... UNTIL 條件 END REPEAT;
    • loop 語句: 循環名稱:LOOP ... IF 條件 THEN LEAVE 循環名稱; END IF; END LOOP;
CREATE PROCEDURE p_while()
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE result INT DEFAULT 0;
WHILE i<=100 DO
  SET result=result+i;
  SET i=i+1;
END WHILE;
SELECT result;
END~

CREATE PROCEDURE p_repeat()
BEGIN
DECLARE min_var INT DEFAULT 1;
DECLARE max_var INT DEFAULT 1;
SELECT MIN(id) INTO min_var FROM tbl_name;
SELECT MAX(id) INTO max_var FROM tbl_name;
REPEAT
  IF min_var%2 = 0 THEN
    UPDATE tbl_name SET gender='F' WHERE id=min_var;
  END IF;
  SET min_var = min_var + 1;
  UNTIL min_var > max_var
END REPEAT;
END~

CREATE PROCEDURE p_loop()
BEGIN
DECLARE min_var INT DEFAULT 1;
DECLARE max_var INT DEFAULT 1;
SELECT MIN(id) INTO min_var FROM tbl_name;
SELECT MAX(id) INTO max_var FROM tbl_name;
loop_name:LOOP
  IF min_var%2 = 0 THEN
    UPDATE tbl_name SET gender='F' WHERE id=min_var;
  END IF;
  SET min_var = min_var + 1;
  IF min_var > max_var THEN
  LEAVE loop_name;
  END IF;
END LOOP;
END~

4.定義條件和處理
條件的定義和處理能夠用來定義過程當中遇到問題時相應的處理步驟。
DECLARE CONTINUE HANDLER FOR sqlstate '錯誤代碼值' SET 變量=變量值

CREATE PROCEDURE p_insert()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SET @X=1;
INSERT INTO test11(username) VALUES('aaa');
INSERT INTO test2(username,password) VALUES('abc','aab');
END~

ERROR 1146 (42S02):Table 'test11' doesn't exists -- 錯誤代碼 42S02 是表不存在,添加了CONTINUE就會直接跳過錯誤向下執行 

5.存儲過程管理

  • 查看存儲過程:SHOW PROCEDURE STATUS WHERE db='數據庫名';
  • 查看當前數據庫下的存儲過程的列表:SELECT specific_name FROM mysql.proc;
  • 查看存儲過程的內容:
    • SELECT specific_name,body FROM mysql.proc [WHERE specific_name=存儲過程名字]
    • SHOW CREATE PROCEDURE 存儲過程名字
  • 刪除存儲過程:DROP PROCEDURE 存儲過程名字
  • 修改存儲過程:ALTER {PROCEDURE | FUNCTION} sp_name [characteristic ...]
    • {CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA} | SQL SECURITY {DEFINER | INVOKER} | COMMENT 'string'
    • NO SQL表示子程序中不包含SQL語句;READS SQL DATA表示子程序中包含讀數據的語句;MODIFIES SQL DATA表示子程序中包含寫數據的語句。SQL SECURITY {DEFINER | INVOKER} 指明誰有權限來執行。DEFINER表示只有定義者本身才可以執行;INVOKER表示調用者能夠執行。COMMENT 'string'是註釋信息。

函數

默認函數功能時關閉的,SHOW VARIABLES LIKE '%fun%'能夠查看到函數功能是否關閉,若是顯示OFF,能夠設置爲ONSET global log_bin_trust_function_creators=1

建立函數

-- 返回是 RETURNS 不是 RETURN,數據類型和返回的數據類型要一致
CREATE FUNCTION 函數名( 變量1, 變量2,... )
RETURNS 數據類型
BEGIN
  ...執行的程序代碼
  RETURN 數據;
END;

CREATE FUNCTION add_f(a INT,b INT)
RETURNS INT
BEGIN
  RETURN a + b;
END~

SELECT add_f(3,4)~  --> 7

刪除函數

DROP FUNCTION [IF EXISTS] 函數名

DROP FUNCTION IF EXISTS add_f~

視圖

視圖是由查詢結果造成的一張虛擬表。
若是某個查詢結果出現的很是頻繁,也就是,要常常拿這個查詢結果來作子查詢,就可使用視圖。

視圖的好處:簡化查詢語句;能夠進行權限控制;大數據表分表的時候,好比某張表的數據由100萬條,那麼能夠將這張表分紅四個視圖。

建立視圖

CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
  VIEW view_name [(column_list)]
  AS select_statement
  [WITH [CASCADED | LOCAL] CHECK OPTION]

該語句能建立新的視圖,若是給定了OR REPLACE子句,該語句還能替換已有的視圖。select_statement是一種SELECT語句,它給出了視圖的定義。該語句可從基表或其餘視圖進行選擇。

-- 把一張表分紅4個視圖,分紅四部分查詢
CREATE OR REPLACE VIEW view_employee1
AS
SELECT * FROM employees WHERE emp_id % 4 = 0;

CREATE OR REPLACE VIEW view_employee2
AS
SELECT * FROM employees WHERE emp_id % 4 = 1;

CREATE OR REPLACE VIEW view_employee3
AS
SELECT * FROM employees WHERE emp_id % 4 = 2;

CREATE OR REPLACE VIEW view_employee4
AS
SELECT * FROM employees WHERE emp_id % 4 = 3;

視圖管理

視圖存放在 information_schema數據庫下的views表裏。

1.視圖的算法

  • Merge:合併的執行方式,每當執行的時候,先將咱們視圖的SQL語句與外部查詢視圖的SQL語句,混合在一塊兒,最終執行;
  • Temptable:臨時表模式,每當查詢的時候,將視圖所使用的SELECT語句生成一個結果的臨時表,再在當前的臨時表內進行查詢。

對於Merge,會將引用視圖的語句的文本與視圖定義合併起來,使得視圖定義的某一部分取代語句的對應部分。
對於Temptable,視圖的結果將被置於臨時表中,而後使用它執行語句。
對於UNDEFINED,MySql將選擇所要使用的算法。若是可能,它傾向於MERGE而不是TEMPTABLE,這是由於MERGE一般更有效,並且若是使用了臨時表,視圖是不可更新。

2.查看視圖的定義:SHOW table status [FROM 數據庫名] [LIKE '匹配']

3.刪除視圖定義:只能刪除視圖的定義,不能刪除數據,必須有DROP權限

  • DROP VIEW [IF EXISTS] view_name [RESTRICT | CASCADE]

4.查看權限:mysql>SELECT Drop_priv FROM mysql.user WHERE USER='root';

5.刪除視圖

  • DROP VIEW IF EXISTS worker_view1;

6.刪除多個

  • DROP VIEW IF EXISTS department_view1,department_view2;

7.視圖更新:某些視圖是可更新的。也就是說,能夠在諸如UPDATE、DELETE 或 INSERT 等語句中使用它們,以更新基表的內容。對於可更新的視圖,在視圖中的行和基表彙總的行之間必須具備一對一的關係。還有一些特定的其餘結構,這類結構會是的視圖不可更新。更具體地講,若是視圖包含下面中的任何一種,那麼它就是不可更新的:

  • 聚合函數(SUM(),MIN(),COUNT()等)
  • DISTINCT
  • GROUP BY
  • HAVING
  • UNSIGNED 或UNION ALL
  • 位於選擇列表中的子查詢
  • JOIN
  • FROM 子句中的不可更新視圖
  • WHERE 子句中的子查詢,引用FROM子句中的表
  • 僅引用文字值(在該狀況下,沒有要更新的基本表)
  • ALGORITHM = TEMPTABLE(使用臨時表總會使視圖成爲不可更新的)

8.with check option的理解和應用:經過視圖進行的修改,必須也能經過該視圖看到修改後的結果。更新視圖的數據,那麼必須先知足視圖的條件,知足以後纔可以更新到基表中。

觸發器

觸發器是一種特殊的存儲過程,它在插入、刪除或修改特定表中的數據時觸發執行,它比數據庫自己標準的功能有更精細和更復雜的數據控制能力。

觸發器的特性:

  • 監視地點:通常就是表名
  • 監視時間:update、delete、insert
  • 觸發事件:after、before
  • 觸發事件:update、delete、insert

觸發器不能直接被調用,是由數據庫主動去執行。

建立觸發器

CREATE TRIGGER 語法:
CREATE TRIGGER trigger_name trigger_time trigger_event
  ON tbl_name FOR EACH ROW trigger_stmt

觸發程序是與表有關的命名數據庫對象,當表上出現特定事件時,將激活該對象。
觸發程序與命名爲tbl_name的表相關,tbl_name必須引用永久性表,不能將觸發程序與TEMPORARY表或視圖關聯起來。
trigger_time是觸發程序的動做時間。它能夠是BEFORE或AFTER,以指明觸發程序是在激活它的語句以前或以後觸發。
trigger_event指明瞭激活觸發程序的語句的類型。trigger_event能夠是下述值之一:

  • INSERT:將新行插入表時激活觸發程序,例如,經過INSERT、LOAD DATA和REPLACE語句
  • UPDATE:更改某一行時激活觸發程序,例如,經過UPDATE語句
  • DELETE:從表中刪除某一行時激活觸發程序,例如,經過DELETE和REPLACE語句
    注意:trigger_cvent與以表操做方式激活觸發程序的SQL語句並不很相似,這點很重要。例如,關於INSERT的BEFORE觸發程序不只能被INSERT語句激活,也能被LOAD DATA語句激活。可能會形成混淆的例子之一是INSERT INTO .. ON DUPLICATE UPDATE ...語法:DEFORE INSERT
    觸發程序對於每一行激活,後跟AFTER INSERT觸發程序,或BEFORE UPDATE和AFTER UPDATE觸發程序,具體狀況取決於行上是否有重複鍵。
    對於具備相同觸發程序動做時間和時間的給定表,不能有兩個觸發程序。例如,對於某一表,不能有兩個BEFORE UPDATE觸發程序。但能夠有1個BEFORE UPDATE觸發程序。
    trigger_stmt是當觸發程序激活時執行的語句。若是打算執行多個語句,可使用DEGIN ... END符合語句結構。這樣,就能使用存儲子程序中容許的相同語句。

特別說明:

  • 對於INSERT而言,就插入的行用new來標識,行中的每一列的值用new.列名來表示
  • 對於DELETE而言,本來有一行,後來被刪除,想引用被刪除的這一行,用old來表示,old.列名能夠引用被刪除的行的值
  • 對於update而言,其修改的行,修改前的數據,用old來表示,old.列名引用被修改以前中的值;修改後的數據,用new來表示,new.列名引用被修改以後運行中的值。
CREATE TRIGGER tr_insert AFTER INSERT
ON employee FOR EACH ROW
BEGIN
  INSERT salaries VALUES(new.emp_no,0,'2019-05-10');
END~

CREATE TRIGGER tr_delete AFTER DELETE
ON employee FOR EACH ROW
BEGIN
  DELETE FROM salaries WHERE emp_no=old.emp.no;
END~

觸發器的管理

1.查看全部觸發器:SHOW TRIGGERS;

2.MYSQL中有一個information_schema.TRIGGERS表,存儲全部庫中的全部觸發器,DESC information_schema.TRIGGERS,能夠查看到觸發器結構。

3.查看觸發器名字:SELECT * FROM information_schema.TRIGGERS WHERE TRIGGER_NAME='觸發器名字'\G

4.刪除觸發器:DROP TRIGGER [schema_name.]trigger_name

MyISAM表鎖

鎖是計算機協調對個進程或線程併發訪問某一資源的機制。在數據庫中,數據也是一種供許多用戶共享的資源。如何保證數據併發訪問的一致性、有效性是全部數據庫必須解決的一個問題,鎖衝突也是影響數據庫併發訪問性能的一個重要因素。從這個角度來講,鎖對數據庫而言顯得尤爲重要,也更加複雜。

MYSQL鎖機制相比其餘數據庫,最顯著的特色是不一樣的存儲引擎支持不一樣鎖機制。好比MyISAM和MEMORY存儲引擎採用的是表級鎖(table-level locking);BDB存儲引擎採用的是頁面鎖(page-level locking),但也支持表級鎖;INNODB既支持行級鎖(row-level locking),也支持表級鎖,但默認是行級鎖。

  • 表級鎖:開銷小,加鎖塊,不會出現死鎖;鎖粒粒度大,發生鎖衝突的機率高,併發度最低
  • 行級鎖:開銷大,加鎖慢,會出現死鎖;併發度最高
  • 頁面鎖:開銷介於之間,會出現死鎖,併發度通常。
    從鎖的角度說,表級鎖更適合於以查詢爲主,只有少許按索引條件更新數據的應用,如WEB應用;而行級鎖更適合於有大量按索引條件併發更新少許不一樣數據,同時又併發查詢的應用,好比一些在線事務處理(OLTP)系統。

共享讀鎖

先把數據庫導出,在導出的.sql文件中添加set storage_engine = MyISAM;,而後再導入,確保成爲MyISAM存儲引擎。

MySQL的表級鎖有兩種模式:表共享讀鎖(Table Read Lock)和表獨佔寫鎖(Table Write Lock)。

對於MyISAM表的讀操做,不會阻塞其餘用戶對同一表的讀請求,但會阻塞對同一表的寫請求;對於寫操做,則會阻塞其餘用戶對同一表的讀和寫操做;讀操做和寫操做之間,以及寫操做之間是串行的。

一個SESSION使用LOCK TABLE命令給表加了讀鎖,這個SESSION能夠查詢鎖定表中的記錄,但更新或訪問其餘表會提示錯誤;同時,另一個SESSION能夠查詢表中的記錄,但更新就會出現鎖等待。

1.加共享讀鎖:LOCK TABLE tbl_name READ;

2.解鎖:UNLOCK TABLES;

獨佔寫鎖

1.加獨佔寫鎖:LOCK TABLE tbl_name WRITE;

2.解鎖:UNLOCK TABLES;

併發插入

MyISAM表的讀和寫是串行的,但就整體而言,在必定條件下,MyISAM表也支持查詢和插入操做的併發進行。
該引擎有一個系統變量consurrent_insert,專門用以控制其併發插入的行爲,其值分別能夠爲0、1和2.

  • 當爲0時,不容許併發插入
  • 當爲1時,若是MyISAM表中沒有空洞(即表的中間沒有被刪除的行),MyISAM運行在一個進程讀表的同時,另外一個進程從表尾插入記錄。這也是MYSQL的默認設置
  • 當爲2時,不管MyISAM表中有沒有空洞,都容許在表尾併發插入記錄

鎖調度:一個進程請求讀鎖,另外一個進程請求同一表的寫鎖;寫進程先得到鎖。MYSQL任務寫請求更重要。MyISAM不適合有大量更新操做和查詢操做。
解決方法:執行set low_priority_updates=1,使該鏈接發出的更新請求優先下降,其中insert、delete也能夠經過此方法指定。

事務

1.查看數據庫是否支持事務(INNODB支持):SHOW ENGINES;
2.查看MYSQL當前默認的存儲引擎:SHOW VARIABLES LIKE '%storage_engine%'
3.查看某張表的存儲引擎:SHOW CREATE TABLE tbl_name
4.修改表的存儲結構:

  • CREATE TABLE ... type=InnoDB;
  • ALTER TABLE tbl_name type=InnoDB;

建立事務

事務是爲了保證數據的一致性,開啓事務以後須要提交以後數據纔會生效。
START TRANSACTION; 開啓事務
COMMIT; 提交

SET AUTOCOMMIT=1; 自動提交

事務的回滾

回到事務發生以前的數據狀態,經過 ROLLBACK;
補充:

  • commit and chain; 表示提交事務以後從新開啓了新的事務。
  • rollback and release; 表示事務回滾以後斷開和客戶端的鏈接。

還原點:
Set autocommit=0;
insert into userinfo values(6,’test1’,’128’);
savepoint s1;
insert into userinfo values(6,’test2’,’128’);
savepoint s2;
執行完三條插入語句,select * from userinfo能夠看到三條。若是你想回滾到最初roolback就是最初什麼都沒有作的狀態。若是你想回到savepoint s1的狀態(也就是插入一條test1那裏): rollback to savepoint s1; 。

事務更改被鎖定: lock table 事務名稱 writes;
解鎖,讓其餘客戶端可讀: start transaction;

事務的4個屬性:原子性、一致性、隔離性、持久性,這四個屬性一般稱爲ACID特性。

  • 原子性(atomicity):一個事務是一個不可分割的工做單位,事務中包括的諸操做要麼都作,要麼都不作;
  • 一致性(consistencr):事務必須是使數據庫從一個一致性狀態變到另外一個一致性狀態,一致性與原子性密切相關;
  • 隔離性(isolation):一個事務的執行不能被其餘事物干擾。即一個事物內部的操做及使用的數據對併發的他事物是隔離的,併發執行的各個事物之間不能互相干擾;
  • 持久性(durability):持久性也稱永久性,指一個事物一旦提交,它對數據庫中的數據的改變應該是永久性的。接下來的其餘操做或鼓掌不該該對其有任何影響。

慢查詢

MYSQL 記錄下查詢超過指定時間的語句,咱們將超過指定時間的SQL語句查詢成爲‘慢查詢’。
查看慢查詢設定時間:SHOW VARIABLES LIKE '%long%';

獲取慢查詢

SHOW status語句,獲取當前數據庫運行的時間:

  • SHOW status LIKE 'uptime%'
  • SHOW status LIKE 'com_Select'
  • SHOW status LIKE 'connections'
  • SHOW status LIKE 'slow_quries'

啓動慢查詢

啓動慢查詢須要以安全模式啓動mysql服務,安全模式能夠經過日誌恢復數據庫:mysql.exe --safe-mode --slow-query-log

數據庫存儲日誌存放位置能夠在my.ini中的datadir=‘...’查看到,而後打開到該文件夾,就能看到ZY-slow.log文件。超過設定時間,一般是5s-10s,就能在.log文件中看到。

配置慢查詢

在mysql的配置文件中添加參數:

-- 文件和文件夾是已經建立好的
log-slow-queries=C:/MySQL/log/mysqld-slow-query.log

-- 慢查詢的時間設置
long-query-time=5

-- 及時沒有超過期間,但若是沒有使用到索引,也會記錄SQL語句
log-queries-not-using-indexes

索引

在關係數據庫中,索引是一種與表有關的數據庫結構,它可使對於於表的SQL語句執行更快。

索引的分類

1.主鍵索引:ALTER TABLE tbl_name PRIMARY KEY(字段名)

2.惟一索引:惟一索引所在的列能夠爲NULL值;惟一索引所在的列不能爲空字符串。注:列名即字段名
CREATE UNIQUE INDEX 索引名稱 ON tbl_name(列名)

3.普通索引: CREATE INDEX 索引名稱 ON tbi_name(字段名)

4.全文(FULL TEXT)索引: 用於全文搜索,只有MyISAM表類型支持FULL TEXT索引;FULL TEXT索引只能夠從CHAR、VARCHAR和TEXT列中建立;整個列都會被編入索引,不支持部分列編索引。

-- 查看數據表articles中title,body字段中包含database單詞的
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('database');

-- 查看全文匹配度
SELECT id,MATCH(title,body) AGAINST ('Tutorial') FROM articles;

索引的管理

1.查看索引:SHOW KEYS FROM tbl_name 或者 SHOW INDEXS FROM tbl_name

2.刪除索引:ALTER TABLE tbl_name DROP INDEX 索引名稱

3.經過Explain分析具體有沒有使用索引,執行低效SQL的執行計劃:
EXPLAIN SELECT 索引名稱(字段名) FROM tbl_name\G;
EXPLAIN SELECT 字段名 FROM tbl_name\G;

經過索引優化SQL

索引原理:主要經過二叉樹去尋找索引文件,效率:log2N 檢索10次:2的10次方,1024條記錄

索引帶來的開銷:

  • .frm 文件: 表示表的結構
  • .myd 文件: 表示數據
  • .myi 文件: 表示索引的文件

哪些不適合建立索引:更新很是頻繁的字段;惟一性比較差的字段,好比人的性別。

建立索引的條件:確定在WHERE條件中常用到的;該字段的變化不會太頻繁。

經過 SHOW PROFILE 分析 SQL 具體消耗時間:

  1. 首先查看 mysql 是否支持 SHOW PROFILE
    SELECT @@HAVE_PROFILING;
  2. 若是 PROFILING 是關閉的,能夠經過 SET 語句在 SESSION 級別開啓 PROFILING
    SET PROFILING=1;
  3. 執行完畢以後,能夠經過 SHOW PROFILES; 語句,查看當前 SQL 的 QUERY ID
  4. 執行 SELECT COUNT(*) FROM 表名;
  5. 經過 SHOW PROFILE FOR QUERY ID;。

優化

表的分析、檢查、優化:
1.按期分析表:ANALYZE [ LOCAL | NO_WRITE_TO_BINLOG ] TABLE tbl_name [,tbl_name]

2.按期檢查表:CHECK TABLE tbl_name [,tbl_name ] [option]
備註:CHECK TABLE 也能夠檢查視圖是否有錯誤,好比在視圖定義中被引用的表已不存在

3.按期優化表:OPTIMIZE [ LOCAL | NO_WRITE_TO_BINLOG ] TABLE tbl_name [,tbl_name]
對於MyISAM表,OPTIMIZE TABLE按以下方式操做:

  • 若是表已經刪除或分解了行,則修復表;
  • 若是未對索引頁進行分類,則進行分類
  • 若是表的統計數據沒有更新(而且經過對索引進行分類不能實現修復),則進行更新

注意:不管是ANALYZER,CHECK仍是OPTIMIZE在執行期間將對錶進行鎖定,所以請注意這些操做要在數據庫不繁忙的時候執行。

獲取表的相關信息

SHOW TABLE STATUS 獲取表的信息
SHOW TABLE STATUS LIKE 'tableName'\G

1.Name:表名稱
2.Engine:表的存儲引擎
3.Version:版本
4.Row_format:行格式
5.Rows:表中的行數
6.Avg_row_length:平均每行包括的字節數
7.Data_length:整個表的數據量(單位:字節)
8.Max_data_length:表能夠容納的最大數據量
9.Index_length:索引佔用磁盤的空間大小
10.Data_free:未使用空間
11.Auto_increment:下一個自增加值
12.Create_time:表建立時間
13.Update_time:表最近更新時間
14.Check_time:使用check table或myisamchk工具檢查表的最近時間
15.Collation:表的默認字符集和字符排序規則
16.Checksum:啓用則對整個表的內容計算時的檢驗和
17.Create_options:指表建立時的其餘全部選項
18.Comment:包含了其餘額外信息

表的分區

當數據量過大的時候,須要將一張表的數據劃分幾張表存儲。一些查詢能夠獲得極大的優化,這主要是有助於知足一個給定WHERE語句的數據能夠值保存在一個或多個分區內,這樣在查找時就不用查找其餘剩餘的分區。

查看是否支持分區:SHOW VARIABLES LIKE '%partition%'; yes表示支持分區。

分區的分類:

  • RANGE分區:基於屬於一個特定連續區間的列值,把多行分配給分區
  • LIST分區:相似與按RANGE分區,區別在於它是基於列值匹配一個離散值集合中的某個值來進行選擇
  • HASH分區:基於用戶定義的表達式的返回值來進行選擇的分區
  • KEY分區::相似與HASH分區,區別在於它只支持計算一列或多列
CREATE TABLE employees(
  id INT NOT NULL,
  fname VARCHAR(30),
  lname VARCHAR(30),
  hired DATE NOT NU;; DEFAULT '1970-01-01',
  separated DATE NOT NULL DEFAULT '9999-12-31',
  job_code INT NOT NULL,
  store_id INT NOT NULL
)

partition BY RANGE(store_id)(
  partition p0 VALUES LESS THAN(6),
  partition p1 VALUES LESS THAN(11),
  partition p2 VALUES LESS THAN(16),
  partition p3 VALUES LESS THAN MAXVALUE
);

-- 查看分區
SHOW CREATE TABLE employees\G

分區的刪除:ALTER TABLE 表名 DROP PARTITION 分區名

增長分區:ALTER TABLE 表名 ADD PARTITION(PARTITION 分區名字 VALUES LESS THEN 具體的某個值)

內存優化

myisam內存優化:
1.key_buffer_size設置,決定索引塊緩存區的大小,通常的myisam數據庫,建議用1/4可用內存分配給key_buffer_size:
key_buffer_size=2G
2.read_buffer_size,常常順序掃描myisam表,就須要設置,該值是每一個session獨佔的,若是默認值設置太大,就會形成內存浪費。
3.read_rnd_buffer_size,須要作排序的myisam表查詢,如帶有order by子句的sql,適當增長該值。但須要注意,該值是每一個session獨佔的,設置太大內存浪費。

innodb內存優化:
1.innodb_buffer_pool_size,決定表數據和索引數據的最大緩存區大小
2.innodb_log_buffer_size,決定innodb重作日誌緩存的大小,對應有大量更新記錄的事務,增長該值大小,能夠避免在事務提交前就執行沒必要要的日誌寫入磁盤操做。

mysql併發參數:
1.max_connections,提升併發鏈接
2.thread_cache_size,加快鏈接數據庫的速度,控制mysql緩存客戶服務線程的數量
3.innodb_lock_wait_timeout,控制innodb事務等待行鎖的時間

應用程序優化

1.訪問數據庫採用鏈接池優化,就是鏈接數據庫的客戶端放在一個鏈接池裏。

2.採用緩存減小對mysql的訪問:

  • 避免對同一數據作重複檢索,儘量選擇多個字段
  • 使用查詢緩存,好比一條SQL查詢除了字段名和代表不同,其餘都同樣,mysql就會把SQL語句1緩存,發給SQL2語句
  • 緩存參數的配置
    • query_cache_type:是否打開緩存,大小寫要同樣,如下是可選項
      • OFF :關閉
      • ON:老是打開
      • DEMAND:只有明確寫了SQL_CACHE的查詢纔會吸入緩存
    • query_cache_size:緩存使用的總內存大小空間,單位字節,必須是1024的整數倍,不然MYSQL實際分配可能跟這個數值不一樣
    • query_cache_min_res_unit:分配內存塊時的最小單位大小
    • query_cache_limit:MYSQL可以緩存的最大結構,若是超出則增長query_not_cached的值,並刪除查詢結果
    • query_cache_wlock_invalidate:若是某個數據表被鎖住,是否仍然從緩存中返回數據,默認是OFF,即是仍然返回

3.負載均衡(讀寫分離):一個主MYSQL服務器(MASTER)服務器與多個從屬MYSQL服務器(STAVE)創建複製(replication)鏈接,主服務器與從屬服務器實現必定程度上的數據同步,多個從屬服務器存儲相同的數據副本,實現數據冗餘,提供容錯功能。部署開發應用系統時,對數據庫操做代碼進行優化,將寫操做(如UPDATE、INSERT)定向到主服務器,把大量的查詢操做(SELECT)定向到從屬服務器,實現集羣的負載均衡功能。

若是主服務器發生故障,從屬服務器將轉換角色成爲主服務器,是應用系統爲終端用戶提供不剪短的網絡服務;主服務器恢復運行後,將其轉換爲從屬服務器,存儲數據庫副本,繼續對終端用戶提供數據查詢檢索服務。

帳號管理

查看用戶:
mysql>USE mysql;
mysql>SELECT host,user,password FROM user;

1.GRANT命令使用

對於ZY用戶,賦予SELECT的權限,能查看全部數據庫和全部數據表
GRANT SELECT ON . TO ZY@'localhost' IDENTIFIED BY 'PWD' WITH GRANT OPTION;;

對應YZ用戶,賦予test下索引數據表的索引權限
GRANT ALL PRIVILEGES ON test.* TO YZ@'localhost' IDENTIFIED BY 'PWD' WITH GRANT OPTION;;

  • ALL PRIVILEGES :表示多有權限,你也可使用SELECT、UPDATE等提到的權限
  • ON :用來指定權限針對哪些庫和表
  • test.* :test數據庫下的全部表
  • TO :表示將權限賦予給哪一個用戶
  • YZ@'localhost' :表示test用戶,@後面接限制的主機,能夠是IP、IP段、域名以及%,%表示任何地方,但有的版本不包括本地,若是不包括須要再加一個localhost的用戶
  • IDENTIFIED BY :指定用戶的登陸密碼
  • WITH GRANT OPTION :表示該用戶能夠將本身擁有的權限

2.查看用戶的權限:
SHOW GRANTS FOR ‘root’@'localhost'

3.刪除用戶,不只僅要刪除用戶的名稱,還要刪除用戶擁有權限。
使用DELETE刪除,並不能刪除權限,新建同名用戶後會繼承之前的權限,正確的作法是使用DROP命令:
DROP USER ‘zy’@'localhost' ;

4.修改密碼
SET PASSWORD FOR 'ty'@'localhost'=password('123');

5.對帳號權限的資源設置
GRANT SELECT ON employees.* TO test@localhost IDENTIFIED BY 'pwd' WITH max_queries_per_hour 5 max_user_connections 6;

  • 設置test用戶對employees數據庫的權限,每小時查詢的次數小於5次,最多有6個用戶進行併發鏈接

MYSQL監控

隨着軟件後期的不斷升級,mysql的服務器數量愈來愈多,軟硬件故障的發生機率也愈來愈高。這個時候須要一套監控系統,當主機發生異常時,此時經過監控系統發現和處理。

1.常見監控方式的分類:下面語句沒有分號;

  • 本身寫程序或者腳本控制
    • 監控mysql是否提供正常的服務:mysqladmin -uroot -proot -hlocalhost ping,輸出:mysql is alive
    • 獲取當前的幾個狀態值:mysqladmin -uroot -proot -hlocalhost status
    • 獲取數據庫當前的鏈接信息:mysqladmin -uroot -proot -hlocalhost processlist
    • 獲取當前數據庫的鏈接數:mysql -uroot -proot -BNe "select host,count(host) from processlist group by host;" information_schema
    • 檢查修復分析優化:mysqlcheck -u root -proot --all-databases
    • 在客戶端執行如下命令
      • 檢查臨時表是否過多:SHOW STATUS LIKE 'Created_tmp%'
      • 鎖定狀態:SHOW STATUS LIKE "%lock%"
      • Inonodb_log_waits反應Innodb Log Buffer空間不足形成等待的次數:SHOW STATUS LIKE 'Innodb_log_waits'
  • 監控採用商業解決方案
  • 監控開源軟件

定時維護

mysql 設置定時器,從5.1開始才支持event的。查看版本SELECT VERSION();
1.查看是否開啓event與開啓event

  • 查看evevt的狀態:SHOW VARIABLES LIKE '%sche%'
  • 開啓evevt功能:SET GLOBAL event_scheduler=1;

2.建立定時器,建立事件test_event:

DROP EVENT IF EXISTS test_event;
CREATE EVENT test_event
ON schedule every 1 second
ON completion preserve disable
DO CALL p_test_proce();

-- 當爲on completion preserve的時候,當event到期了,event會被disable,但該event還會存在

-- 當爲on completion not preserve的時候,當event到期時,該event會被自動刪除

-- p_test_proce是一個存儲過程的名字
  • 開啓事件test_event:ALTER EVENT test_event ON completion preserve enable;
  • 關閉事件test-event:ALTER EVENT test_event ON completion preserve disable;

備份與還原

1.備份:

  • 經過mysqldump命令備份:
    • 備份單個數據庫:mysqldump -u username -p dbname [table1 table2] > backupName.sql
      • dbname 表示數據庫的名稱,table1 table2表示備份表名稱,backupName.sql參數表設計備份文件的名稱
    • 備份多個數據庫:mysqldump -u username -p --databases dbname1 dbname2 >backup.sql
    • 備份全部數據庫:mysqldump -u username -p -all-databases > bakcupName.sql
  • 直接複製整個數據庫目錄
  • 使用mysqlhotcopy工具快速備份

2.還原

  • 使用mysql命令還原mysqldump備份的數據庫:
    • mysql -u root -p [dbname] < backupName.sql
相關文章
相關標籤/搜索