MENU Mário Valney

HyperDB: duas instalações do WordPress utilizando a mesma tabela de usuários

WordPress 22 de janeiro de 2016 18 comentários
WordPress
  • 22 - 01 - 16
  •        
  • 18

E ae, meu povo!
A quanto tempo, hein? Pois é… faz tempo que não posto nada (mas sempre respondo os e-mails e comentários de vocês :D).

O motivo de eu estar afastado do site é, como vocês devem imaginar: trabalho! Do nosso Curso de Android eu andava afastado porque meu notebook não estava mais aguentando o Android Studio, mas agora, com notebook novo, devo voltar a escrever lá também. Mas o assunto de hoje é outro: WordPress!

O Problema

O problema de hoje era o seguinte:

Dois sites precisavam compartilhar as mesmas informações sobre os usuários, mas estava instalados em bancos de dados diferentes.

Complicado, hein… Mas a galera do WordPress possui uma solução muito boa para quem quer mexer mais a fundo na arquitetura do banco de dados: o HyperDB.

HyperDB

O HyperDB é uma classe substituta da classe wpdb nativa do WP, que permite o uso de vários bancos de dados simultaneamente.

Essa classe é muito poderosa e nos permite replicar dados (um banco mestre e vários agindo como slaves, dessa forma, você pode escrever apenas no mestre, que será replicado pela sua infraestrutura nos demais bancos – aí já é questão de servidor – e ler em qualquer uma das réplicas, permitindo melhor performance). Permite também particionar dados (é o que faremos hoje) e trabalha com um failover bem legal, permitindo várias tentativas de acesso, caso um dos bancos não esteja acessível.

Ah! Sabe quem mais usa? O WordPress.com.
Só com isso já dá pra perceber que é uma solução bem robusta, hein? Imagina o banco de dados deles!

Instalando o HyperDB

O HyperDB não é um plugin comum, então a instalação dele é um pouco diferente:

  1. Faça o download no repositório oficial.
  2. Descompacte e faça as configurações necessárias no arquivo db-config.php
  3. Coloque o arquivo db-config.php no mesmo diretório do wp-config.php, ou seja, na raiz da instalação ou um nível acima. Caso queira colocá-lo em outro lugar também pode, mas aí você precisará definir a constante DB_CONFIG_FILE com o caminho para ele no wp-config.php.
  4. Coloque o outro arquivo db.php dentro do diretório wp-content (ou equivalente).
  5. Para desativá-lo, basta mudar um dos arquivos de lugar.

Configurando o HyperDB

O arquivo db-config.php é cheio de comentários ensinando a configurar tudo. Desde particionamento a replica dos bancos de dados, com alguns exemplos.
A primeira coisa é incluir o banco de dados principal. Como já temos as constantes configuradas, podemos usá-las:

$wpdb->add_database(array(
	'host'     	=> DB_HOST,
	'user'     	=> DB_USER,
	'password' 	=> DB_PASSWORD,
	'name'     	=> DB_NAME
));

O segundo passo é adicionar o outro banco de dados. Como queremos que a tabela de usuários lida seja a tabela desse outro banco, então adicionamos o banco, mas num outro contexto, que na classe é chamado dataset:

$wpdb->add_database(array(
	'host'     	=> 'localhost',
	'user'     	=> 'root',
	'password' 	=> '',
	'name'     	=> 'banco_dois',
	'dataset'  	=> 'users'
));

Reparou no parâmetro dataset? Não colocamos nada no primeiro pois ele é o banco principal, ou seja, seu contexto é global, que é o valor padrão desse atributo.

Outro valor padrão é true para os parâmetros write e read, ou seja, os dois bancos adicionados podem ser lidos e escritos. No caso do primeiro, como ele é o master (mestre) devemos permitir leitura e escrita. No caso do segundo, permitimos a leitura (claro) e a escrita, pois iremos utilizar a tabela de metadados também.

A tabela de metadados wp_usermeta é onde ficam armazenadas as informações dos usuários como Nome e as Capabilities. É nela também onde ficam armazenadas informações sobre as sessões, por isso que deixaremos esse banco com a capacidade de escrita: para permitir que os usuários façam login.

Criando um callback

No HyperDB, podemos adicionar callbacks.
Callbacks são funções ou métodos que serão executados (na ordem em que foram registrados) até que um deles retorne algo além de null.

Para adicionar um callback fazemos assim:

$wpdb->add_callback($callback, $callback_group);

Sendo $callback a função/método e $callback_group o grupo de callbacks ao qual esse será adicionado. O valor padrão para o $callback_group é dataset.

Lembra que adicionamos o segundo banco (o que possui as tabelas de usuário) com o dataset users? Agora precisamos adicionar uma função de callback para retornar esse dataset, quando necessário:

$wpdb->add_callback('shared_users');
function shared_users($query, $wpdb) {
    if ($wpdb->table == $wpdb->base_prefix . 'users' || $wpdb->table == $wpdb->base_prefix . 'usermeta') {
        return 'users';
    }
}

Omitimos o segundo parâmetro, pois o valor padrão é dataset mesmo.

Explicando a função shared_users:

O valor da tabela consultada fica armazenado em $wpdb->table. Então, se essa tabela for a tabela de usuários wp_users ou a tabela de informações deles wp_usermeta, retornamos o valor users para o dataset. Como é diferente de null, não serão executados outros callbacks e o HyperDB, vai saber que deve usar o segundo banco de dados.

Como o prefixo nem sempre é wp_, usamos o valor de $wpdb->base_prefix.

Conclusão

Esse artigo é o resultado da minha pesquisa para resolver esse meu problema. Espero que tenham gostado e principalmente que seja útil! E se estão se perguntando o motivo de eu não ter utilizado uma instalação multisite do WordPress, a resposta é que ambos os sites serão bastante robustos e armazenarão milhares de [custom] posts. Então eu não queria entulhar tudo dentro do mesmo banco de dados.

O HyperDB é uma solução bastante poderosa para quem deseja utilizar vários bancos de dados, seja por performance, seja por integração de sites (como é o nosso caso). Um uso bastante interessante seria dividir os posts em vários bancos, dessa forma não sobrecarregaria a tabela de posts (e postmetas) com dados de todos os posts. Isso seria bastante interessante para o caso de vários Custom Posts, por exemplo.

Se gostou, deixe um comentário para alegrar esse pobre desenvolver que vos escreve e não se esqueça de compartilhar para espalhar a palavra! Abraços e até a próxima!

Por favor, considere desativar o AdBlock

Não perca nenhuma novidade, assinando nossa newsletter!



Não se preocupe: não enviaremos muitos e-mails, nem mostraremos seu e-mail para ninguém. Dúvidas?


Deixe seu comentário! Dúvida sobre como comentar
ou vai postar código? Leia antes.