这里主要是 由于之前的一个 datetime 存储的时间 导致的问题的衍生出来的探究
探究的主要内容为 int 类类型的存储, 浮点类类型的存储, char 类类型的存储, blob 类类型的存储, enum/json/set/bit 类类型的存储
本文主要 的相关内容是 bit/json/enum/set 类类型的相关数据的存储
这部分数据 客户端 和 服务器这边的交互 主要是以字符串的形式交互
服务器这边的存储 相关的编码之后的整形, json 为字符串
测试数据表 以及数据如下
CREATE TABLE `tz_test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`field1` bit(6) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
INSERT INTO `test`.`tz_test`(`id`, `field1`) VALUES (1, '7');
测试脚本如下
package com.hx.test07;
/**
* Test06MysqlTimezone
*
* @author Jerry.X.He
* @version 1.0
* @date 2023/4/24 16:26
*/
public class Test06MysqlTimezone {
// Test06MysqlTimezone
public static void main(String[] args) {
String url = "jdbc:mysql://10.60.50.16:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&autoReconnectForPools=true&useSSL=false";
String username = "root";
String password = "root";
JdbcTemplate jdbcTemplate = Test14GenExpertSql.getMysqlJdbcTemplate(url, username, password);
String sql = " select * from tz_test; ";
List
mysql 是将给定的 bit 的数据以 字符串的形式 交互给客户端的
mysql 服务器中对应的类型为 BIT
bit 这边转换, 是直接获取的给定的字段对应的 字节序列
这里是 new byte[] { 0x37 }
与客户端的交互, 取出存放的 bits 的数据
然后 拷贝到 val_buffer 响应给客户端, 这里输出了一个 '7'
是转换为单字节进行存储的
和上面 bit 相同
mysql 服务器中对应的类型为 JSON
与客户端的交互, 以 my_charset_bin 反序列化为字符串, 格式化为 json
然后输出 json 字符串到给定的 buf
将给定的 json 的 字符串以 my_charset_bin 序列化为 二进制, 以二进制的形式存储
以下代码 基于 mysql-8.0.23
和上面 bit 相同
mysql 服务器中对应的类型为 STRING? 为什么不是 ENUM
与客户端的交互, 获取当前字段 在枚举的索引, 然后 根据配置的选项列表 获取对应的字符串表示
根据输入的 枚举字符 获取索引, 然后 存储的是具体的索引
假设输入的字段值 不在枚举列表中, 则存放的是 0, 表示的空字符串
数据的存储是根据索引的值域 按不同的长度进行存储
和上面 bit 相同
mysql 服务器中对应的类型为 STRING? 为什么不是 SET
与客户端的交互, 从当前字段的值中 按照权重 获取相应的字符串表示, 并用 分隔符 连接起来
可以看到 boy, girl, unknown 的索引分别为 0, 1, 2, 权重分别为 1, 2, 4
因此 这里存储的 girl, unknown 为 2 + 4 = 6
数据的存储 和上面 enum 一致, 根据存储的值的取值区间 按不同的长度进行存储
对于匹配不上的值 这里的处理是 直接过滤掉
完