我的情况
我有 MySQL 数据库,每个数据库都有相同的模式(表结构和关系完全相同)。
Green 数据库中的数据由其他三个共享。我有一个夜间进程,可以在 Green 数据库中查找更改并将它们 UPSERT 到其他三个数据库中。
将绿色数据库视为由一个单独的团队更新的参考数据,但它有很多,而且每天都在变化。
最终结果是,蓝色、红色和紫色数据库中的每一个都是其独有的可更新记录和绿色数据库中可能被引用但不能修改的记录的混合。
问题
自定义同步过程混乱且不可靠,对问题并不重要。
我的问题
有没有更好的方法将共享(绿色)数据与其他数据库结合起来?我希望对应用程序数据访问层的影响最小,该访问层专为通过夜间同步过程实现的交错数据而设计。
考虑的想法
我考虑将绿色数据保留在自己的模式中(在同一个 MySQL 服务器上)并为我的其他数据库中的每个表创建一个视图(用于查询),以产生原始合并表的错觉:
CREATE VIEW blue.vw_table001 AS
SELECT * FROM blue.table001 UNION
SELECT * FROM blue.table001;
这将允许我简单地将我的 Hibername 映射到原始表的映射替换为到相应视图的映射。然后写入将像今天一样引用实际的表。
但是,这会产生两个问题......
- 我必须消除所有外键,因为 Blue 数据库中的记录可以引用 Green 数据库中的记录。
- 我被告知以这种方式组合数据的性能不会很好。重要的是要知道有一些复杂的查询会跨多个表连接,而这些表现在将跨视图连接。
最后的想法
虽然最好不要将绿色数据复制到其他三个中(并且有一天可能会超过三个),但只要机制相对简单可靠(我的 java 解决方案非常复杂),我就可以接受并且容易出错)。
此外,您可能想知道在 Green 数据库中创建的记录与其他三个记录之间的主键冲突。我们几乎同步的逻辑将绿色记录的原始 ID 记录在一个特殊的列中,然后为记录分配一个本地唯一的 ID。
在我看来,在这种情况下,基于行的复制(而不是基于语句和默认混合的复制)可能是一个合适的解决方案。
原生 mysql 复制,其实不需要主从端的表完全相同。唯一的要求是对于每个复制的 INSERT 从属设备不应具有具有相同 PRIMARY/UNIQUE 键的行。反之亦然 - 对于每个 DELETE/UPDATE,相应的行应该存在。
基于行的复制按原样直接传播行更改。如果在 master 上删除了包含 ID=xxxxxx 的行,则在 slave 上将删除同一行。如果在主服务器上插入了具有自动递增列的行,那么将在从服务器上插入具有相同 A/I 值的同一行,尽管从服务器的自动递增计数器。
您需要一个多列主键:
hostID -- rowID -- col1 -- col2...
PRIMARY (hostID, rowID) with hostID=Green|Red|Blue|Purple... 将保证 PK 对于系统中的任何行都是唯一的。因此,来自主服务器的复制事件永远不会干扰从服务器上的本地数据。您可以安全地操作与复制的主数据交错的“本地”行,直到限制为具有 local 的行
hostID
。此外,这种方法很容易扩展到任意数量的从站。可能这不是一个最好的解决方案(需要大量的代码修改),但它肯定会起作用。