2012-10-02 43 views
1

這將是絕對巨大的,如果下面的事情是可能的:如何從Mysql中獲取位集BLOB select ID查詢?

比方說,我有一個「文件」 mysql表,用文件「ID」和其他幾個欄目:

CREATE TABLE document(id INT AUTO_INCREMENT NOT NULL, ....); 

可以有很多文件,但是現在我只有兩百萬。

我想迅速獲得此查詢我的編程語言空間的結果:

SELECT id FROM document WHERE ... whatever ...; 

的條款「不管」是潛在的空的,所以集可以包含的所有文件的ID的。

所以我的問題是:有沒有辦法得到這個查詢的結果作爲位向量BLOB的大小200萬位(〜250K的數據),而不是可能的2百萬字符串數字(〜14Mo ..不是很好)。

爲BLOB壓縮稀疏套:)情況下額外的榮譽

+0

嗯......這是否屬於數據庫層?我能想到在MySQL中做這件事的唯一方法是編寫一個[UDF](http://dev.mysql.com/doc/en/adding-udf.html),它初始化後在組中更新一個BLOB值聚合; ['BIT_OR(1 << id)'](http://dev.mysql.com/doc/en/group-by-functions.html#function_bit-or)本來可以做到這一點,如果它不受限制的話以64位精度。 – eggyal

+0

是的,我想如果沒有辦法在本地執行,那麼帶有簽名BLOB f(id_query,id_name,max_id)的新函數就可以完成這項工作。我想我必須從我的C編譯器中吹走灰塵:) – jeje

回答

3

雖然性能會可怕,這個存儲過程會給你你所要求的結果:我們正在返回HEX(result)

CREATE PROCEDURE ex12688666(whatever TEXT) 
DETERMINISTIC 
READS SQL DATA 
SQL SECURITY INVOKER 
COMMENT '' 
proc: BEGIN 
    DECLARE not_found BOOL DEFAULT FALSE; 
    DECLARE max   BIGINT UNSIGNED DEFAULT 0; 
    DECLARE len   BIGINT UNSIGNED; 
    DECLARE i   BIGINT UNSIGNED; 
    DECLARE pos   BIGINT UNSIGNED; 
    DECLARE result  LONGBLOB DEFAULT ''; 

    DECLARE cur1 CURSOR FOR 
     SELECT id FROM ids WHERE id RLIKE whatever ORDER BY id; 

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET not_found = TRUE; 

    SELECT MAX(id) INTO max FROM ids; 

    IF (max > 0) THEN 
     SET len = FLOOR((max + 7)/8); 
     SET result = REPEAT("\0", len); 

     OPEN cur1; 

     loop1: LOOP 
      FETCH cur1 INTO i; 
      IF not_found THEN 
       LEAVE loop1; 
      END IF; 

      SET pos = FLOOR(i/8) + 1; 
      SET result = CONCAT(
       SUBSTRING(result, 1, pos - 1), 
       CHAR(ASCII(SUBSTRING(result, pos, 1)) | (1 << (i MOD 8))), 
       SUBSTRING(result, pos + 1) 
      ); 
     END LOOP; 

     CLOSE cur1; 
    END IF; 

    SELECT HEX(result) AS result; 
END; 

說明性目的。在實踐中,人們可以簡單地用

SELECT result; 

更換

SELECT HEX(result) AS result; 

,或者如果你想要的結果的zlib壓縮:

SELECT COMPRESS(result) AS result; 
應該得到額外的榮譽你所提到的這

查看http://sqlfiddle.com/#!2/6f5c0/1進行互動演示。