...无需进行不必要的比较
我想获取一系列行的md5哈希值。由于带宽限制,我希望它在服务器端进行。
这有效:
create table some_table (id int auto_increment,
col1 varchar(1),
col2 int,
primary key (id));
insert into some_table (col1, col2)
values ('a', 1),
('b', 11),
('c', 12),
('d', 25),
('e', 50);
select group_concat(id,col1,col2) from
(select * from some_table
where id >= 2 and id < 5
order by id desc) as some_table
group by 1 = 1;
输出:
+----------------------------+
| group_concat(id,col1,col2) |
+----------------------------+
| 2b11,3c12,4d25 |
+----------------------------+
并带有哈希:
select md5(group_concat(id,col1,col2)) from
(select * from some_table
where id >= 2 and id < 5
order by id desc) as some_table
group by 1 = 1;
输出:
+----------------------------------+
| md5(group_concat(id,col1,col2)) |
+----------------------------------+
| 32c1f1dd34d3ebd33ca7d95f3411888e |
+----------------------------------+
但是我觉得应该有更好的方法。
尤其是,我想避免将1与100万次进行比较,这是我发现将行范围划分为一组所必需的,以便使用group_concat
,而我需要使用md5
在多行上使用group_concat
。
是否有一种方法可以在行范围上使用{A1: true, A2: false, A3: false, A4: false, A5: false, …}
(或类似名称),而无需进行不必要的比较?
修改
我想对多行进行哈希处理,以便可以比较不同服务器上产生的哈希值。如果它们不同,则可以得出结论,子查询返回的行有所不同。
答案 0 :(得分:0)
解决方案是完全省略group by 1 = 1
。我以为group_concat
会要求我为其提供一个组,但是它可以直接用于子查询,就像这样:
select group_concat(id,col1,col2) from
(select * from some_table
where id >= 2 and id < 5
order by id desc) as some_table;
请注意,需要将空值强制转换为对concat友好的对象,例如:
insert into some_table (col1, col2)
values ('a', 1),
('b', 11),
('c', NULL),
('d', 25),
('e', 50);
select group_concat(id, col1, col2) from
(select id, col1, ifnull(col2, 'NULL') as col2
from some_table
where id >= 2 and id < 5
order by id desc) as some_table;
输出:
+------------------------------+
| group_concat(id, col1, col2) |
+------------------------------+
| 2b11,3cNULL,4d25 |
+------------------------------+
另一个警告:mysql的group_concat
的最大长度由变量group_concat_max_len
定义。为了哈希 n 个表行的串联,我需要:
group_concat_max_len > (n * 33)
(多余的字节用于添加逗号)group_concat
。最终,我最终使用了客户端语言来检查每列的名称,编号和可空性,然后构建如下查询:
select md5(group_concat(row_fingerprint)) from
(select concat(id, col1, ifnull(col2, 'null')) as row_fingerprint
from some_table
where id >= 2 and id < 5
order by id desc) as foo;
有关更多详细信息,您可以浏览我的代码here(请参见函数:find_diff_intervals)。