5

I'm intending on storing a 256-bit long binary value in a MySQL table column.

Which column type should I be using (blob?) such that I can run bitwise operations against it (example of an AND would be ideal).

6
  • 256-bit is only 32 byte. Not really a Binary Large OBject. Do you only have to store those values on the DB. Or do you plan to perform some operations on them (search by value, pattern matching, arithmetic operations, bit-wise logic operations)... Commented Aug 13, 2013 at 21:40
  • I'm planning on using bit-wise operations on them. Commented Aug 13, 2013 at 21:51
  • OK, only bit-wise operation. As this is an interesting question I've done some experiments. Could you confirm that this expression from your answer below bin(label & b'01..00') works as expected if label is a BLOB column? For me, it doesn't work ?!? Always returning 0... Commented Aug 13, 2013 at 22:01
  • It does work in the select although I couldn't seem to make it work for the where clause and I haven't checked with >64-bits yet. Commented Aug 13, 2013 at 22:16
  • I think this might work up to 64 bits. But certainly not above. I've edited my answer below to what I think to be the only decently working solution: split your 256-bit value as 4 64-bit BIGINT UNSIGNED. Not excessively elegant, but that works, and you will have access to the "full power" of the MySQL bit-wise operators as well as to the various conversion function (HEX(), BIN()). Commented Aug 13, 2013 at 22:35

2 Answers 2

7

I don't think you could find some way to perform bit-wise operation on 256-bit values at SQL level as the doc clearly state that:

MySQL uses BIGINT (64-bit) arithmetic for bit operations, so these operators have a maximum range of 64 bits.

http://dev.mysql.com/doc/refman/5.5/en/bit-functions.html#operator_bitwise-and


As for storing those values, TINYBLOB is possible, but my personal preference would go to simply BINARY(32) (a binary string of 32 bytes -- 256-bits).



While writing this, one trick came to my mind. If we are limited to 64-bit values (BIGINT UNSIGNED), why not store your 256-bit as 4 words of 64-bits. Not very elegant but that would work. Especially here since you only need bitwise operations:

ABCD32 & WXYZ32 == A8 & W8, B8 & X8, C8 & Y8, D8 & Z8

Very basically:

create table t (a bigint unsigned, 
                b bigint unsigned, 
                c bigint unsigned, 
                d bigint unsigned);

While inserting, 256-bit values has to be "split" on 4 words:

-- Here I use hexadecimal notation for conciseness. you may use b'010....000' if you want 
insert into t values (0xFFFFFFFF,
                      0xFFFF0000,
                      0xFF00FF00,
                      0xF0F0F0F0);

You could easily query the 256-bit value:

mysql> select CONCAT(LPAD(HEX(a),8,'0'),
                     LPAD(HEX(b),8,'0'),
                     LPAD(HEX(c),8,'0'),
                     LPAD(HEX(d),8,'0')) from t;
+-------------------------------------------------------------------------------------------------------------------------------------------------------+
| CONCAT(LPAD(HEX(a),8,'0'),
                     LPAD(HEX(b),8,'0'),
                     LPAD(HEX(c),8,'0'),
                     LPAD(HEX(d),8,'0')) |
+-------------------------------------------------------------------------------------------------------------------------------------------------------+
| FFFFFFFFFFFF0000FF00FF00F0F0F0F0                                                                                                                      |
+-------------------------------------------------------------------------------------------------------------------------------------------------------+

I used hexadecimal here again, but you could display as binary by replacing ̀HEX() by BIN()

And last but not least you could perform binary operation on them. Once again, you just have to "split" the operand. Assuming I want to apply the 256 bits mask 0xFFFFFFFFFFFFFFFF0000000000000000 to all values in the table:

update t set a = a & 0xFFFFFFFF, 
             b = b & 0xFFFFFFFF, 
             c = c & 0x00000000, 
             d = d & 0x00000000;
Sign up to request clarification or add additional context in comments.

1 Comment

+1 Until MySQL implements the Oracle style RAW datatype, or implements the 256-bit unsigned REALLYBIGINT UNSIGNED datatype, an integer type is the way to go.
1

Looks like blob works with a query like this for the bitwise and:

select id,bin(label & b'01000000010000001000000000000000000') from projects;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.