Minha situação
Eu tenho bancos de dados MySQL, cada um com o mesmo esquema (estrutura de tabela e relacionamentos exatamente iguais).
Os dados do banco de dados Green são compartilhados pelos outros três. Eu tenho um processo noturno que encontra alterações no banco de dados Green e as envia para os outros três bancos de dados.
Pense no banco de dados Green como dados de referência atualizados por uma equipe separada, mas há muitos deles e mudam todos os dias.
O resultado final é que cada um dos bancos de dados Blue, Red e Purple é uma mistura de registros atualizáveis exclusivos para ele e os registros do banco de dados Green que podem ser referenciados, mas não modificados.
O problema
O processo de sincronização personalizado é confuso e não confiável de maneiras que não são importantes para a questão.
Minha pergunta
Existe uma maneira melhor de combinar os dados compartilhados (verdes) com outros bancos de dados? Eu gostaria de ter um impacto mínimo na camada de acesso a dados do aplicativo projetada para os dados intercalados que são possíveis pelo processo de sincronização noturna.
Ideia considerada
Eu pensei em deixar os dados do Green em seu próprio esquema (no mesmo servidor MySQL) e criar uma view, (para consultas) para cada tabela em meus outros bancos de dados para dar a ilusão das tabelas originais mescladas:
CREATE VIEW blue.vw_table001 AS
SELECT * FROM blue.table001 UNION
SELECT * FROM blue.table001;
Isso me permitiria simplesmente substituir meu mapeamento Hibername para as tabelas originais por mapeamentos para a visualização correspondente. Em seguida, as gravações fariam referência às tabelas reais como fazem hoje.
No entanto, isso cria dois problemas...
- Eu teria que eliminar todas as chaves estrangeiras porque os registros no banco de dados Blue podem referenciar registros no banco de dados Green.
- Me disseram que o desempenho de combinar os dados dessa maneira não será bom. Pode ser importante saber que existem algumas consultas complexas que se unem em várias tabelas que agora seriam unidas em exibições.
Pensamentos finais
Embora seja bom não replicar os dados Green nos outros três (e pode haver muitos mais de três algum dia), estou bem com isso, desde que o mecanismo seja relativamente simples e confiável (minha solução java é bastante complicada e propenso a erros).
Além disso, você pode estar se perguntando sobre colisões de chave primária entre registros criados no banco de dados Green e cada um dos outros três. Nossa lógica de quase sincronização registra o ID original dos registros Green em uma coluna especial e, em seguida, atribui um ID localmente exclusivo aos registros.
Parece-me que a replicação baseada em linha (em vez de baseada em instrução e mista padrão) pode ser uma solução adequada nesse caso.
A replicação nativa do mysql, na verdade, não requer tabelas idênticas nos lados mestre e escravo. O único requisito é que para cada escravo INSERT replicado não deve ter a linha com as mesmas chaves PRIMARY/UNIQUE. E vice-versa - para cada DELETE/UPDATE as linhas correspondentes devem existir.
A replicação baseada em linha propaga as alterações de linha diretamente, como está. Se a linha contendo ID=xxxxxx foi excluída no mestre, a mesma linha será excluída no escravo. Se uma linha com uma coluna autoincrementada foi inserida no mestre, então a mesma linha com o mesmo valor A/I será inserida no escravo, apesar do contador de autoincremento do escravo.
Você precisa de chaves primárias de várias colunas:
hostID -- rowID -- col1 -- col2...
PRIMARY (hostID, rowID) com hostID=Green|Red|Blue|Purple... garantirá que o PK será exclusivo para qualquer linha no sistema. Como resultado, os eventos de replicação do mestre nunca interferirão nos dados locais no escravo. Você pode manipular com segurança as linhas 'locais' intercaladas com os dados do mestre replicado até limitar-se às linhas com local
hostID
. Além disso, esta abordagem é facilmente extensível para um número arbitrário de escravos.Pode ser que não seja a melhor solução (muita modificação de código necessária), mas definitivamente funcionará.