Ich möchte eine Prüfsumme aller Werte einer Spalte in Aggregat berechnen.
Mit anderen Worten, ich möchte ein Äquivalent von
machen %Vor%Das Problem mit diesem Ansatz ist:
(Falls Sie sich wundern, können Sie sicherstellen, dass die Concat der Werte in einer konsistenten Reihenfolge sind, da Group_concat () eine order by-Klausel akzeptiert, oder nicht, zB group_concat(some_column order by some_column)
)
MySQL bietet die nicht standardmäßigen bitweisen Aggregatfunktionen BIT_AND (), BIT_OR () und BIT_XOR () an, von denen ich annehme, dass sie für dieses Problem nützlich wären. Die Spalte ist in diesem Fall numerisch, aber ich würde gerne wissen, ob es eine Möglichkeit gibt, dies mit String-Spalten zu tun.
Für diese spezielle Anwendung muss die Prüfsumme nicht kryptologisch sicher sein.
Es scheint, als ob Sie crc32
anstelle von md5
verwenden könnten, wenn Sie sich nicht um die kryptographische Stärke kümmern. Ich denke das:
würde auf Strings funktionieren. Es könnte ineffizient sein, da MySQL möglicherweise eine temporäre Tabelle erstellen würde (besonders wenn Sie order by
hinzugefügt haben).
Die folgende Abfrage wird in Perconas Mysql Table Checksumming Tool verwendet. Es ist ein wenig schwer zu verstehen, aber im Wesentlichen ist es CRC32
s die Spalte (oder eine Reihe von Spalten concatted) für jede Zeile, dann XOR
s sie alle zusammen mit der BIT_XOR
Gruppenfunktion. Wenn ein CRC-Hash unterschiedlich ist, wird das Ergebnis von XOR
ing auch anders sein. Dies geschieht im festen Speicher, so dass Sie beliebig große Tabellen mit Prüfsummen erstellen können.
SELECT CONV(BIT_XOR(CAST(CRC32(column) AS UNSIGNED)), 10, 16)
Beachten Sie jedoch, dass dies mögliche Kollisionen nicht verhindert, und CRC32
ist nach heutigem Standard eine ziemlich schwache Funktion. Eine schönere Hashfunktion wäre etwas wie FNV_64
. Es wäre sehr unwahrscheinlich, zwei Hashes zu haben, die sich ergänzen, wenn XOR
ed zusammen ist.
Wenn die Spalte numerisch ist, können Sie dies tun:
%Vor%Natürlich ist das leicht zu besiegen, aber es enthält alle Bits in der Spalte.