MySQL 临时视图是否可行?

6
这是跟进以下内容:

允许用户只能获取数据库中的某些信息

我正在编写如下视图(我相信这可以进行优化): 包含 db.php 的文件:
$conn = mysql_connect("localhost","directory","dghgffhghf") or die(mysql_error());

mysql_select_db("directory", $conn) or die(mysql_error());  

mysql_query("CREATE or REPLACE VIEW {$user}_rooms AS SELECT * FROM rooms WHERE palace = '$user'") or die(mysql_error()); 
mysql_query("CREATE or REPLACE VIEW {$user}_users AS SELECT * FROM users WHERE palace = '$user'") or die(mysql_error()); 
mysql_query("CREATE or REPLACE VIEW {$user}_servers AS SELECT * FROM servers WHERE palace = '$user'") or die(mysql_error()); 
mysql_query("CREATE or REPLACE VIEW {$user}_online_servers AS SELECT * FROM online_servers WHERE palace = '$user'") or die(mysql_error()); 

用户“ directory”必须具有 SELECT CREATE VIEW DROP 权限(由于 or REPLACE 的原因,需要 DROP )。我不希望他们拥有 DROP 权限,因为directory用户将在由apache拥有的PHP文件中,而且他们不受使用 dir 的限制——因此,他们可以查看用户名和密码。

此外,如果用户实际上是 joe ,我不希望用户仅仅使用 bob_rooms 。我只想为该特定连接的仅那个用户创建视图,并在连接结束时删除 DROP 。我不能指望用户自己执行 DROP 操作。

同时,拥有一个自动删除的临时视图可以消除使用 or REPLACE 的必要性,这意味着我可以为该用户取消奇怪的 DROP 权限。

我猜在SQLlite中,这很容易实现:

CREATE TEMP VIEW ...

SqlLite可以创建临时视图,但MySQL不能吗?


1
为什么你需要放弃它们?它们不像静态的东西(尽管我怀疑限制用户访问的计划的理智性,或者授予编写自己的SQL查询的权利,当他们是不可信的)。 - Wrikken
因为如果视图没有被删除,任何用户只要知道用户名就可以查看其他用户的信息。这个想法是目录数据库包含有关他们服务器的信息。一些信息是私人的。我给他们访问自己信息的权限,以便他们可以在向访问者显示信息时使用它。 - ParoX
1
现在有什么不同吗?他们仍然可以做到,只是时间更少了。 - Wrikken
我希望mySQL有一个临时视图,就像临时表一样,只有创建该表的连接才能访问该表。因此,当他们运行他们的PHP文件时,将为他们创建一个视图/表,他们将无法访问其他任何内容。 - ParoX
临时视图的惊人之处在于,视图可以允许读/写。 - William Entriken
2个回答

3

我不清楚临时视图,但是支持临时表。因此,您可以创建与它们所镜像的表相同结构的临时表,例如 temp_bob_rooms 用于 rooms。然后从真实表中选择插入到临时表中,并加上适当限制,例如:

INSERT INTO temp_bob_rooms (SELECT * FROM rooms WHERE user='bob');

当用户完成会话后,临时表将自动删除,因此目录用户不再需要DROP权限。您可以在此处阅读有关临时表的更多信息:

http://www.tutorialspoint.com/mysql/mysql-temporary-tables.htm

这种方法的缺点是当使用临时表的会话期间插入“真实”表中的数据时,临时表将不会更新。

另一种方法可能是编写一个脚本,为每个实际用户生成一个mysql用户,适当的视图,并将这些视图的权限授予适当的用户。该方法唯一的缺点是您的db.php文件将不再有用,因为每个用户都必须创建自己的连接并使用正确的密码和用户名。


大约100个优秀的用户使得mysql用户想法有点过头了。我曾考虑创建临时表,但这样一来,我就必须给用户INSERT权限,而这是我不想让他们拥有的...尽管我可以限制对主要表的非访问...我可能不得不使用这种方法。 - ParoX
我还没有花时间去研究这个想法,但是一个值得探索的途径是将临时表的创建、插入和存储过程合并。然后,“目录”用户可以只访问该存储过程,而不具备插入权限。 - user470714

3
您可以使用以下语法在一步中从查询创建临时表:

CREATE TEMPORARY TABLE temp_table_name SELECT ... ;

临时表的注意事项:

  • 它们没有索引 - 大型临时表性能较差。
  • 它们仅存在于创建它们的会话范围内。

临时表可以像通常一样完全创建索引,尽管您应该要求这样做。它可以具有任何索引配置,不仅适用于现有列,例如 CREATE TEMPORARY TABLE tmp (KEY smth(foo,bar)) SELECT ..., ... as foo, ... as bar, ... FROM ...;,还可以声明新的附加列和带有auto_increment 的主索引:CREATE TEMPORARY TABLE tmp2 (new_pk INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY) AS SELECT tbl.* FROM tblCREATE TABLE ... SELECT 案例在 MySQL 手册中已经被充分描述。 - Alex Offshore

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接