1

次のことが可能であれば、それは絶対に素晴らしいことです。

ドキュメント「id」と他のいくつかの列を持つ「ドキュメント」mysqlテーブルがあるとしましょう。

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

ドキュメントはかなりたくさんあるかもしれませんが、今のところ私は200万しか持っていないとしましょう。

このクエリの結果をプログラミング言語空間ですばやく取得したいのですが、次のようになります。

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

句「whatever」は潜在的に空であるため、セットにはすべてのドキュメントのIDを含めることができます。

だから私の質問は:このクエリの結果を、潜在的に200万の文字列化された数値(〜14Mo ..あまり良くない)ではなく、サイズ200万ビット(〜250kのデータ)のビットベクトルBLOBとして取得する方法はありますか?

スパースセットの場合のblob圧縮に対する追加の賞賛:)

4

1 に答える 1

3

パフォーマンスはひどいものになりますが、このストアドプロシージャは、要求した結果を提供します。

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;

HEX(result)説明のために戻ってきました。実際には、置き換えることができます

SELECT HEX(result) AS result;

単に

SELECT result;

または、結果のzlib圧縮が必要な場合:

SELECT COMPRESS(result) AS result;

あなたが言及した余分な称賛を得るはずです。

インタラクティブなデモについては、http://sqlfiddle.com/#!2 / 6f5c0/ 1を参照してください。

于 2012-10-02T13:35:03.890 に答える