MySQL hex strings low bytes first - mysql

If I insert 0xFF into a binary column, MySql (5.7) assumes these are the high bytes.
e.g. if the column is BINARY(2):
+--------------------+
| HEX(binary_column) |
+--------------------+
| FF00 |
+--------------------+
Just for convenience, how would you get MySql to interpret a hex string normally?
P.S. Also tried UNHEX()

binary is not really a numerical datatype. It is a special type of string used to store binary data like files. In contrast to e.g. char, binary does not have a character map and comparisons are done with the numerical code.
That behaviour is similar as to how other programming languages treat strings and byte arrays, and is expected in mysql too, see The BINARY and VARBINARY Type:
When BINARY values are stored, they are right-padded with the pad value to the specified length. The pad value is 0x00 (the zero byte). Values are right-padded with 0x00 on insert, and no trailing bytes are removed on select. All bytes are significant in comparisons, including ORDER BY and DISTINCT operations. 0x00 bytes and spaces are different in comparisons, with 0x00 < space.
You seem to look for binary numbers, so you may want to use a numeric type. You can use e.g. int (or bit(16)) and still insert values like 0xFF (just not as '0xFF' without further casting), and you still can display them with e.g. hex(0xFF) in the way you want.
If you want to use binary values (or need large values > 8 byte), you can use lpad to fill them with leading zeros, e.g.
select hex(lpad(0xFF,2,0x0))
You have to know (or query) the size of your column, and you will probably run into a lot of issues with this, starting with the simple task of adding two binary values. So to keep it simple, use a numeric type.

Related

Proper way to insert binary and varbinary datat in MySQL? Need an example [duplicate]

This question already has an answer here:
How to store varbinary in MySQL?
(1 answer)
Closed 6 years ago.
How to insert binary and varbinary datat in MySQL? Need an example
create table string_binary1 (binarydata binary(3));
insert into string_binary1 values ('a');
insert into string_binary1 values ('12343');
difference between above 2 statements, whether in both the cases data is converted to binary. If so then , it is displayed as BLOB
but if I uncheck , treat binary/varbinary as non binary charater string, then only data is displayed properly but not in binary value.
You can simpply use quotes to insert the data:
INSERT INTO varbinaryt1 (varbinarydata ) VALUES('myvarbinarydata')
See the MySQL docs:
When BINARY values are stored, they are right-padded with the pad
value to the specified length. The pad value is 0x00 (the zero byte).
Values are right-padded with 0x00 on insert, and no trailing bytes are
removed on select. All bytes are significant in comparisons, including
ORDER BY and DISTINCT operations. 0x00 bytes and spaces are different
in comparisons, with 0x00 < space.
Example: For a BINARY(3) column, 'a ' becomes 'a \0' when inserted.
'a\0' becomes 'a\0\0' when inserted. Both inserted values remain
unchanged when selected.
For VARBINARY, there is no padding on insert and no bytes are stripped
on select. All bytes are significant in comparisons, including ORDER
BY and DISTINCT operations. 0x00 bytes and spaces are different in
comparisons, with 0x00 < space.

Why some MySQL data type require some extra bytes?

I was reading about the MySQL data type size. I saw VARCHAR takes extra 1/2 bytes, MEDIUMTEXT requires extra 3 bytes, LONGTEXT requires extra 4 bytes. What is the reason for such MySQL behaviour?
When MySQL (or any database or computer language) stores a variable length string, there are basically two ways to store the value:
The length can be encoded followed by the characters in the string
The end of the string can be marked by a special character (typically '0')
Databases (almost?) always use length encoding. So, when you store 'ABC' as a variable length string, in the database storage it looks like:
3 A B C
When you store 'A':
1 A
That way, MySQL knows when one string ends and the next begins. The different lengths for the different types are based on the maximum length of the string. So, 1 byte can hold values from 0 to 255. 2 bytes can hold values from 0 to 65,535 and so on.
When you use a regular character expression, say char(3), then 'ABC' looks like:
A B C
This occupies three bytes/whatever (depending on the character coding). The length is known from the table metadata.
With char(3), the string 'A' also occupies three slots:
A
---^space here
--------^space here
The extra two are occupied by spaces. For long strings, this is generally a big waste of space, which is why most strings are stored as varchar rather than char.

How to bitwise OR into a binary(100)?

I have a binary(100), and I want to bitwise OR just one of its bytes with a constant.
Any idea how this would be done?
Alternatively, how can I store a value into a byte of a binary(100)?
Firstly, consider whether BINARY is actually the appropriate field type. When compared to BLOB it has a potentially nasty "feature" of stripping trailing spaces. BINARY is really designed to be just a case-insenstive binary text string, and not a blob of arbitrary binary data.
If you do use a blob, you'd need to use the SUBSTRING() operator combined with ASCII() to extract just the byte you want, then use the | bitwise operator.
To set something in the second byte you'd need to use something like:
UPDATE TABLE SET col = CONCAT(
SUBSTR(col, 1, 1),
CHAR(ASCII(SUBSTR(col, 2, 1) | 0x80)),
SUBSTR(col, 3)
)
A possibly simpler solution might be to treat your 100 bytes as 12.5 lots of 64 bits (i.e. BIGINT), and then use direct bitwise operations on individual words.

Inserting hex value in MySQL

I have created an SQL database using Java. I have a table created which has two columns, the first being a big integer which increments, the second I have tried defining it as a char, varchar and binary.
But I'm still not getting the desired functionality. Say I try and store a hex number 0a into the char column and I get an error. I appended 0x to the beginning and it seems to store, but when I print out the contents it is blank. Or in some cases I get characters such as '/' or '?'. I also tried using SQL explorer and it gives me the same result viewing the table,
My problem is I need to store an eight character hex string such as eb8d4ee6.
Could someone please advise me of how this can be done?
See http://dev.mysql.com/doc/refman/5.5/en/hexadecimal-literals.html
MySQL supports hexadecimal values,
written using X'val', x'val', or 0xval
format, where val contains hexadecimal
digits (0..9, A..F). Lettercase of the
digits does not matter. For values
written using X'val' or x'val' format,
val must contain an even number of
digits. For values written using 0xval
syntax, values that contain an odd
number of digits are treated as having
an extra leading 0. For example, 0x0a
and 0xaaa are interpreted as 0x0a and
0x0aaa.
In numeric contexts, hexadecimal
values act like integers (64-bit
precision). In string contexts, they
act like binary strings, where each
pair of hex digits is converted to a
character:
You probably should store the Hex number in an integer column. You can then convert back to hex when selecting using the HEX() function.
E.g.,
INSERT INTO MyTable (`MyIntegerColumn`) VALUES (0xeb8d4ee6);
You can use a Json column:
And use JSON.stringify(hex) to insert and you can always get the result via select and compare too

Can MySQL VARCHAR's store any chars?

Can MySQL VARCHAR's store any char like nulls and newlines?
MySQL can store any chars, but depending on the specified encoding, some characters may be misrepresented if different from your display encoding.
Varchars can contain any chars, even 0x00, since its not a null terminated string, but a length specified string, where the length is specified at the beginning of the string as a 2 or 4 byte value.
I'm not sure about Char columns, but I'm guessing they are null terminated in the sense that the first 0x00 indicates end of string (though storage still takes up the full length).
If you want to store true byte data though, you should use the BLOB type. That is also a length specified type, which is guaranteed to contain whatever data you put into it, and is not affected by encodings at all.
You should probably use the BINARY and VARBINARY data types for storing strings of non-printable characters, especially if you want strings of single bytes instead of actual text characters (which can be multi-byte).