2009-02-26 4 views
8

Я хочу вычислить контрольную сумму всех значений столбца в совокупности.Создать совокупную контрольную сумму столбца

Другими словами, я хочу сделать некоторые эквивалент

md5(group_concat(some_column)) 

Проблема с этим подходом является:

  1. Это неэффективно. Он должен конкатрировать все значения столбца в виде строки в некотором временном хранилище, прежде чем передать его функции md5.
  2. group_concat имеет максимальную длину 1024, после чего все остальное будет усечено.

(В случае, если вам интересно, вы можете быть уверены, что CONCAT значений в последовательном порядке, однако, как считают это или нет GROUP_CONCAT() принимает заказ пунктом в нем, например, group_concat(some_column order by some_column))

MySQL предлагает нестандартные побитовые агрегированные функции BIT_AND(), BIT_OR() и BIT_XOR(), которые, как я полагаю, были бы полезны для этой проблемы. Столбец является числовым в этом случае, но мне было бы интересно узнать, есть ли способ сделать это со строковыми столбцами.

Для этого конкретного приложения контрольная сумма не должна быть криптологически безопасной.

ответ

2

Похоже, вы можете также использовать crc32 вместо md5, если вы не заботитесь о криптографической стойкости. Я думаю это:

select sum(crc32(some_column)) from some_table; 

будет работать на струнах. Это может быть неэффективно, поскольку MySQL может создать временную таблицу (особенно если вы добавили order by).

+0

'SUM()' Неправильно использовать здесь, поскольку две различные контрольные суммы могут свести к одному и тому же значению довольно легко. –

+0

Как вы избегаете числового переполнения с помощью этого подхода? – Robert

1

Если столбец числовой, вы можете сделать это:

SELECT BIT_XOR(mycolumn) + SUM(mycolumn) 

Конечно, это легко победить, но это будет включать в себя все биты в столбце.

3
SELECT crc 
FROM 
(
    SELECT @r := MD5(CONCAT(some_column, @r)) AS crc, 
     @c := @c + 1 AS cnt 
    FROM 
    (
    SELECT @r := '', @c := 0 
    ) rc, 
    (
    SELECT some_column 
    FROM mytable 
    WHERE condition = TRUE 
    ORDER BY 
     other_column 
    ) k 
) ci 
WHERE cnt = @c 
4

Следующий запрос используется в инструменте Checksumming таблицы Mysql таблицы Percona. Его немного сложно понять, но по существу это столбец (или куча столбцов, посланных) для каждой строки, затем XOR s все вместе, используя групповую функцию BIT_XOR. Если один хэш-хэш отличается, результат XOR все будет также отличаться. Это происходит в фиксированной памяти, поэтому вы можете проверять произвольно большие таблицы.

SELECT CONV(BIT_XOR(CAST(CRC32(column) AS UNSIGNED)), 10, 16)

Одна вещь, чтобы иметь в виду, что хотя это не мешает возможных столкновений, а CRC32 является довольно слабой функцией по сегодняшним меркам. Более приятная функция хэширования будет чем-то вроде FNV_64. Было бы очень маловероятно иметь два хеша, которые дополняют друг друга при объединении XOR.

Смежные вопросы