我有一个名为servers
的表,它只有一个列id
。
这个表由不同的机器访问,每个机器都有不同的数据库用户名。
我希望这样每个服务器都不会看到这个表上的所有信息,而只会看到我指定的子集,以便在应用服务器之间划分工作负载。
我最初的想法是重命名该表(例如,"servers_table"),向其添加另一个"user“列,并创建一个视图(带有原始名称),该视图根据当前连接到服务器的用户名显示结果。
我的桌子现在是这样的:
id user
1 server1
2 server1
3 server2
4 server1
5 server2
我的尝试是(作为"server1"):
CREATE VIEW server AS
SELECT id
FROM server_orig
WHERE usuario=SUBSTRING_INDEX(CURRENT_USER(),'@',1);
但是,这不起作用,因为CURRENT USER()
是在CREATE VIEW
时计算的,而不是在SELECT
时计算的。
因此,运行:
mysql -userver1 database -e "select * from server;"
产量:
+----+
| id |
+----+
| 1 |
| 2 |
| 4 |
+----+
但以server2的身份运行它也是如此。
我不能(因为程序是封闭的)更改原始的select
语句(这最终也会导致更改insert/update
语句)。
是否有一种方法可以完全在MySQL方面实现这一点?
发布于 2012-10-03 01:19:24
来自current_user() 文档的提示:
对于使用SECURITY特性定义的存储过程、函数和视图,CURRENT_USER()返回对象的调用程序。
另一方面,在PostgreSQL中,您也可以这样做(使用current_user
函数,它的行为完全符合需要),如果有了良好的设计和配置,性能不会更差--不过,我不认为这个特性会使迁移到PostgreSQL有任何意义(特别是考虑到应用程序代码已经关闭.)
发布于 2012-10-03 13:40:07
请运行以下SQL查询:
SELECT USER(),CURRENT_USER();
USER()
报告您如何尝试在MySQL中进行身份验证。CURRENT_USER()
报告如何允许您在MySQL中进行身份验证。实际上,USER()
可能更好,因为它揭示了DB连接的原始点。您可能应该创建一个存储过程或存储函数(用SELECT GROUP_CONCAT(id) FROM server_orig WHERE usuario=SUBSTRING_INDEX(CURRENT_USER(),'@',1);
返回逗号分隔的ids列表)。
这样,您就可以使用SQL安全定义器创建存储过程或存储函数,并且仍然知道是谁发起了查询。CURRENT_USER()将是定义者。您将需要使用USER()
函数。
发布于 2019-01-11 13:35:27
使用USER()
而不是CURRENT_USER()
。也离开SQL SECURITY DEFINER
。使用INVOKER
,您将无法在不为它使用的每个表授予权限的情况下选择视图。
https://dba.stackexchange.com/questions/25337
复制