连接到同一 DBMS 上的“外部”数据库

Posted

技术标签:

【中文标题】连接到同一 DBMS 上的“外部”数据库【英文标题】:Connecting to "foreign" database on the same DBMS 【发布时间】:2021-04-20 00:12:09 【问题描述】:

看到 JDBC 允许我透明地从同一 DBMS 上的“外部”数据库中的表中选择表,我感到有些惊讶,我对此具有必要的权限,而无需显式连接到外部数据库。这是 mysql 应该有的样子,还是只是 JDBC 的怪癖?

详情: 我在我的 DBMS 上创建了两个数据库:stkovrflo_1 和 stkovrflo_2。我从MySQL World database. 填充了这些数据库中的表

CREATE TABLE stkovrflo_1.Country
SELECT name, region FROM world.Country;

CREATE TABLE stkovrflo_2.City
SELECT world.City.name, world.Country.name AS country
FROM world.City INNER JOIN world.Country ON world.City.CountryCode = world.Country.code;

在 JDBC 中,我可以通过与 stkovrflo_1 数据库的连接来选择 stkovrflo_2.City 表的条目。我对这两个数据库都有 SELECT 访问权限。

这是我的 JDBC 代码:

import java.sql.*;

public class JDBCExample 
    static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";  
    static final String DB_URL = "jdbc:mysql://localhost/stkovrflo_1";

    public static void main(String[] args) throws Exception
        
        String uid = args[0];
        String pswd = args[1];
        
        if(pswd.toUpperCase().equals("NULL"))
            pswd = null;

        Connection conn = null;
        conn = DriverManager.getConnection(DB_URL,uid,pswd);
        
        processTableSameDB(conn);
        System.out.println("\n\n");
        processTableDifferentDB(conn);
        
        if(conn != null)
            conn.close();
    

    protected static void processTableSameDB(Connection conn) throws Exception 
        Statement stmt = null;
        String tableName = "Country";

        try
            Class.forName("com.mysql.jdbc.Driver");

            System.out.println("Retrieving from table in same database...");

            stmt = conn.createStatement();
            String sql;
            sql = "SELECT * FROM " + tableName + " LIMIT 10";
            ResultSet rs = stmt.executeQuery(sql);

            while(rs.next())
                String name = rs.getString("name");
                String region = rs.getString("region");

                System.out.print("Name: " + name);
                System.out.println(", Region: " + region);
            
            rs.close();
        
        catch(SQLException se)
            se.printStackTrace();
        
        finally
            if(stmt!=null)
                stmt.close();
        
    

    protected static void processTableDifferentDB(Connection conn) throws Exception 
        Statement stmt = null;
        String tableName = "stkovrflo_2.City";

        try
            Class.forName("com.mysql.jdbc.Driver");

            System.out.println("Retrieving from table in different database...");

            stmt = conn.createStatement();
            String sql;
            sql = "SELECT * FROM " + tableName + " LIMIT 10";
            ResultSet rs = stmt.executeQuery(sql);

            while(rs.next())
                String name = rs.getString("name");
                String country = rs.getString("Country");

                System.out.print("Name: " + name);
                System.out.println(", Country: " + country);
            
            rs.close();
        
        catch(SQLException se)
            se.printStackTrace();
        
        finally
            if(stmt!=null)
                stmt.close();
        
    
  

JDBC输出如下:

Retrieving from table in same database...
Name: Aruba, Region: Caribbean
Name: Afghanistan, Region: Southern and Central Asia
Name: Angola, Region: Central Africa
Name: Anguilla, Region: Caribbean
Name: Albania, Region: Southern Europe
Name: Andorra, Region: Southern Europe
Name: Netherlands Antilles, Region: Caribbean
Name: United Arab Emirates, Region: Middle East
Name: Argentina, Region: South America
Name: Armenia, Region: Middle East



Retrieving from table in different database...
Name: Oranjestad, Country: Aruba
Name: Kabul, Country: Afghanistan
Name: Qandahar, Country: Afghanistan
Name: Herat, Country: Afghanistan
Name: Mazar-e-Sharif, Country: Afghanistan
Name: Luanda, Country: Angola
Name: Huambo, Country: Angola
Name: Lobito, Country: Angola
Name: Benguela, Country: Angola
Name: Namibe, Country: Angola

【问题讨论】:

【参考方案1】:

阅读https://dev.mysql.com/doc/refman/8.0/en/identifier-qualifiers.html

这是正常的。只要数据库位于同一个 MySQL 实例上并且您对该数据库具有权限,那么您的“默认”数据库并不重要。您可以引用任何databasename.tablename

默认数据库类似于 shell 中的当前工作目录 (cwd)。您始终可以通过提供路径来引用另一个目录中的文件。

【讨论】:

以上是关于连接到同一 DBMS 上的“外部”数据库的主要内容,如果未能解决你的问题,请参考以下文章

两台计算机如何通过 NAT 连接到同一个外部地址?

无法从 Ubuntu 服务器上的外部站点连接到 phpMyAdmin

连接到数据库时,Java 程序是不是会替代 DBMS

如何将外部服务器上的网站连接到本地主机上通过 Xaamp 运行的数据库?

在 Linux 上从 PHP 连接到 MS Access 数据库

选择语句上的“字符串数据,右截断”警告