在我们的上一集(如何在 MySQL 中构建跨数据库查询)中,我学习了如何在 MySQL 中构建跨数据库查询。这很有效,但是当我们的英雄尝试在 PHP 中使用这些新发现的知识时,他发现他最好的朋友失败了。
我查看了 PHP 的 mysql_select_db
。这似乎意味着,如果我想将 MySQL 与 PHP 一起使用,我有几个选择:
使用 mysql_select_db
但每次只能使用一个数据库。这是我们当前的设置,将数据库作为命名空间标识符似乎不起作用(它在 MySQL shell 中工作正常,所以我知道这不是我们的 MySQL 服务器设置的问题)。
不要使用 mysql_select_db
。从我看到的一些示例来看,这似乎意味着我必须为我所做的每个查询指定数据库。这是有道理的,因为我没有使用 mysql_select_db
来告诉 PHP 我想要访问哪个数据库。这也让人难过,因为我不想遍历所有代码并在每个查询前添加数据库名称。
还有比这更好的吗?有没有办法让我在 PHP 中进行跨数据库 MySQL 查询,而不必像 (2) 这样疯狂的事情?
澄清:所提出的答案实际上都没有让我进行跨数据库查询。相反,它们允许我分别访问两个不同的数据库。我想要一个解决方案,允许我执行类似 SELECTforeign_db.login.username,firstname,lastname fromforeign_db.login,user where...
的操作,而不仅仅是对不同的数据库进行不同的查询。就其价值而言,(2) 对我来说不起作用。
阅读您的说明后,我的印象是您实际上想要查询驻留在两个单独的 MySQL 服务器实例中的表。至少,您的澄清文字:
建议您希望在以两个用户身份登录时运行一个查询(可能驻留在也可能不驻留在同一个 mysql 服务器实例上)。
在您的问题中,您说您想要从两个不同的数据库查询数据,但重要的是要认识到一个 MySQL 实例可以有很多很多数据库。对于由同一 mysql 实例管理的多个数据库,您链接到的问题中提出的解决方案很简单:只需在表名前添加数据库名称前缀,用点分隔数据库和表名称:
.
.但是,就像我指出的那样,这只在以下情况下有效:
场景1:同一主机上的数据库:授予适当的权限并限定表名称
因此,如果这些表实际上驻留在同一个 mysql 实例上,则无需第二次登录或连接 - 只需授予您用于连接到数据库的数据库用户适当的权限,即可从您需要的所有表中进行选择。您可以使用 GRANT 语法来做到这一点,记录如下:http://dev.mysql.com/doc/refman/5.1/en/grant.html
例如,
GRANT SELECT ON sakila.film TO 'test'@'%'
将允许用户test@%
从film 选择数据
表。完成此操作后,用户可以使用 sakila.film(所谓的限定表名)引用该表,或者如果当前数据库设置为 sakila,只需如下所示sakila
数据库中的电影
场景2:由不同MySQL实例管理的数据库:FEDERATED引擎
如果您要访问的表实际上由两个不同的 MySQL 实例管理,则有一个技巧可能有效,也可能无效,具体取决于您的配置。从MySQL 5.0开始,mysql支持
FEDERATED
存储引擎。这使您可以创建一个实际上不是表的表,而是远程服务器上表的窥视孔。该引擎记录在此处:http://dev. mysql.com/doc/refman/5.1/en/federated-storage-engine.html例如,如果您知道远程主机上的
misc
数据库中有此表:您可以使用以下命令创建指向该远程表的本地“指针”:
不幸的是,
FEDERATED
引擎并不总是可用,因此您必须首先检查是否可以使用它。但假设是这样,那么您可以在查询中简单地使用本地表 t,就像任何其他表一样,MySQL 将与远程服务器通信并对另一端的物理表执行适当的操作。警告:FEDERATED 表存在多个优化问题。您应该了解这些是否以及在多大程度上适用于您。例如,在许多情况下,将
WHERE
应用于联合表可能会导致整个表内容通过网络拉至本地服务器,在本地服务器上应用实际的过滤。另一个问题是表创建:您必须非常确定联合表及其指向的表的定义完全匹配,除了 ENGINE 子句(和 CONNECTION)。例如,如果您有不同的字符集,则数据在通过网络传输后可能会完全乱码。如果您想使用
FEDERATED
表,请阅读这篇文章http://oreilly.com/pub/a/databases/2006/08/10/mysql-federated-tables.html 来决定它是否适合您特定用例。如果您认为确实需要它,我有一个实用程序可以在此处创建联合表:http://forge.mysql.com/tools/tool.php?id=54
场景3:无法使用FEDERATED,但表位于不同的MySQL实例上
最后,如果您在不同的 MySQL 实例上有表,但由于某种原因无法使用联合表引擎,那么恐怕您就不走运了。您只需对两个 MySQL 实例执行查询、接收结果并在 PHP 中执行一些智能操作。根据您的具体要求,这可能是一个完全可行的解决方案
我想您需要自己决定我的答案的哪一部分最能解决您的问题,并添加评论以防您需要更多帮助。蒂亚·罗兰。
您将需要数据库在同一主机上运行。
如果是这样,您应该能够在您最喜欢的/默认数据库上使用 mysql_select_db 并手动指定外部数据库。
如果您的数据库运行在不同的主机上,您将无法直接加入。但随后您可以进行 2 个查询。