二进制数据类型排序规则与MariaDB中的字符

t5zmwmid  于 2023-04-06  发布在  其他
关注(0)|答案(1)|浏览(191)

我正在努力深入了解RDBMS,我正在学习MariaDB。
正在努力获取Binary数据类型及其排序规则的工作方式。
我知道二进制(n)数据类型需要n个字节。这意味着可以分配的最小内存是1个字节?
这是从MariaDB文档中摘录的:
BINARY类型类似于CHAR类型,但存储的是二进制字节串而不是非二进制字符串。M表示以字节为单位的列长度。它不包含字符集,比较和排序基于字节的数值。
我有以下子问题:
1.一个字节的数值到底是什么?它和一个ASCII字符得到一个数字是一样的吗?如果不是,一个数值是如何确定的?
1.如果我在一个二进制数据类型中插入一个字符'A',它是如何编码和存储的?在Table plus客户端中,我看不到它以二进制存储。
1.在相同的数据类型中,我可以添加字符和二进制图像,例如,如何确定字节字符串的数值?
我已经创建了几个表来测试它,
首先,我创建一个表,用Binary(1)测试它,这不允许我添加超过1个数字0-9或1个字符A-Z或a-z
然后我用Binary(10)创建了一个表来查看排序顺序是如何工作的

CREATE TABLE BinaryEg1(
    b BINARY(1)
);

-- Adding two binary digits
INSERT INTO BinaryEg1 VALUES (0), (1);

-- Throws error, too long
INSERT INTO BinaryEg1 VALUES (10);

-- Adding basic chars to compare sort
INSERT INTO BinaryEg1 VALUES ('A'), ('a'), ('B'), ('b');

在这里,如果我看到默认的排序顺序,它会将数字放在大写字母之前,然后是小写字母:

SELECT * FROM BinaryEg1 ORDER BY b;

-- Creating a table of 10 binary bytes to test how sorting works
CREATE TABLE BinaryEg10(
    b BINARY(10)
);

-- Inserting values into 10 byte binary column
INSERT INTO BinaryEg10 VALUES (HEX('A'));

-- Adding some numbers of varying lengths to test sort order
INSERT INTO BinaryEg10 VALUES
(110),
(44),
(999999),
(1111111111),
(7876);

SELECT * FROM BinaryEg10 ORDER BY b;

现在,我看到排序顺序:

请有人解释一下排序是如何工作的,看起来第一个字节在序列中是最重要的,它忽略了其余的字节,
我明白,这可能是一个不相关和无意义的问题,因为通常我认为我不应该使用二进制来存储字符,但我仍然想对这种数据类型的工作原理有一个坚实的理解

ha5z0ras

ha5z0ras1#

感谢上面我的问题中的评论,它给了我获取十六进制值的想法。现在,我对这是如何工作的有了深刻的理解。
答案是:
一个字节的数值到底是什么?它和一个ASCII字符得到一个数字是一样的吗?如果不是,一个数值是如何确定的?
字节序列中的每个字节,每个字节是一个从0到255以10为基数的数字,因为每个字节有8位。
当我添加一个ASCII字符时,它的数值Map到它的十六进制数字代码,十六进制数字代码Map到它的十进制数字代码。所以,在ASCII字符的情况下,数字代码和数值是相同的。
如果我在一个二进制数据类型中插入一个字符'A',它是如何编码和存储的?在Table plus客户端中,我看不到它以二进制存储。
如果我在二进制列中插入字符'A',它将占用1字节的内存,就像我在char列中添加char 'A'一样。
它将被编码成二进制的基础上,其十进制/十六进制值从Latin 1字符集,这是默认的字符集为MariaDB。这Map到ASCII和Unicode表,所以它是相同的。
字符'A'的十六进制值为:41.当转换为二进制时,将存储为:0100 0001,这需要一个字节的内存。十进制值是65。如果将此char与另一行中的另一个值进行比较,则比较将基于此数值,而不是字符的排序规则。
在相同的数据类型中,我可以添加字符和二进制图像,例如,如何确定字节字符串的数值?
将二进制数据类型理解为字节序列是很重要的,每个字节都有一个从0到255的数值。
比较从左到右比较每个字节的数值,如果字节相等,则比较下一组字节的字节值,依此类推。
下面是一些例子来说明这一点:

-- Creating a table with just 1 byte
CREATE TABLE BinaryEg1(
    b BINARY
);

-- Inserting values:
INSERT INTO BinaryEg1 VALUES (0), (1), ('A'), ('B'), ('a'), ('b'), (0);

现在,我已经创建了两列,一列是正常值,另一列是十六进制值,我们可以看到数值加起来是ASCII,Latin 1,UTF8字符集中的数字代码:

SELECT b, HEX(b) FROM BinaryEg1 ORDER BY b;

我创建了另一个包含三列的示例来展示同一点,我们可以看到列是如何以相同的方式排序的:

CREATE TABLE BinaryEg3(
    b BINARY(3)
);

INSERT INTO BinaryEg3 VALUES 
(418), (518), (318);
(320), (319), (317);

现在,您可以看到正常的十进制数字字符以及它们的十六进制值,我可以了解它将如何排序:

SELECT b, HEX(b) FROM BinaryEg3 ORDER BY b;

现在,这些值以基于十六进制数的二进制形式存储。每个字节有2个十六进制数字,因此这3个数字有6个十六进制数字。
每个字节都基于该数值进行比较,这就是为什么317在318之前,318在319之前。
因为3和1的十六进制/二进制值是一样的,但是7〈8〈9

相关问题