說說MySQL權限

本文首發於我的微信公衆號《andyqian》,期待你的關注~

前言

  今天繼續MySQL系列文章,講講MySQL權限相關的內容。咱們都知道,在寫系統的時候,都會有權限相關的服務,以達到權限控制的目的。以最簡單的權限菜單爲例: 管理員擁有最大權限,能夠查看系統下全部菜單。操做員只擁有部分菜單權限。一樣的,在MySQL數據庫中也有相應的權限管理。例如:數據庫鏈接權限,新增,修改,查詢權限等等。下面咱們就一一揭曉MySQL權限的真實面貌。mysql

受權方式

  在講 MySQL 權限以前,咱們不得不先熟悉下MySQL中常見的兩種受權方式。 sql

姑且稱爲:受權法改表法 吧。數據庫

1. 受權法 後端

標準語法以下:服務器

grant all on db_name.table_name to 'user_name'@'host_name';

其中:微信

  1. grant 爲MySQL關鍵字。
  2. all 表示全部權限,也能夠授予部分權限,如select,insert,update,create,drop等等。
  3. db_name 表示數據庫名。其中:* 表示該數據庫實例中的全部數據庫。
  4. table_name 爲db_name數據庫中的表名。其中:* 表示db_name數據庫中的全部表。
  5. user_name 表示數據庫服務器中已經存在的用戶名。
  6. host_name 表示容許鏈接的主機。(localhost / 127.0.0.1 表示本機,% 表示任何主機,也能夠用域名錶示。)

以設置root用戶容許遠程鏈接爲例:數據結構

給 root 用戶設置該實例上全部數據庫的全部權限,且容許其經過任意主機鏈接該實例。則能夠用下述語句表示:數據庫設計

grant all on *.* to 'root'@'%';

2. 改表法 函數

你必定很好奇,MySQL是如何判斷用戶是否有某數據庫的權限?是否有某表的權限?
其實呀,在MySQL中是有特定數據結構來存儲這部分信息的。咱們能夠按照下述步驟來找到它,甚至能夠來修改它,以達到修改權限的目的。優化

  1. 首先,咱們登陸到MySQL服務器。
  2. 進入MySQL服務器中自帶的 mysql 數據庫中。
  3. 找到 mysql 數據中的 user 表,修改對應用戶的信息便可。

以設置root用戶容許遠程鏈接爲例:

use mysql;

update user set host="%" where user="root";

flush privileges;

執行以上語句後,咱們能夠經過如下語檢查是否生效:

show grants for 'root'@'%';

值得注意的是:

爲了權限驗證時的高效性。MySQL在服務啓動時,就會將權限數據加載在內存中。所以,受權法改表法 會有如下細微差別:

  1. 咱們在使用 grant 命令時,即受權法。其會自動通知MySQL服務器從新加載一次權限數據。以達到即時生效的效果。
  2. 但當咱們使用改表法時。是沒有通知從新加載權限數據的。所以會致使其不會即時生效。直至服務重啓後生效。服務重啓,特別是生產環境,那幾乎是災難性的。好在MySQL爲咱們提供了手動通知的命令。即:flush privilege命令。

例如:

mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)

鏈接權限

   經過上面的介紹,咱們如今應該已經知道了MySQL中常見的受權方式。如今就從實際角度來用用。咱們都知道在MySQL中默認是不容許root用戶遠程登陸的。咱們經過如下命令修改便可:

grant all on *.* to 'root'@'%';
  1. 若是想設置成經過指定的IP登陸,則能夠將 %替換成特定的IP便可。
  2. 若是想設置成經過指定的IP段登陸,便可以將%替換成192.168.1.%便可。

  (其中: 將192.168.1修改爲你想要IP段便可!)

表權限

  知道了鏈接權限,咱們再來講說表權限。以幾種常見的場景爲例:

  1. 設置用戶 andyqian 在 customer 數據庫中的 t_user 表的全部權限。
grant all on customer.t_user to 'andyqian'@'%';
  1. 設置用戶 andyqian 在 customer 數據庫中 t_user 表的只讀權限。
grant select on customer.t_user to 'andyqian'@'%';

當僅僅只設置只讀權限時,執行update命令會有以下錯誤信息:

mysql> update t_user set name="sansan",updated_at=now() where oid=1;
ERROR 1142 (42000): UPDATE command denied to user 'andyqian'@'localhost' for table 't_user
  1. 設置用戶andyqiancustomer 數據庫中 t_user 表的可讀可寫權限。
grant select,insert,update on customer.t_user to 'andyqian'@'%';

當僅僅只設置可讀,可寫,可修改權限時,執行drop命令會有以下錯誤信息:

mysql> drop table t_user;
ERROR 1142 (42000): DROP command denied to user 'andyqian'@'%' for table 't_user

列權限

  在某些場景下,咱們須要將權限精確到列上。咱們也可使用 grant命令來實現。

  1. 設置指定列的insert權限時:
grant insert(created_at,updated_at) on customer.t_user to 'andyqian'@'localhost';
  1. insert包括未設置權限的列時,則會有如下錯誤信息:
mysql> insert into t_user(name,created_at,updated_at)values('name',now(),now()); 
ERROR 1143 (42000): INSERT command denied to user 'andyqian'@'localhost' for column 'name' in table 't_user'

撤銷權限

  有添加權限,確定也少不了撤銷權限。其語法與grant基本一致。僅僅只是關鍵字不一樣

  1. 撤銷 用戶 andyqiancustomer數據庫中的t_usercreated_atupdated_at字段的新增權限。
revoke insert(created_at,updated_at) on customer.t_user from 'andyqian'@'localhost';

查看用戶權限

  上面說到,若是用戶執行沒有權限的命令時。則會顯示錯誤信息。爲了不這種狀況發生。咱們能夠先經過如下命令來查看當前用戶擁有的權限。

命令: show grants for 'user_name'@'localhost'

其可使用current_user()函數來表示當前登陸用戶。

例如:

mysql> show grants for current_user();
+-----------------------------------------------------------------------+
| Grants for andyqian@localhost                                         |
+-----------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'andyqian'@'localhost'                          |
| GRANT SELECT, INSERT ON `customer`.`t_user` TO 'andyqian'@'localhost' |
+-----------------------------------------------------------------------+
2 rows in set (0.00 sec)
  1. 其中第一句: USAGE 表示沒有特殊權限的意思。使用 show grants命令查看時,一般會一塊兒顯示在結果列表中。
  2. 第二句則表示用戶 andyqian 在customer數據庫中的t_user表中有select,insert 權限。

最後

  有不少童鞋會以爲:數據庫管理,SQL優化,索引創建等等,都是DBA的事情。開發人員不須要了解。我認爲這種認知是錯誤的,數據庫設計自己就是後端工程師工做職責的一部分。DBA 應該是設計的審覈者,而不是創建者。


相關閱讀:

寫會MySQL索引

讀懂MySQL執行計劃

<center>公衆號</center>

相關文章
相關標籤/搜索