2011-06-09 100 views
20

我一直無法找到一個合理的解決方案,實現以下所有權限到數據庫:MySQL授權,除了一個表

我希望有,有一個數據庫上的所有權限的用戶(或與一系列數據庫相同的模式),,除了的一個表,他們將只有SELECT權限。

本質上我想讓用戶對數據庫擁有免費統治權,但不能更新特定的表。

到目前爲止,我已經試過了,沒有用:(DB_NAME *)

  • 授予該數據庫上的所有特權,然後專門對所需的表僅授予選擇權限(希望它能覆蓋「所有「,我知道愚蠢)。

  • 授予對該數據庫(db_name。*)的所有權限,然後撤消插入,更新和刪除操作。但是這產生了一個錯誤,說db_name.table_name沒有授權規則。

從我已經能夠收集我將不得不單獨授予除了只讀表的數據庫的每個表上的所有特權。

請有人告訴我,有一個更簡單的方法

注意:我運行MySQL 5.1。 Ubuntu 10.04上的最新版本。

+0

什麼是您的MySQL版本? – Devart 2011-06-09 06:11:55

+0

對不起,應該說明這一點,它是5.1 – xzyfer 2011-06-09 06:15:50

+0

1.使用兩個數據庫怎麼樣?我的意思是你可以在第二個數據庫中存儲特殊表。 2.我問過版本,因爲在MySQL 5.5中,這可以通過準備好的語句來完成。 – Devart 2011-06-09 06:26:06

回答

6

AFAIK,是的,你需要每個表單獨授予。但是,嘿,你有一臺電腦。計算機是在爲你自動執行重複任務很大,所以你爲什麼不使一個腳本,執行以下操作:

  1. 獲取所有表的列表在數據庫(SHOW TABLES;
  2. 有關每個項目名單,授予所有權限
  3. 撤消權限上特殊的表

,或者: 2.對於列表中的每個項目,檢查它是否是特殊的表;如果它是而不是,則授予所有權限

我沒有給出代碼的原因是它可以用MySQL設施在任何腳本語言中完成,甚至是shell腳本;使用你最喜歡使用的東西。

+4

雖然此解決方案現在可以正常工作,但如果您向數據庫添加表,則必須爲每個用戶添加權限新表格。似乎沒有辦法在*上添加權限,但對特定表具有反權限。 – 2011-07-05 17:40:37

+0

除了這種方式,真的沒有辦法做到這一點嗎?這看起來不正確。我會更好的從MySQL。我也需要這樣做。 – Para 2012-08-28 15:57:06

25

我知道這是一箇舊的帖子,但我想我會添加@tdammers問題讓別人看到。您還可以在information_schema.tables上執行SELECT CONCAT以創建授權命令,而不必編寫單獨的腳本。

首先撤銷所有特權從DB:

REVOKE ALL PRIVILEGES ON db.* FROM [email protected]; 

然後創建您的GRANT語句:

SELECT CONCAT("GRANT UPDATE ON db.", table_name, " TO [email protected];") 
FROM information_schema.TABLES 
WHERE table_schema = "YourDB" AND table_name <> "table_to_skip"; 

複製並將結果粘貼到你的MySQL客戶端和運行它們。

+1

使用'wildcard'異常而不是使用'AND table_name <>'use' AND table_name NOT LIKE「%_something _%」' – 2016-12-31 21:20:47

+0

這真的很方便。 :) – Bowi 2017-08-23 08:23:08

1

這裏是我用來授予MariaDB角色的草稿。 也許設置EVENT會讓它更酷:-)

DELIMITER $$ 

DROP PROCEDURE IF EXISTS refreshRoles $$ 
CREATE PROCEDURE refreshRoles() 
    COMMENT 'Grant SELECT on new databases/tables, revoke on deleted' 
BEGIN 
    DECLARE done BOOL; 
    DECLARE db VARCHAR(128); 
    DECLARE tb VARCHAR(128); 
    DECLARE rl VARCHAR(128); 
    DECLARE tables CURSOR FOR 
    SELECT table_schema, table_name, '_bob_live_sg' FROM information_schema.tables 
    WHERE table_schema LIKE '%bob\_live\_sg' AND 
     ( false 
     OR table_name LIKE 'bundle%' 
     OR table_name LIKE 'cart%' 
     OR table_name LIKE 'catalog%' 
     OR table_name LIKE 'url%' 
    ); 

    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=true; 

    CREATE ROLE IF NOT EXISTS '_bob_live_sg'; 
    REVOKE ALL, GRANT OPTION FROM '_bob_live_sg'; 

    OPEN tables; 
    SET done = false; 
    grant_loop: LOOP 
    FETCH tables INTO db, tb, rl; 
    IF done THEN 
     LEAVE grant_loop; 
    END IF; 
    SET @g = CONCAT('GRANT SELECT ON `', db, '`.`', tb, '` TO ', rl); 
    PREPARE g FROM @g; 
    EXECUTE g; 
    DEALLOCATE PREPARE g; 
    END LOOP; 
    CLOSE tables; 
END $$ 

DELIMITER ; 

CALL refreshRoles;