Как оставить 2 таблицы в 2 разных базах данных?

У меня есть первая база данных (dbA) со следующей таблицей: Имя пользователя:

+------------------+--------------+
| Username         | PhoneNumber  |
+------------------+--------------+
| jamesbond007     | 555-0074     |
| batmanbegins     | 555-0392     |
+------------------+--------------+

то с другой стороны у меня есть dbB с таблицей, подобной этой, с именем PrivateMessage:

+------------------+---------------------------------+
| Username         | Message                         |
+------------------+---------------------------------+
| jamesbond007     | I need new bond-girl            |
| batmanbegins     | thanks for the paycheck, Nolan  |
+------------------+---------------------------------+

теперь, как объединить эти две таблицы из двух разных баз данных, поэтому вывод будет выглядеть следующим образом:

+------------------+--------------+---------------------------------+
| Username         | PhoneNumber  | Message                         |
+------------------+--------------+---------------------------------+
| jamesbond007     | 555-0074     | I need new bond-girl            |
| batmanbegins     | 555-0392     | thanks for the paycheck, Nolan  |
+------------------+--------------+---------------------------------+

Ответ 1

Вы можете просто присоединиться к таблице другой базы данных. Вы должны указать имя базы данных в своем предложении FROM. Чтобы сделать его короче, добавьте на него ALIAS,

SELECT  a.*,          -- this will display all columns of dba.`UserName`
      b.`Message`
FROM  dba.`UserName` a  -- or LEFT JOIN to show all rows whether it exists or not
      INNER JOIN dbB.`PrivateMessage` b    
         ON a.`username` = b.`username`

но некоторые из них, возможно, где-в a username не будет сообщений. В этом случае используйте LEFT JOIN, если вы хотите показать все записи dba.Username.

Чтение из ваших комментариев, таблицы имеют разные collation. Работа над этим заключается в том, чтобы указать COLLATE в ваших связанных операторах,

SELECT  a.*,          -- this will display all columns of dba.`UserName`
      b.`Message`
FROM  dba.`UserName` COLLATE latin1_swedish_ci a  
      LEFT JOIN dbB.`PrivateMessage` COLLATE latin1_swedish_ci b    
         ON a.`username` = b.`username`

вы можете изменить latin1_swedish_ci на все, что хотите.

Подробнее о COLLATION см. полный список

Наборы символов и сортировки в MySQL


Если у вас достаточно привилегий для ALTER таблиц, просто используйте этот синтаксис для ручного преобразования и сопоставления их сопоставлений,

ALTER TABLE tbl_name CONVERT TO CHARACTER SET latin2 COLLATE 'latin2_general_ci';

Ответ 2

То же, что и обычная таблица, кроме указания базы данных:

SELECT dbA.Username, dbA.PhoneNumber, dbB.Message
   FROM dbA.Username LEFT JOIN dbB.PrivateMessage
   ON (dbA.UserName.Username = dbB.PrivateMessage.Username);

Что нужно искать:

  • LEFT JOIN вернет всех пользователей, а также тех, у кого нет сообщений (используйте INNER JOIN для извлечения только пользователей с сообщениями).
  • Пользователи с несколькими сообщениями будут появляться несколько раз (используйте агрегации и GROUP BY, чтобы получать только одно сообщение на пользователя - вам нужно будет указать критерий для выбора одного сообщения)
  • Вам нужны привилегии запросов для обеих баз данных (в противном случае некоторые пользователи с привилегиями на обоих должны копировать, например, периодически в crontab, таблицу или подмножество таблицы из базы данных в другую).
  • Совпадения могут не совпадать. Если это так, вам нужно изменить сортировку в одной из двух таблиц, используя COLLATE или преобразовать поле одной БД в charset другого с CONVERT: CONVERT (db.table.field USING Latin1), что предотвратит использование индексов, что уменьшит производительность. Вы можете изменить одну из двух таблиц, но проверить, что вы не нарушаете какой-либо запрос или приложение, используя таблицу ALTER 'ed (в крайнем случае, конвертируйте всю базу данных в хорошо зарекомендовавший себя UTF8).
  • JOIN в текстовых полях не очень эффективны, даже если у вас есть ИНДЕКС по отношению к ним в обеих таблицах; было бы лучше иметь таблицу сообщений, содержащую уникальный, числовой идентификатор пользователя, чтобы ссылаться на владельца сообщения. Я понимаю, что две разные базы данных с различными логиками могут не способствовать этому решению, но вы можете применить один из вышеперечисленных "трюков" ( "скопировать таблицу или их подмножество" ) и периодически экспортировать преобразованную и идентификационную таблицу от БД к другому. Этот один периодический запрос будет дорогостоящим, но все последующие JOIN-ы будут очень полезны.

Тестирование

Это создает две таблицы с одинаковой структурой в двух разных базах данных и объединяет их в третьей базе данных.

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.6.30 openSUSE package

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> CREATE DATABASE first_database;
Query OK, 1 row affected (0.01 sec)

mysql> CREATE DATABASE second_database;
Query OK, 1 row affected (0.00 sec)

mysql> USE first_database;
Database changed
mysql> CREATE TABLE mytable ( x integer, t varchar(32) );
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO mytable ( x, t ) VALUES ( 1, 'One in First Database' ), ( 2, 'Two in First Database' );
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> USE second_database;
Database changed
mysql> CREATE TABLE mytable ( x integer, t varchar(32) );
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO mytable ( x, t ) VALUES ( 1, 'One in Second Database' ), ( 3, 'Three in Second Database' );
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> USE test;
Database changed
mysql> SELECT * FROM first_database.mytable LEFT JOIN second_database.mytable USING ( x );
+------+-----------------------+------------------------+
| x    | t                     | t                      |
+------+-----------------------+------------------------+
|    1 | One in First Database | One in Second Database |
|    2 | Two in First Database | NULL                   |
+------+-----------------------+------------------------+
2 rows in set (0.00 sec)

mysql>

Ответ 3

SQL для этого довольно просто...

SELECT A.Username, A.PhoneNumber, B.Message
FROM dbA.Username as A
INNER JOIN dbB.PrivateMessage as B ON A.Username = B.Username

... при условии, что вы можете получить доступ к обеим базам данных в вашем соединении.

Если вы не можете получить к ним доступ, вам придется работать по другому подходу (например, копировать одну таблицу в другую базу данных до запроса или что-то подобное).

Ответ 4

Попробуйте приведенный ниже код

SELECT * FROM dbA.Username JOIN dbB.PrivateMessage USING(Username);