1. 程式人生 > 其它 >mysql整理

mysql整理

一、資料庫概念

1.1、什麼是資料庫

資料庫 ( DataBase , 簡稱DB )

概念 : 長期存放在計算機內,有組織,可共享的大量資料的集合,是一個數據 "倉庫"

作用 : 儲存,並能安全管理資料(如:增刪改查等),減少冗餘...

資料庫總覽 :

  • 關係型資料庫 ( SQL )

    • MySQL , Oracle , SQL Server , SQLite , DB2 , ...
    • 關係型資料庫通過外來鍵關聯來建立表與表之間的關係
  • 非關係型資料庫 ( NOSQL )

    • Redis , MongoDB , ...
    • 非關係型資料庫通常指資料以物件的形式儲存在資料庫中,而物件之間的關係通過每個物件自身的屬性來決定

1.2、什麼是DBMS

資料庫管理系統 ( DataBase Management System )

資料庫管理軟體 , 科學組織和儲存資料 , 高效地獲取和維護資料

MySQL應該算是一個數據庫管理系統.

1.3、MySQL簡介

概念 : 是現在流行開源的,免費關係型資料庫

歷史 : 由瑞典MySQL AB 公司開發,目前屬於 Oracle 旗下產品。

特點 :

  • 免費 , 開源資料庫
  • 小巧 , 功能齊全
  • 使用便捷
  • 可運行於Windows或Linux作業系統
  • 可適用於中小型甚至大型網站應用

官網 : https://www.mysql.com/

二、資料庫操作

2.1、結構化查詢語句分類

名稱 解釋 命令
DDL資料庫定義語言 定義和管理資料物件,庫表等 create,drop,alter...
DML資料庫操作語言 操作資料 INSERT,UPDATE,DELETE
DQL資料查詢語言 查詢 select
DCL資料控制語言 管理資料庫的語言,修改許可權等 grant,commit,roolback

2.2、資料庫操作

命令列操作資料庫

建立資料庫 :  create database [if not exists] 資料庫名;
刪除資料庫 : drop database [if exists] 資料庫名;
檢視資料庫 : show databases;
使用資料庫 : use 資料庫名;

2.2.1、建立資料表

屬於DDL的一種,語法 :

create table [if not exists] `表名`(
   '欄位名1' 列型別 [屬性][索引][註釋],
   '欄位名2' 列型別 [屬性][索引][註釋],
   '欄位名n' 列型別 [屬性][索引][註釋]
)[表型別][表字符集][註釋];

說明 : 反引號用於區別MySQL保留字與普通字元而引入的 (鍵盤esc下面的鍵).

2.2.2、資料值和列型別

列型別 : 規定資料庫中該列存放的資料型別

2.2.2.1、數值型別

2.2.2.2、字串型別

型別 大小 用途
CHAR 0-255 bytes 定長字串
VARCHAR 0-65535 bytes 變長字串
TINYBLOB 0-255 bytes 不超過 255 個字元的二進位制字串
TINYTEXT 0-255 bytes 短文字字串
BLOB 0-65 535 bytes 二進位制形式的長文字資料
TEXT 0-65 535 bytes 長文字資料
MEDIUMBLOB 0-16 777 215 bytes 二進位制形式的中等長度文字資料
MEDIUMTEXT 0-16 777 215 bytes 中等長度文字資料
LONGBLOB 0-4 294 967 295 bytes 二進位制形式的極大文字資料
LONGTEXT 0-4 294 967 295 bytes 極大文字資料

2.2.2.3、日期和時間型數值型別

型別 大小 ( bytes) 範圍 格式 用途
DATE 3 1000-01-01/9999-12-31 YYYY-MM-DD 日期值
TIME 3 '-838:59:59'/'838:59:59' HH:MM:SS 時間值或持續時間
YEAR 1 1901/2155 YYYY 年份值
DATETIME 8 1000-01-01 00:00:00/9999-12-31 23:59:59 YYYY-MM-DD HH:MM:SS 混合日期和時間值
TIMESTAMP 4 1970-01-01 00:00:00/2038 結束時間是第 2147483647 秒,北京時間 2038-1-19 11:14:07,格林尼治時間 2038年1月19日 凌晨 03:14:07 YYYYMMDD HHMMSS 混合日期和時間值,時間戳

2.2.2.4、NULL值

  • 理解為 "沒有值" 或 "未知值"
  • 不要用NULL進行算術運算 , 結果仍為NULL

2.2.3、資料欄位屬性

UnSigned

  • 無符號的
  • 宣告該資料列不允許負數 .

ZEROFILL

  • 0填充的
  • 不足位數的用0來填充 , 如int(3),5則為005

Auto_InCrement

  • 自動增長的 , 每新增一條資料 , 自動在上一個記錄數上加 1(預設)

  • 通常用於設定主鍵 , 且為整數型別

  • 可定義起始值和步長

    • 當前表設定步長(AUTO_INCREMENT=100) : 隻影響當前表
    • SET @@auto_increment_increment=5 ; 影響所有使用自增的表(全域性)

NULL 和 NOT NULL

  • 預設為NULL , 即沒有插入該列的數值
  • 如果設定為NOT NULL , 則該列必須有值

DEFAULT

  • 預設的
  • 用於設定預設值
  • 例如,性別欄位,預設為"男" , 否則為 "女" ; 若無指定該列的值 , 則預設值為"男"的值
-- 目標 : 建立一個school資料庫
-- 建立學生表(列,欄位)
-- 學號int 登入密碼varchar(20) 姓名,性別varchar(2),出生日期(datatime),家庭住址,email
-- 建立表之前 , 一定要先選擇資料庫

CREATE TABLE IF NOT EXISTS `student` (
`id` int(4) NOT NULL AUTO_INCREMENT COMMENT '學號',
`name` varchar(30) NOT NULL DEFAULT '匿名' COMMENT '姓名',
`pwd` varchar(20) NOT NULL DEFAULT '123456' COMMENT '密碼',
`sex` varchar(2) NOT NULL DEFAULT '男' COMMENT '性別',
`birthday` datetime DEFAULT NULL COMMENT '生日',
`address` varchar(100) DEFAULT NULL COMMENT '地址',
`email` varchar(50) DEFAULT NULL COMMENT '郵箱',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

-- 檢視資料庫的定義
SHOW CREATE DATABASE school;
-- 檢視資料表的定義
SHOW CREATE TABLE student;
-- 顯示錶結構
DESC student;  -- 設定嚴格檢查模式(不能容錯了)SET sql_mode='STRICT_TRANS_TABLES';

2.2.4、資料表的型別

設定資料表的型別

CREATE TABLE 表名(
   -- 省略一些程式碼
   -- Mysql註釋
   -- 1. # 單行註釋
   -- 2. /*...*/ 多行註釋
)ENGINE = MyISAM (or InnoDB)

-- 檢視mysql所支援的引擎型別 (表型別)
SHOW ENGINES;

MySQL的資料表的型別 : MyISAM , InnoDB , HEAP , BOB , CSV等...

常見的 MyISAM 與 InnoDB 型別:

經驗 ( 適用場合 ) :

  • 適用 MyISAM : 節約空間及相應速度
  • 適用 InnoDB : 安全性 , 事務處理及多使用者操作資料表

資料表的儲存位置

  • MySQL資料表以檔案方式存放在磁碟中

    • 包括表文件 , 資料檔案 , 以及資料庫的選項檔案
    • 位置 : Mysql安裝目錄\data\下存放資料表 . 目錄名對應資料庫名 , 該目錄下檔名對應資料表 .
  • 注意 :

    • * . frm -- 表結構定義檔案

    • * . MYD -- 資料檔案 ( data )

    • * . MYI -- 索引檔案 ( index )

    • InnoDB型別資料表只有一個 *.frm檔案 , 以及上一級目錄的ibdata1檔案

    • MyISAM型別資料表對應三個檔案 :

設定資料表字符集

我們可為資料庫,資料表,資料列設定不同的字符集,設定方法 :

  • 建立時通過命令來設定 , 如 : CREATE TABLE 表名()CHARSET = utf8;
  • 如無設定 , 則根據MySQL資料庫配置檔案 my.ini 中的引數設定

2.2.5、修改資料庫

修改表 ( ALTER TABLE )

修改表名 :ALTER TABLE 舊錶名 RENAME AS 新表名

新增欄位 : ALTER TABLE 表名 ADD欄位名 列屬性[屬性]

修改欄位 :

  • ALTER TABLE 表名 MODIFY 欄位名 列型別[屬性]
  • ALTER TABLE 表名 CHANGE 舊欄位名 新欄位名 列屬性[屬性]

刪除欄位 : ALTER TABLE 表名 DROP 欄位名

刪除資料表

語法:DROP TABLE [IF EXISTS] 表名

  • IF EXISTS為可選 , 判斷是否存在該資料表
  • 如刪除不存在的資料表會丟擲錯誤

2.3、外來鍵

如果公共關鍵字在一個關係中是主關鍵字,那麼這個公共關鍵字被稱為另一個關係的外來鍵。由此可見,外來鍵表示了兩個關係之間的相關聯絡。

以另一個關係的外來鍵作主關鍵字的表被稱為主表,具有此外來鍵的表被稱為主表的從表

在實際操作中,將一個表的值放入第二個表來表示關聯,所使用的值是第一個表的主鍵值(在必要時可包括複合主鍵值)。此時,第二個表中儲存這些值的屬性稱為外來鍵(foreign key)。

外來鍵作用

保持資料一致性完整性,主要目的是控制儲存在外來鍵表中的資料,約束。使兩張表形成關聯,外來鍵只能引用外表中的列的值或使用空值。

2.4、建立外來鍵

1、建表時指定外來鍵約束

-- 建立外來鍵的方式一 : 建立子表同時建立外來鍵

-- 年級表 (id\年級名稱)
CREATE TABLE `grade` (
`gradeid` INT(10) NOT NULL AUTO_INCREMENT COMMENT '年級ID',
`gradename` VARCHAR(50) NOT NULL COMMENT '年級名稱',
PRIMARY KEY (`gradeid`)
) ENGINE=INNODB DEFAULT CHARSET=utf8

-- 學生資訊表 (學號,姓名,性別,年級,手機,地址,出生日期,郵箱,身份證號)
CREATE TABLE `student` (
`studentno` INT(4) NOT NULL COMMENT '學號',
`studentname` VARCHAR(20) NOT NULL DEFAULT '匿名' COMMENT '姓名',
`sex` TINYINT(1) DEFAULT '1' COMMENT '性別',
`gradeid` INT(10) DEFAULT NULL COMMENT '年級',
`phoneNum` VARCHAR(50) NOT NULL COMMENT '手機',
`address` VARCHAR(255) DEFAULT NULL COMMENT '地址',
`borndate` DATETIME DEFAULT NULL COMMENT '生日',
`email` VARCHAR(50) DEFAULT NULL COMMENT '郵箱',
`idCard` VARCHAR(18) DEFAULT NULL COMMENT '身份證號',
PRIMARY KEY (`studentno`),
KEY `FK_gradeid` (`gradeid`),
CONSTRAINT `FK_gradeid` FOREIGN KEY (`gradeid`) REFERENCES `grade` (`gradeid`)
) ENGINE=INNODB DEFAULT CHARSET=utf8

2、建表後修改

-- 建立外來鍵方式二 : 建立子表完畢後,修改子表新增外來鍵
ALTER TABLE `student`
ADD CONSTRAINT `FK_gradeid` FOREIGN KEY (`gradeid`) REFERENCES `grade` (`gradeid`);

2.5、刪除外來鍵

操作:刪除 grade 表,發現報錯

注意 : 刪除具有主外來鍵關係的表時 , 要先刪子表 , 後刪主表

-- 刪除外來鍵
ALTER TABLE student DROP FOREIGN KEY FK_gradeid;
-- 發現執行完上面的,索引還在,所以還要刪除索引
-- 注:這個索引是建立外來鍵的時候預設生成的
ALTER TABLE student DROP INDEX FK_gradeid;

三、DML語言

資料庫意義 : 資料儲存、資料管理

管理資料庫資料方法:

  • 通過navicat等管理工具管理資料庫資料
  • 通過DML語句管理資料庫資料

DML語言:資料操作語言

  • 用於操作資料庫物件中所包含的資料

  • 包括 :

    • INSERT (新增資料語句)
    • UPDATE (更新資料語句)
    • DELETE (刪除資料語句)

3.1、新增資料

INSERT INTO 表名[(欄位1,欄位2,欄位3,...)] VALUES('值1','值2','值3')

3.2、修改資料

update命令

語法:

UPDATE 表名 SET column_name=value [,column_name2=value2,...] [WHERE condition];

where條件子句

可以簡單的理解為 : 有條件地從表中篩選資料

測試:

-- 修改年級資訊
UPDATE grade SET gradename = '高中' WHERE gradeid = 1;

3.3、刪除資料

DELETE命令

語法:

DELETE FROM 表名 [WHERE condition];

注意:condition為篩選條件 , 如不指定則刪除該表的所有列資料

-- 刪除最後一個數據
DELETE FROM grade WHERE gradeid = 5

TRUNCATE命令

作用:用於完全清空表資料 , 但表結構 , 索引 , 約束等不變 ;

語法:

TRUNCATE [TABLE] table_name;

-- 清空年級表
TRUNCATE grade

注意:區別於DELETE命令

  • 相同 : 都能刪除資料 , 不刪除表結構 , 但TRUNCATE速度更快

  • 不同 :

    • 使用TRUNCATE TABLE 重新設定AUTO_INCREMENT計數器
    • 使用TRUNCATE TABLE不會對事務有影響 (事務後面會說)

測試:

-- 建立一個測試表
CREATE TABLE `test` (
`id` INT(4) NOT NULL AUTO_INCREMENT,
`coll` VARCHAR(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8

-- 插入幾個測試資料
INSERT INTO test(coll) VALUES('row1'),('row2'),('row3');

-- 刪除表資料(不帶where條件的delete)
DELETE FROM test;
-- 結論:如不指定Where則刪除該表的所有列資料,自增當前值依然從原來基礎上進行,會記錄日誌.

-- 刪除表資料(truncate)
TRUNCATE TABLE test;
-- 結論:truncate刪除資料,自增當前值會恢復到初始值重新開始;不會記錄日誌.

-- 同樣使用DELETE清空不同引擎的資料庫表資料.重啟資料庫服務後
-- InnoDB : 自增列從初始值重新開始 (因為是儲存在記憶體中,斷電即失)
-- MyISAM : 自增列依然從上一個自增資料基礎上開始 (存在檔案中,不會丟失)

四、使用DQL查詢資料

4.1、DQL( Data Query Language 資料查詢語言 )

  • 查詢資料庫資料 , 如SELECT語句
  • 簡單的單表查詢或多表的複雜查詢和巢狀查詢
  • 是資料庫語言中最核心,最重要的語句
  • 使用頻率最高的語句

SELECT語法

SELECT [ALL | DISTINCT]
{* | table.* | [table.field1[as alias1][,table.field2[as alias2]][,...]]}
FROM table_name [as table_alias]
  [left | right | inner join table_name2]  -- 聯合查詢
  [WHERE ...]  -- 指定結果需滿足的條件
  [GROUP BY ...]  -- 指定結果按照哪幾個欄位來分組
  [HAVING]  -- 過濾分組的記錄必須滿足的次要條件
  [ORDER BY ...]  -- 指定查詢記錄按一個或多個條件排序
  [LIMIT {[offset,]row_count | row_countOFFSET offset}];
   -- 指定查詢的記錄從哪條至哪條

注意 : [ ] 括號代表可選的 , { }括號代表必選得

4.2、指定查詢欄位

-- 查詢表中所有的資料列結果 , 採用 **" \* "** 符號; 但是效率低,不推薦 .

-- 查詢所有學生資訊
SELECT * FROM student;

-- 查詢指定列(學號 , 姓名)
SELECT studentno,studentname FROM student;

4.3、AS 子句作為別名

作用:

  • 可給資料列取一個新別名
  • 可給表取一個新別名
  • 可把經計算或總結的結果用另一個新名稱來代替
-- 這裡是為列取別名(當然as關鍵詞可以省略)
SELECT studentno AS 學號,studentname AS 姓名 FROM student;

-- 使用as也可以為表取別名
SELECT studentno AS 學號,studentname AS 姓名 FROM student AS s;

-- 使用as,為查詢結果取一個新名字
-- CONCAT()函式拼接字串
SELECT CONCAT('姓名:',studentname) AS 新姓名 FROM student;

DISTINCT關鍵字的使用

作用 : 去掉SELECT查詢返回的記錄結果中重複的記錄 ( 返回所有列的值都相同 ) , 只返回一條

-- # 檢視哪些同學參加了考試(學號) 去除重複項
SELECT * FROM result; -- 檢視考試成績
SELECT studentno FROM result; -- 檢視哪些同學參加了考試
SELECT DISTINCT studentno FROM result; -- 瞭解:DISTINCT 去除重複項 , (預設是ALL)

使用表示式的列

資料庫中的表示式 : 一般由文字值 , 列值 , NULL , 函式和操作符等組成

應用場景 :

  • SELECT語句返回結果列中使用

  • SELECT語句中的ORDER BY , HAVING等子句中使用

  • DML語句中的 where 條件語句中使用表示式

    -- selcet查詢中可以使用表示式
    SELECT @@auto_increment_increment; -- 查詢自增步長
    SELECT VERSION(); -- 查詢版本號
    SELECT 100*3-1 AS 計算結果; -- 表示式
    
    -- 學員考試成績集體提分一分檢視
    SELECT studentno,StudentResult+1 AS '提分後' FROM result;
    
  • 避免SQL返回結果中包含 ' . ' , ' * ' 和括號等干擾開發語言程式.

4.4、where條件語句

作用:用於檢索資料表中符合條件的記錄

搜尋條件可由一個或多個邏輯表示式組成 , 結果一般為真或假.

邏輯操作符

測試

-- 滿足條件的查詢(where)
SELECT Studentno,StudentResult FROM result;

-- 查詢考試成績在95-100之間的
SELECT Studentno,StudentResult
FROM result
WHERE StudentResult>=95 AND StudentResult<=100;

-- AND也可以寫成 &&
SELECT Studentno,StudentResult
FROM result
WHERE StudentResult>=95 && StudentResult<=100;

-- 模糊查詢(對應的詞:精確查詢)
SELECT Studentno,StudentResult
FROM result
WHERE StudentResult BETWEEN 95 AND 100;

-- 除了1000號同學,要其他同學的成績
SELECT studentno,studentresult
FROM result
WHERE studentno!=1000;

-- 使用NOT
SELECT studentno,studentresult
FROM result
WHERE NOT studentno=1000;

模糊查詢 :比較操作符

注意:

  • 數值資料型別的記錄之間才能進行算術運算 ;
  • 相同資料型別的資料之間才能進行比較 ;

測試

-- 模糊查詢 between and \ like \ in \ null

-- =============================================
-- LIKE
-- =============================================
-- 查詢姓劉的同學的學號及姓名
-- like結合使用的萬用字元 : % (代表0到任意個字元) _ (一個字元)
SELECT studentno,studentname FROM student
WHERE studentname LIKE '劉%';

-- 查詢姓劉的同學,後面只有一個字的
SELECT studentno,studentname FROM student
WHERE studentname LIKE '劉_';

-- 查詢姓劉的同學,後面只有兩個字的
SELECT studentno,studentname FROM student
WHERE studentname LIKE '劉__';

-- 查詢姓名中含有 嘉 字的
SELECT studentno,studentname FROM student
WHERE studentname LIKE '%嘉%';

-- 查詢姓名中含有特殊字元的需要使用轉義符號 '\'
-- 自定義轉義符關鍵字: ESCAPE ':'

-- =============================================
-- IN
-- =============================================
-- 查詢學號為1000,1001,1002的學生姓名
SELECT studentno,studentname FROM student
WHERE studentno IN (1000,1001,1002);

-- 查詢地址在北京,南京,河南洛陽的學生
SELECT studentno,studentname,address FROM student
WHERE address IN ('北京','南京','河南洛陽');

-- =============================================
-- NULL 空
-- =============================================
-- 查詢出生日期沒有填寫的同學
-- 不能直接寫=NULL , 這是代表錯誤的 , 用 is null
SELECT studentname FROM student
WHERE BornDate IS NULL;

-- 查詢出生日期填寫的同學
SELECT studentname FROM student
WHERE BornDate IS NOT NULL;

-- 查詢沒有寫家庭住址的同學(空字串不等於null)
SELECT studentname FROM student
WHERE Address='' OR Address IS NULL;

4.5、連線查詢

我們已經學會了如何在一張表中讀取資料,這是相對簡單的,但是在真正的應用中經常需要從多個數據表中讀取資料。

你可以在 SELECT, UPDATE 和 DELETE 語句中使用 Mysql 的 JOIN 來聯合多表查詢。

JOIN 按照功能大致分為如下三類:

  • INNER JOIN(內連線,或等值連線):獲取兩個表中欄位匹配關係的記錄。
  • LEFT JOIN(左連線):獲取左表所有記錄,即使右表沒有對應匹配的記錄。
  • RIGHT JOIN(右連線): 與 LEFT JOIN 相反,用於獲取右表所有記錄,即使左表沒有對應匹配的記錄。
mysql> use RUNOOB;
Database changed
mysql> SELECT * FROM tcount_tbl;
+---------------+--------------+
| runoob_author | runoob_count |
+---------------+--------------+
| 菜鳥教程       | 10           |
| RUNOOB.COM    | 20           |
| Google        | 22           |
+---------------+--------------+
3 rows in set (0.01 sec)
 
mysql> SELECT * from runoob_tbl;
+-----------+---------------+---------------+-----------------+
| runoob_id | runoob_title  | runoob_author | submission_date |
+-----------+---------------+---------------+-----------------+
| 1         | 學習 PHP       | 菜鳥教程       | 2017-04-12      |
| 2         | 學習 MySQL     | 菜鳥教程       | 2017-04-12      |
| 3         | 學習 Java      | RUNOOB.COM    | 2015-05-01      |
| 4         | 學習 Python    | RUNOOB.COM    | 2016-03-06      |
| 5         | 學習 C         | FK            | 2017-04-05      |
+-----------+---------------+---------------+-----------------+
5 rows in set (0.01 sec)

接下來我們就使用MySQL的INNER JOIN(也可以省略 INNER 使用 JOIN,效果一樣)來連線以上兩張表來讀取

runoob_tbl表中所有runoob_author欄位在tcount_tbl表對應的runoob_count欄位值:

4.5.1、INNER JOIN:

mysql> SELECT a.runoob_id,a.runoob_author, b.runoob_count 
FROM runoob_tbl a INNER JOIN tcount_tbl b 
ON a.runoob_author = b.runoob_author;

+-------------+-----------------+----------------+
| a.runoob_id | a.runoob_author | b.runoob_count |
+-------------+-----------------+----------------+
| 1           | 菜鳥教程         | 10             |
| 2           | 菜鳥教程         | 10             |
| 3           | RUNOOB.COM      | 20             |
| 4           | RUNOOB.COM      | 20             |
+-------------+-----------------+----------------+
4 rows in set (0.00 sec)

where

mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count 
FROM runoob_tbl a, tcount_tbl b 
WHERE a.runoob_author = b.runoob_author;
+-------------+-----------------+----------------+
| a.runoob_id | a.runoob_author | b.runoob_count |
+-------------+-----------------+----------------+
| 1           | 菜鳥教程         | 10             |
| 2           | 菜鳥教程         | 10             |
| 3           | RUNOOB.COM      | 20             |
| 4           | RUNOOB.COM      | 20             |
+-------------+-----------------+----------------+
4 rows in set (0.01 sec)

4.5.2、MySQL LEFT JOIN

MySQL left join 與 join 有所不同。 MySQL LEFT JOIN 會讀取左邊資料表的全部資料,即便右邊表無對應資料。

嘗試以下例項,以 runoob_tbl 為左表,tcount_tbl 為右表,理解 MySQL LEFT JOIN 的應用:

LEFT JOIN

mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count 
FROM runoob_tbl a LEFT JOIN tcount_tbl b 
ON a.runoob_author = b.runoob_author;
+-------------+-----------------+----------------+
| a.runoob_id | a.runoob_author | b.runoob_count |
+-------------+-----------------+----------------+
| 1           | 菜鳥教程         | 10             |
| 2           | 菜鳥教程         | 10             |
| 3           | RUNOOB.COM      | 20             |
| 4           | RUNOOB.COM      | 20             |
| 5           | FK              | NULL           |
+-------------+-----------------+----------------+
5 rows in set (0.01 sec)

以上例項中使用了 LEFT JOIN,該語句會讀取左邊的資料表 runoob_tbl 的所有選取的欄位資料,即便在右側表 tcount_tbl中 沒有對應的 runoob_author 欄位值。

4.6、排序和分頁

我們知道從 MySQL 表中使用 SQL SELECT 語句來讀取資料。

如果我們需要對讀取的資料進行排序,我們就可以使用 MySQL 的 ORDER BY 子句來設定你想按哪個欄位哪種方式來進行排序,再返回搜尋結果。

4.6.1、排序語法

以下是 SQL SELECT 語句使用 ORDER BY 子句將查詢資料排序後再返回資料:

SELECT field1, field2,...fieldN FROM table_name1, table_name2...
ORDER BY field1 [ASC [DESC][預設 ASC]], [field2...] [ASC [DESC][預設 ASC]]
  • 你可以使用任何欄位來作為排序的條件,從而返回排序後的查詢結果。
  • 你可以設定多個欄位來排序。
  • 你可以使用 ASC 或 DESC 關鍵字來設定查詢結果是按升序或降序排列。 預設情況下,它是按升序排列。
  • 你可以新增 WHERE...LIKE 子句來設定條件。

以下將在 SQL SELECT 語句中使用 ORDER BY 子句來讀取MySQL 資料表 runoob_tbl 中的資料:

嘗試以下例項,結果將按升序及降序排列。

mysql> use RUNOOB;
Database changed
mysql> SELECT * from runoob_tbl ORDER BY submission_date ASC;
+-----------+---------------+---------------+-----------------+
| runoob_id | runoob_title  | runoob_author | submission_date |
+-----------+---------------+---------------+-----------------+
| 3         | 學習 Java   | RUNOOB.COM    | 2015-05-01      |
| 4         | 學習 Python | RUNOOB.COM    | 2016-03-06      |
| 1         | 學習 PHP    | 菜鳥教程  | 2017-04-12      |
| 2         | 學習 MySQL  | 菜鳥教程  | 2017-04-12      |
+-----------+---------------+---------------+-----------------+
4 rows in set (0.01 sec)
 
mysql> SELECT * from runoob_tbl ORDER BY submission_date DESC;
+-----------+---------------+---------------+-----------------+
| runoob_id | runoob_title  | runoob_author | submission_date |
+-----------+---------------+---------------+-----------------+
| 1         | 學習 PHP    | 菜鳥教程  | 2017-04-12      |
| 2         | 學習 MySQL  | 菜鳥教程  | 2017-04-12      |
| 4         | 學習 Python | RUNOOB.COM    | 2016-03-06      |
| 3         | 學習 Java   | RUNOOB.COM    | 2015-05-01      |
+-----------+---------------+---------------+-----------------+
4 rows in set (0.01 sec)

4.6.2、分頁語法

-- 每頁顯示5條資料
SELECT s.studentno,studentname,subjectname,StudentResult
FROM student s
INNER JOIN result r
ON r.studentno = s.studentno
INNER JOIN `subject` sub
ON r.subjectno = sub.subjectno
WHERE subjectname='資料庫結構-1'
ORDER BY StudentResult DESC , studentno
LIMIT 0,5

-- 查詢 JAVA第一學年 課程成績前10名並且分數大於80的學生資訊(學號,姓名,課程名,分數)
SELECT s.studentno,studentname,subjectname,StudentResult
FROM student s
INNER JOIN result r
ON r.studentno = s.studentno
INNER JOIN `subject` sub
ON r.subjectno = sub.subjectno
WHERE subjectname='JAVA第一學年'
ORDER BY StudentResult DESC
LIMIT 0,10

4.7、分組

mysql> set names utf8;
mysql> SELECT * FROM employee_tbl;
+----+--------+---------------------+--------+
| id | name   | date                | singin |
+----+--------+---------------------+--------+
|  1 | 小明 | 2016-04-22 15:25:33 |      1 |
|  2 | 小王 | 2016-04-20 15:25:47 |      3 |
|  3 | 小麗 | 2016-04-19 15:26:02 |      2 |
|  4 | 小王 | 2016-04-07 15:26:14 |      4 |
|  5 | 小明 | 2016-04-11 15:26:40 |      4 |
|  6 | 小明 | 2016-04-04 15:26:54 |      2 |
+----+--------+---------------------+--------+
6 rows in set (0.00 sec)

#接下來我們使用 GROUP BY 語句 將資料表按名字進行分組,並統計每個人有多少條記錄:
mysql> SELECT name, COUNT(*) FROM   employee_tbl GROUP BY name;
+--------+----------+
| name   | COUNT(*) |
+--------+----------+
| 小麗 |        1 |
| 小明 |        3 |
| 小王 |        2 |
+--------+----------+
3 rows in set (0.01 sec)

4.7.1、使用 WITH ROLLUP

WITH ROLLUP 可以實現在分組統計資料基礎上再進行相同的統計(SUM,AVG,COUNT…)。

例如我們將以上的資料表按名字進行分組,再統計每個人登入的次數:

mysql> SELECT name, SUM(singin) as singin_count FROM  employee_tbl GROUP BY name WITH ROLLUP;
+--------+--------------+
| name   | singin_count |
+--------+--------------+
| 小麗 |            2 |
| 小明 |            7 |
| 小王 |            7 |
| NULL   |           16 |
+--------+--------------+
4 rows in set (0.00 sec)

4.7.2、coalesce

我們可以使用 coalesce 來設定一個可以取代 NUll 的名稱,coalesce 語法:

select coalesce(a,b,c);

引數說明:如果a==null,則選擇b;如果b==null,則選擇c;如果a!=null,則選擇a;如果a b c 都為null ,則返回為null(沒意義)。

以下例項中如果名字為空我們使用總數代替:

mysql> SELECT coalesce(name, '總數'), SUM(singin) as singin_count FROM  employee_tbl GROUP BY name WITH ROLLUP;
+--------------------------+--------------+
| coalesce(name, '總數') | singin_count |
+--------------------------+--------------+
| 小麗                   |            2 |
| 小明                   |            7 |
| 小王                   |            7 |
| 總數                   |           16 |
+--------------------------+--------------+
4 rows in set (0.01 sec)

4.8、子查詢

4.8.1、什麼是子查詢?

在查詢語句中的WHERE條件子句中,又嵌套了另一個查詢語句
巢狀查詢可由多個子查詢組成,求解的方式是由裡及外;
子查詢返回的結果一般都是集合,故而建議使用IN關鍵字;

-- 查詢 資料庫結構-1 的所有考試結果(學號,科目編號,成績),並且成績降序排列
-- 方法一:使用連線查詢
SELECT studentno,r.subjectno,StudentResult
FROM result r
INNER JOIN `subject` sub
ON r.`SubjectNo`=sub.`SubjectNo`
WHERE subjectname = '資料庫結構-1'
ORDER BY studentresult DESC;

-- 方法二:使用子查詢(執行順序:由裡及外)
SELECT studentno,subjectno,StudentResult
FROM result
WHERE subjectno=(
   SELECT subjectno FROM `subject`
   WHERE subjectname = '資料庫結構-1'
)
ORDER BY studentresult DESC;

-- 查詢課程為 高等數學-2 且分數不小於80分的學生的學號和姓名
-- 方法一:使用連線查詢
SELECT s.studentno,studentname
FROM student s
INNER JOIN result r
ON s.`StudentNo` = r.`StudentNo`
INNER JOIN `subject` sub
ON sub.`SubjectNo` = r.`SubjectNo`
WHERE subjectname = '高等數學-2' AND StudentResult>=80

-- 方法二:使用連線查詢+子查詢
-- 分數不小於80分的學生的學號和姓名
SELECT r.studentno,studentname FROM student s
INNER JOIN result r ON s.`StudentNo`=r.`StudentNo`
WHERE StudentResult>=80

-- 在上面SQL基礎上,新增需求:課程為 高等數學-2
SELECT r.studentno,studentname FROM student s
INNER JOIN result r ON s.`StudentNo`=r.`StudentNo`
WHERE StudentResult>=80 AND subjectno=(
   SELECT subjectno FROM `subject`
   WHERE subjectname = '高等數學-2'
)

-- 方法三:使用子查詢
-- 分步寫簡單sql語句,然後將其巢狀起來
SELECT studentno,studentname FROM student WHERE studentno IN(
   SELECT studentno FROM result WHERE StudentResult>=80 AND subjectno=(
       SELECT subjectno FROM `subject` WHERE subjectname = '高等數學-2'
  )
)

4.9、unino查詢

MySQL UNION 操作符用於連線兩個以上的 SELECT 語句的結果組合到一個結果集合中。多個 SELECT 語句會刪除重複的資料。

MySQL UNION 操作符語法格式:

SELECT expression1, expression2, ... expression_n
FROM tables
[WHERE conditions]
UNION [ALL | DISTINCT]
SELECT expression1, expression2, ... expression_n
FROM tables
[WHERE conditions];
  • expression1, expression2, ... expression_n: 要檢索的列。
  • tables: 要檢索的資料表。
  • WHERE conditions: 可選, 檢索條件。
  • DISTINCT: 可選,刪除結果集中重複的資料。預設情況下 UNION 操作符已經刪除了重複資料,所以 DISTINCT 修飾符對結果沒啥影響。
  • ALL: 可選,返回所有結果集,包含重複資料。
mysql> SELECT * FROM Websites;
+----+--------------+---------------------------+-------+---------+
| id | name         | url                       | alexa | country |
+----+--------------+---------------------------+-------+---------+
| 1  | Google       | https://www.google.cm/    | 1     | USA     |
| 2  | 淘寶          | https://www.taobao.com/   | 13    | CN      |
| 3  | 菜鳥教程      | http://www.runoob.com/    | 4689  | CN      |
| 4  | 微博          | http://weibo.com/         | 20    | CN      |
| 5  | Facebook     | https://www.facebook.com/ | 3     | USA     |
| 7  | stackoverflow | http://stackoverflow.com/ |   0 | IND     |
+----+---------------+---------------------------+-------+---------+

mysql> SELECT * FROM apps;
+----+------------+-------------------------+---------+
| id | app_name   | url                     | country |
+----+------------+-------------------------+---------+
|  1 | QQ APP     | http://im.qq.com/       | CN      |
|  2 | 微博 APP | http://weibo.com/       | CN      |
|  3 | 淘寶 APP | https://www.taobao.com/ | CN      |
+----+------------+-------------------------+---------+
3 rows in set (0.00 sec)

4.9.1、例項

下面的 SQL 語句從 "Websites" 和 "apps" 表中選取所有不同的country(只有不同的值):

執行SQL 輸出結果如下:

註釋:UNION 不能用於列出兩個表中所有的country。如果一些網站和APP來自同一個國家,每個國家只會列出一次。UNION 只會選取不同的

4.9.2、SQL UNION ALL 例項

下面的 SQL 語句使用 UNION ALL 從 "Websites" 和 "apps" 表中選取所有的country值。請使用 UNION ALL 來選取重複的值!

4.9.3、帶有 WHERE 的 SQL UNION ALL

下面的 SQL 語句使用 UNION ALL 從 "Websites" 和 "apps" 表中選取所有的中國(CN)的資料(也有重複的值):

執行SQL 輸出結果如下:

五、mysql函式

5.1、常用函式

資料函式

 SELECT ABS(-8);  /*絕對值*/
 SELECT CEILING(9.4); /*向上取整*/
 SELECT FLOOR(9.4);   /*向下取整*/
 SELECT RAND();  /*隨機數,返回一個0-1之間的隨機數*/
 SELECT SIGN(0); /*符號函式: 負數返回-1,正數返回1,0返回0*/

字串函式

 SELECT CHAR_LENGTH('狂神說堅持就能成功'); /*返回字串包含的字元數*/
 SELECT CONCAT('我','愛','程式');  /*合併字串,引數可以有多個*/
 SELECT INSERT('我愛程式設計helloworld',1,2,'超級熱愛');  /*替換字串,從某個位置開始替換某個長度*/
 SELECT LOWER('KuangShen'); /*小寫*/
 SELECT UPPER('KuangShen'); /*大寫*/
 SELECT LEFT('hello,world',5);   /*從左邊擷取*/
 SELECT RIGHT('hello,world',5);  /*從右邊擷取*/
 SELECT REPLACE('狂神說堅持就能成功','堅持','努力');  /*替換字串*/
 SELECT SUBSTR('狂神說堅持就能成功',4,6); /*擷取字串,開始和長度*/
 SELECT REVERSE('狂神說堅持就能成功'); /*反轉
 
 -- 查詢姓周的同學,改成鄒
 SELECT REPLACE(studentname,'周','鄒') AS 新名字
 FROM student WHERE studentname LIKE '周%';

日期和時間函式

 SELECT CURRENT_DATE();   /*獲取當前日期*/
 SELECT CURDATE();   /*獲取當前日期*/
 SELECT NOW();   /*獲取當前日期和時間*/
 SELECT LOCALTIME();   /*獲取當前日期和時間*/
 SELECT SYSDATE();   /*獲取當前日期和時間*/
 
 -- 獲取年月日,時分秒
 SELECT YEAR(NOW());
 SELECT MONTH(NOW());
 SELECT DAY(NOW());
 SELECT HOUR(NOW());
 SELECT MINUTE(NOW());
 SELECT SECOND(NOW());

系統資訊函式

 SELECT VERSION();  /*版本*/
 SELECT USER();     /*使用者*/ 

5.2、聚合函式

函式名稱 描述
COUNT() 返回滿足Select條件的記錄總和數,如 select count(*) 【不建議使用 *,效率低】
SUM() 返回數字欄位或表示式列作統計,返回一列的總和。
AVG() 通常為數值欄位或表達列作統計,返回一列的平均值
MAX() 可以為數值欄位,字元欄位或表示式列作統計,返回最大的值。
MIN() 可以為數值欄位,字元欄位或表示式列作統計,返回最小的值。
 -- 聚合函式
 /*COUNT:非空的*/
 SELECT COUNT(studentname) FROM student;
 SELECT COUNT(*) FROM student;
 SELECT COUNT(1) FROM student;  /*推薦*/
 
 -- 從含義上講,count(1) 與 count(*) 都表示對全部資料行的查詢。
 -- count(欄位) 會統計該欄位在表中出現的次數,忽略欄位為null 的情況。即不統計欄位為null 的記錄。
 -- count(*) 包括了所有的列,相當於行數,在統計結果的時候,包含欄位為null 的記錄;
 -- count(1) 用1代表程式碼行,在統計結果的時候,包含欄位為null 的記錄 。
-- 查詢不同課程的平均分,最高分,最低分
 -- 前提:根據不同的課程進行分組
 
 SELECT subjectname,AVG(studentresult) AS 平均分,MAX(StudentResult) AS 最高分,MIN(StudentResult) AS 最低分
 FROM result AS r
 INNER JOIN `subject` AS s
 ON r.subjectno = s.subjectno
 GROUP BY r.subjectno
 HAVING 平均分>80;
 
 /*
 where寫在group by前面.
 要是放在分組後面的篩選
 要使用HAVING..
 因為having是從前面篩選的欄位再篩選,而where是從資料表中的>欄位直接進行的篩選的
 */

六、事務和索引

6.1、事務

  • 事務就是將一組SQL語句放在同一批次內去執行
  • 如果一個SQL語句出錯,則該批次內的所有SQL都將被取消執行
  • MySQL事務處理只支援InnoDB和BDB資料表型別

6.2、事務的ACID原則

原子性(Atomic)

  • 整個事務中的所有操作,要麼全部完成,要麼全部不完成,不可能停滯在中間某個環節。事務在執行過程中發生錯誤,會被回滾(ROLLBACK)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。

一致性(Consist)

  • 一個事務可以封裝狀態改變(除非它是一個只讀的)。事務必須始終保持系統處於一致的狀態,不管在任何給定的時間併發事務有多少。也就是說:如果事務是併發多個,系統也必須如同序列事務一樣操作。其主要特徵是保護性和不變性(Preserving an Invariant),以轉賬案例為例,假設有五個賬戶,每個賬戶餘額是100元,那麼五個賬戶總額是500元,如果在這個5個賬戶之間同時發生多個轉賬,無論併發多少個,比如在A與B賬戶之間轉賬5元,在C與D賬戶之間轉賬10元,在B與E之間轉賬15元,五個賬戶總額也應該還是500元,這就是保護性和不變性。

隔離性(Isolated)

  • 隔離狀態執行事務,使它們好像是系統在給定時間內執行的唯一操作。如果有兩個事務,執行在相同的時間內,執行相同的功能,事務的隔離性將確保每一事務在系統中認為只有該事務在使用系統。這種屬性有時稱為序列化,為了防止事務操作間的混淆,必須序列化或序列化請求,使得在同一時間僅有一個請求用於同一資料。

永續性(Durable)

  • 在事務完成以後,該事務對資料庫所作的更改便持久的儲存在資料庫之中,並不會被回滾。
-- 使用set語句來改變自動提交模式
SET autocommit = 0;   /*關閉*/
SET autocommit = 1;   /*開啟*/

-- 注意:
--- 1.MySQL中預設是自動提交
--- 2.使用事務時應先關閉自動提交

-- 開始一個事務,標記事務的起始點
START TRANSACTION  

-- 提交一個事務給資料庫
COMMIT

-- 將事務回滾,資料回到本次事務的初始狀態
ROLLBACK

-- 還原MySQL資料庫的自動提交
SET autocommit =1;

-- 儲存點
SAVEPOINT 儲存點名稱 -- 設定一個事務儲存點
ROLLBACK TO SAVEPOINT 儲存點名稱 -- 回滾到儲存點
RELEASE SAVEPOINT 儲存點名稱 -- 刪除儲存點

test

mysql> use RUNOOB;
Database changed
mysql> CREATE TABLE runoob_transaction_test( id int(5)) engine=innodb;  # 建立資料表
Query OK, 0 rows affected (0.04 sec)
 
mysql> select * from runoob_transaction_test;
Empty set (0.01 sec)
 
mysql> begin;  # 開始事務
Query OK, 0 rows affected (0.00 sec)
 
mysql> insert into runoob_transaction_test value(5);
Query OK, 1 rows affected (0.01 sec)
 
mysql> insert into runoob_transaction_test value(6);
Query OK, 1 rows affected (0.00 sec)
 
mysql> commit; # 提交事務
Query OK, 0 rows affected (0.01 sec)
 
mysql>  select * from runoob_transaction_test;
+------+
| id   |
+------+
| 5    |
| 6    |
+------+
2 rows in set (0.01 sec)
 
mysql> begin;    # 開始事務
Query OK, 0 rows affected (0.00 sec)
 
mysql>  insert into runoob_transaction_test values(7);
Query OK, 1 rows affected (0.00 sec)
 
mysql> rollback;   # 回滾
Query OK, 0 rows affected (0.00 sec)
 
mysql>   select * from runoob_transaction_test;   # 因為回滾所以資料沒有插入
+------+
| id   |
+------+
| 5    |
| 6    |
+------+
2 rows in set (0.01 sec)
 
mysql>

6.3、索引

6.3.1、索引的作用

  • 提高查詢速度
  • 確保資料的唯一性
  • 可以加速表和表之間的連線 , 實現表與表之間的參照完整性
  • 使用分組和排序子句進行資料檢索時 , 可以顯著減少分組和排序的時間
  • 全文檢索欄位進行搜尋優化.

6.3.2、普通索引

6.3.2.1、建立索引

這是最基本的索引,它沒有任何限制。它有以下幾種建立方式:

CREATE INDEX indexName ON table_name (column_name)

如果是CHAR,VARCHAR型別,length可以小於欄位實際長度;如果是BLOB和TEXT型別,必須指定 length。

6.3.2.2、修改表結構(新增索引)

ALTER table tableName ADD INDEX indexName(columnName)

6.3.2.3、建立表的時候直接指定

CREATE TABLE mytable(  
 
ID INT NOT NULL,   
 
username VARCHAR(16) NOT NULL,  
 
INDEX (username(length))  
 
);  

6.3.2.4、刪除索引的語法

DROP INDEX [indexName] ON mytable; 

6.3.3、唯一索引

它與前面的普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。它有以下幾種建立方式:

6.3.3.1、建立索引

CREATE UNIQUE INDEX indexName ON mytable(username(length)) 

6.3.3.2、修改表結構

ALTER table mytable ADD UNIQUE [indexName] (username(length))

6.3.3.3、建立表的時候直接指定

CREATE TABLE mytable(  
 
ID INT NOT NULL,   
 
username VARCHAR(16) NOT NULL,  
 
UNIQUE (username(length))  
 
);  

6.3.4、使用ALTER 命令新增和刪除索引

有四種方式來新增資料表的索引:

  • ALTER TABLE tbl_name ADD PRIMARY KEY (column_list):

    該語句新增一個主鍵,這意味著索引值必須是唯一的,且不能為NULL。

  • ALTER TABLE tbl_name ADD UNIQUE index_name (column_list): 這條語句建立索引的值必須是唯一的(除了NULL外,NULL可能會出現多次)。

  • ALTER TABLE tbl_name ADD INDEX index_name (column_list): 新增普通索引,索引值可出現多次。

  • ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list):該語句指定了索引為 FULLTEXT ,用於全文索引。

以下例項為在表中新增索引。

mysql> ALTER TABLE testalter_tbl ADD INDEX (c);

你還可以在 ALTER 命令中使用 DROP 子句來刪除索引。嘗試以下例項刪除索引:

mysql> ALTER TABLE testalter_tbl DROP INDEX c;

6.3.5、使用 ALTER 命令新增和刪除主鍵

主鍵作用於列上(可以一個列或多個列聯合主鍵),新增主鍵索引時,你需要確保該主鍵預設不為空(NOT NULL)。例項如下:

mysql> ALTER TABLE testalter_tbl MODIFY i INT NOT NULL;
mysql> ALTER TABLE testalter_tbl ADD PRIMARY KEY (i);

你也可以使用 ALTER 命令刪除主鍵:

mysql> ALTER TABLE testalter_tbl DROP PRIMARY KEY;

刪除主鍵時只需指定PRIMARY KEY,但在刪除索引時,你必須知道索引名。


6.3.6、顯示索引資訊

你可以使用 SHOW INDEX 命令來列出表中的相關的索引資訊。可以通過新增 \G 來格式化輸出資訊。

嘗試以下例項:

mysql> SHOW INDEX FROM table_name; 

七、設計資料庫

7.1、三大正規化

7.1.1、第一正規化 (1st NF)

第一正規化的目標是確保每列的原子性,如果每列都是不可再分的最小資料單元,則滿足第一正規化

7.1.2、第二正規化(2nd NF)

第二正規化(2NF)是在第一正規化(1NF)的基礎上建立起來的,即滿足第二正規化(2NF)必須先滿足第一正規化(1NF)。

第二正規化要求每個表只描述一件事情

7.1.3、第三正規化(3rd NF)

如果一個關係滿足第二正規化,並且除了主鍵以外的其他列都不傳遞依賴於主鍵列,則滿足第三正規化.

第三正規化需要確保資料表中的每一列資料都和主鍵直接相關,而不能間接相關。

7.1.4、規範化和效能的關係

為滿足某種商業目標 , 資料庫效能比規範化資料庫更重要

在資料規範化的同時 , 要綜合考慮資料庫的效能

通過在給定的表中新增額外的欄位,以大量減少需要從中搜索資訊所需的時間

通過在給定的表中插入計算列,以方便查詢

八、許可權

使用者資訊表:mysql.user

1、重新整理許可權

FLUSH PRIVILEGES

2、使用者

 CREATE USER kuangshen IDENTIFIED BY '123456'
CREATE USER 使用者名稱 IDENTIFIED BY [PASSWORD] 密碼(字串)
 \- 必須擁有mysql資料庫的全域性CREATE USER許可權,或擁有INSERT許可權。
 \- 只能建立使用者,不能賦予許可權。
 \- 使用者名稱,注意引號:如 'user_name'@'192.168.1.1'
 \- 密碼也需引號,純數字密碼也要加引號
 \- 要在純文字中指定密碼,需忽略PASSWORD關鍵詞。要把密碼指定為由PASSWORD()函式返回的混編值,需包含關鍵字PASSWORD

-- 重新命名使用者 RENAME USER kuangshen TO kuangshen2
RENAME USER old_user TO new_user

-- 設定密碼
SET PASSWORD = PASSWORD('密碼')   -- 為當前使用者設定密碼
SET PASSWORD FOR 使用者名稱 = PASSWORD('密碼')   -- 為指定使用者設定密碼

-- 刪除使用者 DROP USER kuangshen2
DROP USER 使用者名稱

-- 分配許可權/新增使用者
GRANT 許可權列表 ON 表名 TO 使用者名稱 [IDENTIFIED BY [PASSWORD] 'password']
 \- all privileges 表示所有許可權
 \- *.* 表示所有庫的所有表
 \- 庫名.表名 表示某庫下面的某表

3、檢視許可權



-- 檢視許可權  SHOW GRANTS FOR root@localhost;
SHOW GRANTS FOR 使用者名稱
  -- 檢視當前使用者許可權
 SHOW GRANTS; 或 SHOW GRANTS FOR CURRENT_USER; 或 SHOW GRANTS FOR CURRENT_USER();


4、撤消許可權

REVOKE 許可權列表 ON 表名 FROM 使用者名稱
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 使用者名稱   -- 撤銷所有許可權