【问题标题】:MySQL row HashingMySQL 行哈希
【发布时间】:2016-06-04 09:43:43
【问题描述】:

我正在开发一个数据库系统,其中一个 master bd & table 和许多 slave,并且销售需要从 master 同步他们的数据。

关于这种安排的几点: 1)slave db(S)会时不时离线,所以当他们再次起床时,服务会“同步”他们。 (所以没有复制) 2)我不能改变主数据库,所以不能触发。 (想象主数据库不属于我) 3)同步将发生在服务中,速度并不重要。 4)没有大量的数据——所以我什至可以走遍每一行。 5) 行中的数据变化很大,从 varchar(3) 到 varchar(500)

我环顾四周,发现 Md5() - 我认为这很棒,因为那时我可以只 CONCACT() 行值,并逐行比较。我发现的问题是 CONCAT (AND GROUP_CONCAT) 有点限制,因为它有字符限制。

获取“行”CHECKSUM 或 HASH 的最佳方法是什么?

CHECKSUM ROW WHERE id = 1 会很棒...最接近这个的是什么?

更新: 我已经设法达到那个“SELECT @@group_concat_max_len;”返回最大值 (4294967295)。但是这段代码还是不行:

SELECT id, MD5(GROUP_CONCAT(MD5(`id`), ...many columns here... ,MD5(`col30`))) AS 'md5Hash' FROM company_table GROUP BY id;

它仍然只适用于少数列。

【问题讨论】:

  • 您可以使用group_concat_max_len 变量增加group_concat 的字符限制,从而有效地使其与系统最大支持一样大。
  • 如果它是一项服务,您可以处理服务内的所有内容,如果您无法按照 bishop 的建议设置 group_concat_max_len,则可以对您在代码中连接的返回结果运行哈希。正如您所说,速度无关紧要,这将获得您想要的结果。
  • 考虑到您的要求和约束,使用MD5(GROUP_CONCAT(..))) 散列对我来说似乎是合理的。特别是,请参阅this answer。 @FrankJ 建议的代码级解决方案最终可能是最好的方法,因为它将比数据库级别的内衬更灵活。
  • 看看 percona 工具包。使用命令 pt_table sync 可以同步表或模式。唯一的问题是表结构必须相同。但是你也可以使用主/从复制。每次数据库在线时都会启动。
  • 谢谢主教,我忘了说我试过 group_concat_max_len,但这也没有用。我不确定这些设置是否可以通过我的连接进行操作 - 假设我根本无法更改或依赖对远程系统的任何更改。

标签: mysql


【解决方案1】:

好的,我要回答这个问题,因为我认为我已经走得够远了。

结果是这样的:

SELECT id, MD5(CONCAT(IF(col1,CRC32(col1),CRC32('')), ... ,IF(col20,CRC32(col20),CRC32('')))) AS 'md5has' FROM table

导致 CONCAT 的字符串数量最少,因为 CRC32 最多只能产生 10 位数的值(4,294,967,295),所以即使 concat 或 group_concat 最大值为 1024,我们也可以产生 10 位数的 CRC,然后我们可以散列一个一行有 102 列,一次通过。

最好的选择是构建一个多通道系统,在多通道中散列具有超过 102 列的表。

有点腰围,但还是比散列客户端好...节省的 IO 仍然很大,而且还有谁制作了 102 列的表?!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-09
    • 2013-08-09
    • 2011-01-29
    • 1970-01-01
    • 1970-01-01
    • 2011-05-27
    • 1970-01-01
    • 2012-03-09
    相关资源
    最近更新 更多