federated_select_performancedb

Muitas vezes temos a necessidade de realizar consultas ou até mesmo JOINs com tabelas que estão em outro servidor MySQL/MariaDB. E no nosso cenário não tenos um MySQL Cluster, nem um MySQL Galera Cluster, nem sequer uma replicação, seja isso por qualquer motivo(projetos diferentes, empresas diferentes, etc…).
Para isso o MySQL tem(e faz muito tempo) uma engine específica, a engine FEDERATED. Sim ela permite realizar uma conexão com outro servidor MySQL/MariaDB e executar uma consulta em uma tabela. Mas tenha em mente que a performance vai depender de vários itens, como a velocidade da comunicação pela internet/rede local, quantidade de dados e itens relacionados a performance em geral(estrutura da tabela, índices, engine…).

No exemplo estou usando o MySQL 5.6.28, mas esse mesmo exemplo vai funcionar para o MySQL 5.5 e 5.7, no MySQL 5.1 e 5.0 não testei, se não for isso é muito parecido.

 

Para esse teste, estou usando 2 servidores que vou chamar de mysql56_1 e mysql56_2. O Objetivo é realizar um query que tenha um JOIN com uma tabela que está no mysql56_1 e outra no mysql56_2.

No servidor mysql56_1, tenho o database cidades, com a tabela cidades. Nessa tabela eu tenho o UF e o nome da cidade.
federated_cidades

No servidor mysql56_2, tenho o database estados, com a tabela uf. Nessa tabela eu tenho o UF e o nome do estado.
federated_estados

O objetivo é fazer um select no servidor mysql56_1 e mostrar o nome da cidade e o nome do estado.

Habilitando a engine

A engine FEDERATED não vem habilitada por padrão no MySQL, e a primeira coisa a ser feita é habilitar.

show_engines_sem

A engine já vem instalada, basta habilitar e isso é bem simples, vá até o seu my.cnf(normalmente em /etc/my.cnf) e adicionar a palavra federated dentro da sessão do mysqld, salve e reinicie o serviço do MySQL.

[mysqld]
federated

deferated_show_engines_com

Essa engine só precisa estar habilitada em um dos servidores. Apenas no servidor que a tabela será criada.
No meu exemplo, eu habilitei no mysql56_1.

Criando a tabela

Temos duas opções para criar a tabela FEDERATED, podemos criar um SERVER CONNECTION ou CONNETION.  A diferença é que quando criamos um SERVER CONNECTION, podemos reutilizar a mesma conexão para outras tabelas e a CONNECTION todos os dados da conexão devem ser declarados no comando de CREATE TABLE.

CREATE SERVER

Esse é o modo que eu gosto de utilizar.
A primeira coisa que precisamos fazer é criar um servidor(Não um servidor físico, e sim uma conexão com outro servidor).
Vou criar a conexão no mysql56_1 se conectando no mysql56_2.

CREATE SERVER conn_mysql56_2_estados
FOREIGN DATA WRAPPER mysql
OPTIONS (USER 'usr_estados', HOST '192.168.0.21', PASSWORD '123', DATABASE 'estados');

Onde:

conn_mysql56_2_estados: é o nome da conexão, ele será utilizado no momento de criar a tabela FEDERATED.
mysql: Em FOREIGN DATA WRAPPER mysql significa que é uma conexão com outro servidor MySQL, esse valor não deve ser alterado, pois até o momento é a única disponível.
usr_estados: é o nome do usuário no servidor mysql56_2.
192.168.0.21: é o IP do mysql56_2, também pode ser utilizado DNS.
123: é a senha so usuário usr_estados.
estados: é o nome do banco de dados que eu estou me conectando no servidor mysql56_2.

Agora podemos criar a tabela.

CREATE TABLE mysql56_2_uf (
 uf char(2) NOT NULL,
 nome varchar(50) DEFAULT NULL,
 PRIMARY KEY (`uf`)
) ENGINE=FEDERATED DEFAULT CHARSET=latin1 CONNECTION='conn_mysql56_2_estados/uf';

Onde:

FEDERATED: é a engine da nossa “tabela remota”.
conn_mysql56_2_estados: é o nome da conxão criada no comando CREATE SERVER.
uf: é o nome da tabela alvo, ou seja, a tabela no servidor remoto que vamos fazer o link com a tabela mysql56_2_uf.

Atnção! Veja que no momento em que criei a tabela mysql56_2_uf eu criei com a mesma estrutura que da tabela uf do servidor mysql56_2, mas isso não é uma regra, a tabela pode ser criada apenas com as colunas necessárias.

CONNECTION

A outra opção é não criar uma conexão com um servidor, mas sim declarar toda a string de conexão no momento da criação da tabela.

CREATE TABLE mysql56_2_uf (
 uf char(2) NOT NULL,
 nome varchar(50) DEFAULT NULL,
 PRIMARY KEY (`uf`)
) ENGINE=FEDERATED DEFAULT CHARSET=latin1 CONNECTION='mysql://usr_estados:123@192.168.0.21/estados/uf';

Onde:

FEDERATED: é a engine da nossa “tabela remota”.
mysql://: é o FOREIGN DATA WRAPPER esse valor não deve ser alterado, pois até o momento é a única disponível.
usr_estados: é o nome do usuário no servidor mysql56_2.
123: é a senha so usuário usr_estados.
192.168.0.21: é o IP do mysql56_2, também pode ser utilizado DNS.
estados: é o nome do banco de dados que eu estou me conectando no servidor mysql56_2.
uf: é o nome da tabela alvo, ou seja, a tabela no servidor remoto que vamos fazer o link com a tabela mysql56_2_uf.

Atnção! Veja que no momento em que criei a tabela mysql56_2_uf eu criei com a mesma estrutura que da tabela uf do servidor mysql56_2, mas isso não é uma regra, a tabela pode ser criada apenas com as colunas necessárias.

Utilizando a tabela FEDERATED

Agora bata utilizar como se fosse uma tabela qualquer do seu servidor.

federated_select_in_federated_table

Vamos ao JOIN!

federated_select_in_federated_table_join

 

Espero que esse tutorial ajude muito vocês!

Gostou? compartilha esse artigo ai :)

Post Navigation