2009-02-26 57 views
8

Tôi muốn tính tổng kiểm tra tất cả các giá trị của một cột tổng hợp.Tạo tổng kiểm tra tổng hợp của một cột

Nói cách khác, tôi muốn làm một số tương đương với

md5(group_concat(some_column)) 

Vấn đề với phương pháp này là:

  1. Đó là không hiệu quả. Nó phải concat tất cả các giá trị của cột như một chuỗi trong một số lưu trữ tạm thời trước khi chuyển nó vào hàm md5
  2. group_concat có độ dài tối đa 1024, sau đó mọi thứ khác sẽ bị cắt bớt.

(Trong trường hợp bạn đang tự hỏi, bạn có thể đảm bảo rằng các concat của các giá trị là theo một thứ tự nhất quán, tuy nhiên, như có tin hay không group_concat() chấp nhận một trật tự quy định tại khoản bên trong nó, ví dụ như group_concat(some_column order by some_column))

MySQL cung cấp các hàm tổng hợp bit không chuẩn BIT_AND(), BIT_OR() và BIT_XOR() mà tôi cho là sẽ hữu ích cho vấn đề này. Cột này là số trong trường hợp này nhưng tôi sẽ quan tâm để biết nếu có một cách để làm điều đó với các cột chuỗi.

Đối với ứng dụng cụ thể này, tổng kiểm tra không cần phải an toàn về mặt mật mã.

Trả lời

2

Nó có vẻ như bạn cũng có thể sử dụng thay vì crc32md5 nếu bạn không quan tâm đến sức mạnh mật mã. Tôi nghĩ rằng điều này:

select sum(crc32(some_column)) from some_table; 

sẽ hoạt động trên dây. Nó có thể là không hiệu quả như có lẽ MySQL sẽ tạo ra một bảng tạm thời (đặc biệt là nếu bạn thêm một order by).

+0

'SUM()' Không phải là điều đúng để sử dụng ở đây, vì hai tổng kiểm tra khác nhau có thể tính tổng giá trị khá dễ dàng –

+0

Làm thế nào để tránh tràn số với phương pháp này? – Robert

1

Nếu cột là số, bạn có thể làm điều này:

SELECT BIT_XOR(mycolumn) + SUM(mycolumn) 

Tất nhiên điều này rất dễ dàng để đánh bại, nhưng nó sẽ bao gồm tất cả các bit trong cột.

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

Truy vấn sau được sử dụng trong công cụ Kiểm tra bảng Mysql của Percona. Hơi khó hiểu, nhưng về cơ bản nó là CRC32 s cột (hoặc một loạt các cột được định vị) cho mỗi hàng, sau đó XOR s tất cả chúng lại với nhau bằng cách sử dụng chức năng nhóm BIT_XOR. Nếu một băm crc là khác nhau, kết quả của XOR ing tất cả mọi thứ cũng sẽ khác nhau. Điều này xảy ra trong bộ nhớ cố định, vì vậy bạn có thể kiểm tra các bảng lớn tùy ý.

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

Một điều cần lưu ý rằng mặc dù điều này không ngăn chặn xung đột có thể, và CRC32 là một chức năng khá yếu so với tiêu chuẩn hiện nay. Một hàm băm đẹp hơn sẽ là một cái gì đó giống như FNV_64. Nó sẽ rất khó có hai băm bổ sung cho nhau khi XOR chỉnh sửa với nhau.

Các vấn đề liên quan