TiDB、MySQL与Oracle的char字段

news2025/1/11 2:31:17

文章目录

  • MySQL
  • TiDB
  • Oracle
  • 结论

我们组在团队内维护了一套TiDB,有时候会有其他同事来请教一些问题,当然遇到比较复杂的问题,我也会直接抛给DBA。今天有个同事来问了一下TiDB的char字段查询是否需要补空格。在我的印象中,TiDB是高度兼容MySQL的,因此也没想太多,准备简单回复和MySQL一样。但转念一想,万一有什么不一样的地方呢,因此仔细试了一把,还真有些不同,值得记录。

MySQL

我们首先看MySQL的官方的说明和例子。
MySQL 8.1 Reference Manual - 11.3.2 The CHAR and VARCHAR Types

The length of a CHAR column is fixed to the length that you declare when you create the table. The length can be any value from 0 to 255. When CHAR values are stored, they are right-padded with spaces to the specified length. When CHAR values are retrieved, trailing spaces are removed unless the PAD_CHAR_TO_FULL_LENGTH SQL mode is enabled.
– CHAR列的长度是固定的,等于创建表时申明的长度。长度可以是0到255之间的任何值。当存储CHAR值时,右边会补空格来填充至指定长度。当从数据库中检索CHAR值时,右侧空格影响会被溢出,除非启用了PAD_CHAR_TO_FULL_LENGTH SQL 模式。

Values in VARCHAR columns are variable-length strings. The length can be specified as a value from 0 to 65,535. The effective maximum length of a VARCHAR is subject to the maximum row size (65,535 bytes, which is shared among all columns) and the character set used.
– VARCHAR列中的值是可变长字符串。长度可以指定为0到65535之间的值。VARCHAR列的有效最大长度是由最大行大小(65,535字节,所有列都共享)和使用字符集确定的。

ValueCHAR(4)Storage RequiredVARCHAR(4)Storage Required
‘’’ ’4 bytes‘’1 byte
‘ab’'ab ’4 bytes‘ab’3 bytes
‘abcd’‘abcd’4 bytes‘abcd’5 bytes
‘abcdefgh’‘abcd’4 bytes‘abcd’5 bytes

我们按照官网给的例子简单试运行,以下代码在MySQL 8.0.32版本中进行了验证。

mysql> CREATE TABLE vc (v VARCHAR(4), c CHAR(4));
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO vc VALUES ('ab  ', 'ab  ');
Query OK, 1 row affected (0.00 sec)

mysql> SELECT CONCAT('(', v, ')'), CONCAT('(', c, ')') FROM vc;
+---------------------+---------------------+
| CONCAT('(', v, ')') | CONCAT('(', c, ')') |
+---------------------+---------------------+
| (ab  )              | (ab)                |
+---------------------+---------------------+
1 row in set (0.06 sec)

mysql> CREATE TABLE names (myname CHAR(10));
Query OK, 0 rows affected (0.03 sec)

mysql> INSERT INTO names VALUES ('Jones');
Query OK, 1 row affected (0.00 sec)
mysql> SELECT myname = 'Jones', myname = 'Jones  ' FROM names;
+------------------+--------------------+
| myname = 'Jones' | myname = 'Jones  ' |
+------------------+--------------------+
|                1 |                  1 |
+------------------+--------------------+
1 row in set (0.00 sec)

mysql> SELECT myname LIKE 'Jones', myname LIKE 'Jones  ' FROM names;
+---------------------+-----------------------+
| myname LIKE 'Jones' | myname LIKE 'Jones  ' |
+---------------------+-----------------------+
|                   1 |                     0 |
+---------------------+-----------------------+
1 row in set (0.00 sec)

TiDB

TiDB的相关说明,也可以在官网上找到,不过看起来相对笼统,很容易给人一种与MySQL完全一致的错觉。
TiDB-字符串类型
在这里插入图片描述
但事实操作起来,有些微的不同。为便于理解,我们使用与MySQL完全一致的代码格式来跑一个例子。以下代码在TiDB 5.2.4版本中进行了验证。

TiDB> CREATE TABLE vc (v VARCHAR(4), c CHAR(4));
Query OK, 0 rows affected (0.01 sec)

TiDB> INSERT INTO vc VALUES ('ab  ', 'ab  ');
Query OK, 1 row affected (0.00 sec)

TiDB> SELECT CONCAT('(', v, ')'), CONCAT('(', c, ')') FROM vc;
+---------------------+---------------------+
| CONCAT('(', v, ')') | CONCAT('(', c, ')') |
+---------------------+---------------------+
| (ab  )              | (ab)                |
+---------------------+---------------------+
1 row in set (0.06 sec)

TiDB> CREATE TABLE names (myname CHAR(10));
Query OK, 0 rows affected (0.03 sec)

TiDB> INSERT INTO names VALUES ('Jones');
Query OK, 1 row affected (0.00 sec)

TiDB> SELECT myname = 'Jones', myname = 'Jones  ' FROM names; 
-- 唯一的不同之处!!! 不再匹配右侧补全的空格
+------------------+--------------------+
| myname = 'Jones' | myname = 'Jones  ' |
+------------------+--------------------+
|                1 |                  0 |
+------------------+--------------------+
1 row in set (0.00 sec)

TiDB> SELECT myname LIKE 'Jones', myname LIKE 'Jones  ' FROM names;
+---------------------+-----------------------+
| myname LIKE 'Jones' | myname LIKE 'Jones  ' |
+---------------------+-----------------------+
|                   1 |                     0 |
+---------------------+-----------------------+
1 row in set (0.00 sec)

Oracle

Oracle官网资料目录比较深,找了好一会,这是19版本的。VARCHAR2 and CHAR Data Types
在这里插入图片描述

In contrast to VARCHAR2, CHAR stores fixed-length character strings. When you create a table with a CHAR column, the column requires a string length. The default is 1 byte. The database uses blanks to pad the value to the specified length.
Oracle Database compares VARCHAR2 values using nonpadded comparison semantics and compares CHAR values using blank-padded comparison semantics.
这里就不翻译了,大致意思和MySQL的基本一样。

为便于理解,我们还是使用与MySQL完全一致的代码格式。以下SQL不保证能执行,大家意会即可。代码在Oracle 19.4.0.0.190716版本中进行了验证。

Oracle> CREATE TABLE vc (v VARCHAR2(4), c CHAR(4));
Query OK, 0 rows affected (0.01 sec)

Oracle> INSERT INTO vc VALUES ('ab  ', 'ab  ');
Query OK, 1 row affected (0.00 sec)

Oracle> SELECT CONCAT('(', v, ')'), CONCAT('(', c, ')') FROM vc;
+---------------------+---------------------+
| CONCAT('(', v, ')') | CONCAT('(', c, ')') |
+---------------------+---------------------+
| (ab  )              | (ab  )              |
+---------------------+---------------------+
1 row in set (0.06 sec)
-- 不同之处,char右侧手动插入的空格会被查询到
  
Oracle> CREATE TABLE names (myname CHAR(10));
Query OK, 0 rows affected (0.03 sec)

Oracle> INSERT INTO names VALUES ('Jones');
Query OK, 1 row affected (0.00 sec)

Oracle> SELECT myname = 'Jones', myname = 'Jones  ' FROM names; 
+------------------+--------------------+
| myname = 'Jones' | myname = 'Jones  ' |
+------------------+--------------------+
|                1 |                  1 |
+------------------+--------------------+
1 row in set (0.00 sec)

Oracle> SELECT myname LIKE 'Jones', myname LIKE 'Jones  ' FROM names;
+---------------------+-----------------------+
| myname LIKE 'Jones' | myname LIKE 'Jones  ' |
+---------------------+-----------------------+
|                   0 |                     1 |
+---------------------+-----------------------+
1 row in set (0.00 sec)
-- 诡异的地方,不包含空格的like不会被检索,包含空格的反而会。

结论

对于TiDB和MySQL而言,建议在插入与查询的时候,都忽略char字段右侧自动补全的空格。而对于Oracle则恰好相反,建议在插入与查询中,对于char字段都严格按照长度进行手工的右侧空格补全处理,避免出现意料外的情况。
当然,本身来说,char字段的使用以及长度的值,应该成为设计评审中重点关注的对象。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1128398.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Docker】Docker学习之一:离线安装Docker步骤

前言:基于Ubuntu Jammy 22.04 (LTS)版本安装和测试 1、Docker安装 1.1、离线安装 步骤一:官网下载 docker 安装包 wget https://download.docker.com/linux/static/stable/x86_64/docker-24.0.6.tgz步骤二:解压安装包; tar -zxvf docker…

安防监控视频汇聚平台EasyCVR增加AI算法列表接口的实现方法

安防监控视频汇聚平台EasyCVR基于云边端一体化架构,具有强大的数据接入、处理及分发能力,可提供视频监控直播、云端录像、云存储、录像检索与回看、智能告警、平台级联、云台控制、语音对讲、智能分析等功能。平台既具备传统安防监控的能力,也…

C++进阶语法之函数和指针【学习笔记(三)】

文章目录 1、C 函数1.1 函数的定义1.2 函数原型(function prototypes)1.3 参数(parameter)——值传递(pass by value)1.4 重载(overloading)1.5 函数传参——传递数组(ar…

Linux下控制GPIO的三种方法

https://blog.csdn.net/qq_41076734/article/details/124669908 1. 应用空间控制gpio 1.1简介 在/sys/class/gpio/下有个export文件,向export文件写入要操作的GPIO号,使得该GPIO的操作接口从内核空间暴露到用户空间,GPIO的操作接口包括dir…

Flink学习笔记(四):Flink 四大基石之 Window 和 Time

文章目录 1、 概述2、 Flink 的 Window 和 Time2.1、Window API2.1.1、WindowAssigner2.1.2、Trigger2.1.3、Evictor 2.2、窗口类型2.2.1、Tumbling Windows2.2.2、Sliding Windows2.2.3、Session Windows2.2.4、Global Windows 2.3、Time 时间语义2.4、乱序和延迟数据处理2.5、…

linux系统安装Googletest单元测试框架

环境信息 系统:ubuntn cmake版本:3.5.1 gcc版本:5.4.0 1、下载googletest git clone https://github.com/google/googletest.git注意!不选branch的话默认下载最新版本(需要编译器能够支持C14),…

如何生成osg的动画路径文件

目录 1. 前言 2. 生成动画路径文件 2.1. 粗糙方式 2.2. 精确方式 1. 前言 在进行osg的开发中,有时需要对模型按某个路径或规则进行动画,如下: 奶牛在10秒时间段从起始的osg::Vec3d(0.0, 18, 1.0)位置 匀速直线运动到osg::Vec3d(0.0, -8, …

ubuntu 中使用Qt连接MMSQl,报错libqsqlodbc.so: undefined symbol: SQLAllocHandle

Qt4.8.7的源码编译出来的libqsqlodbc.so,在使用时报错libqsqlodbc.so: undefined symbol: SQLAllocHandle,需要在编译libqsqlodbc.so 的项目pro文件加上LIBS -L/usr/local/lib -lodbc。 这里的路径根据自己的实际情况填写。 编辑: 使用uni…

Python数据结构(队列)

Python数据结构(队列) 队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。 队列是一种先进先出的 (First n First ut)的线性表,简称FIFO。允许插入的一端为队尾,允许删除的一端为队头&#xff…

深度学习——图像分类(CIFAR-10)

深度学习——图像分类(CIFAR-10) 文章目录 前言一、实现图像分类1.1. 获取并组织数据集1.2. 划分训练集、验证集1.3. 图像增广1.4. 引入数据集1.5. 定义模型1.6. 定义训练函数1.7. 训练模型并保存模型参数 二、生成一个桌面小程序2.1. 使用QT设计师设计界…

建筑工程模板分类以及特点?

建筑工程模板可以根据材料、结构和用途等方面进行分类。以下是一些常见的建筑工程模板分类及其特点: 1. 木质模板: - 特点:木质模板是最常见和传统的模板类型。它们由木材制成,具有良好的可塑性和可加工性。木质模板适用于各种形状…

京东数据分析:2023年9月京东白酒行业品牌销售排行榜

鲸参谋监测的京东平台9月份白酒市场销售数据已出炉! 9月白酒市场的整体热度较高,贵州茅台先是与瑞幸联名推出酱香拿铁,后又宣布与德芙推出联名产品酒心巧克力,引起了诸多消费者的关注。在这一热度的加持下,从销售上看&…

Kali Linux 安装搭建 hadoop 平台 调用 wordcount 示例程序 详细教程

步骤一: 目标:*安装虚拟机,在自己虚拟机上完成hadoop的伪分布式安装。(安装完成后要检查)* 1)前期环境准备:(虚拟机、jdk、ssh) 2)SSH相关配置 安装SSH Se…

【MyBatis篇】MyBatis动态代理总结

本人正在浅学mybatis,正学到mybatis动态代理,在查询多方资料之后做出以下总结,以便于系统学习时回顾; 目录 MyBatis为什么引入动态代理 mybatis的动态代理 Dao代理技术 MyBatis为什么引入动态代理 因为程序员的 懒,…

访问控制2

文章目录 主要内容一.Role和ClusterRole1.ClusterRole示例,创建一个名为test-clusterrole且仅有创建Pod和deployment的集群角色代码如下(示例): 2.YAML文件创建代码如下(示例): 3.将udbs用户和Clusterrole进行绑定&…

0基础学习VR全景平台篇第112篇:控制点和遮罩工具 - PTGui Pro教程

上课!全体起立~ 大家好,欢迎观看蛙色官方系列全景摄影课程! 前情回顾:上节,我们用PTGui拼接了一张全景图,全景编辑器里的各项功能帮助我们进行了初步的检查和编辑。 之后我们需要使用【控制点】和【遮罩…

智慧垃圾站:AI视频智能识别技术助力智慧环保项目,以“智”替人强监管

一、背景分析 建设“技术先进、架构合理、开放智能、安全可靠”的智慧环保平台,整合环境相关的数据,对接已建业务系统,将环境相关数据进行统一管理,结合GIS技术进行监测、监控信息的展现和挖掘分析,实现业务数据的快速…

【AI视野·今日CV 计算机视觉论文速览 第271期】Thu, 19 Oct 2023

AI视野今日CS.CV 计算机视觉论文速览 Thu, 19 Oct 2023 Totally 63 papers 👉上期速览✈更多精彩请移步主页 Daily Computer Vision Papers Learning from Rich Semantics and Coarse Locations for Long-tailed Object Detection Authors Lingchen Meng, Xiyang D…

偕行十年,阿里云助力众安保险用科技温暖每一张保单

云布道师 前言:应云而生的众安保险,其 IT 架构都搭建在阿里云上,云服务器 ECS 关键应用上的数据需要保护,需要简单易用、稳定性高的方案,助力保险业务的快速开发和上线。在经过全面充分地沟通评估后,众安保…

凌晨!腾讯云终于发布了2023年度双十一优惠活动!

2023腾讯云双11优惠价格表终于来了,轻量2核2G3M云服务器88元一年、轻量2核4G5M服务器166.6元一年、3年轻量2核2G4M带宽优惠价366.6元、3年轻量2核4G5M配置566.6元,CVM云服务器2核2G配置SA2实例172.3元一年、标准型S5服务器2核2G配置280.8元一年&#xff…