今天測試項目時,連接遠程Mysql數據庫項目正常運行,把遠程數據庫拷貝到本地數據庫,項目無法登陸,一直考慮是同步數據庫出了問題。確認幾遍后發現數據沒問題。最后發現是某條sql出現問題指定定義者的用戶不存在。而該sql中調用了視圖,最后才發現是視圖權限問題,運行sql報The user specified as a definer ('xxx'@'%') does not exist。指定定義者的用戶不存在。而該sql中調用了視圖,最后才發現是視圖權限問題。運行show create view xxx,顯示CREATE ALGORITHM=UNDEFINED DEFINER=`xx`@`%` SQL SECURITY DEFINER VIEW `user_role` AS select `ue`.`user_id` AS `user_id`,`pr`.`role_id` AS `role_id` from ((`user_employee` `ue` left join `post_employee` `pe` on((`ue`.`employee_id` = `pe`.`employee_id`))) left join `post_role` `pr` on((`pe`.`post_id` = `pr`.`post_id`))) where (`pr`.`role_id` > 0)。發現創建視圖時指定了DEFINER並且加入了SQL SECURITY。只能按照定義者的權限來。
我們在mysql創建view、trigger、function、procedure、等時都需要定義以下幾個屬性
DROP VIEW IF EXISTS `xxxx`; CREATE ALGORITHM = UNDEFINED DEFINER = `xx`@`localhost`
SQL SECURITY DEFINER VIEW `xxxx` AS
ALGORITHM=UNDEFINED:指定視圖的處理算法;①
DEFINER=`root`@`localhost`:指定視圖創建者;
SQL SECURITY DEFINER:指定視圖查詢數據時的安全驗證方式;②
任意用戶X訪問此VIEW時,能否成功取決於X是否有調用該VIEW的權限,以及definer是否有view中的SELECT的權限。
只需要修改創建同名用戶或者修改definer即可。
alter DEFINER = 'xx'@'localhost' view xxxx as ……
①:
ALGORITHM可取三個值:MERGE、TEMPTABLE或UNDEFINED。
如果沒有ALGORITHM子句,默認算法是UNDEFINED(未定義的)。算法會影響MySQL處理視圖的方式。
對於MERGE,會將引用視圖的語句的文本與視圖定義合並起來,使得視圖定義的某一部分取代語句的對應部分。
對於TEMPTABLE,視圖的結果將被置於臨時表中,然后使用它執行語句。
對於UNDEFINED,MySQL自己選擇所要使用的算法。如果可能,它傾向於MERGE而不是TEMPTABLE,
這是因為MERGE通常更有效,而且如果使用了臨時表,視圖是不可更新的。
②:
DEFINER 表示按定義者擁有的權限來執行
INVOKER 表示用調用者的權限來執行。默認情況下,系統指定為DEFINER
