对比下不同RDBMS数据库中对字符数据类型处理的差异 - 为什么我们要尽量避免使用CHAR数据类型?

本文涉及的产品
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS AI 助手,专业版
简介: 对比下不同RDBMS数据库中对字符数据类型处理的差异 - 为什么我们要尽量避免使用CHAR数据类型?

1 前言

大家好,我是明哥!

今天我们来对比下 ORACLE 与 MYSQL 中不同字符数据类型的异同,以避免因前期数据结构设计时数据类型选用不当,造成后续存储加工和处理数据时的各种坑。

2 ORACLE 与 MYSQL 中字符数据类型都有哪些

ORACLE 中内置的字符数据类型主要有以下三大类:

  • CHAR/NCHAR:存储固定长度的字符串,其中NCHAR使用 national character set;
  • VARCHAR2/VARCHAR/NVARCHAR2:存储变长字符串,其中 VARCHAR 等同于 VARCHAR2,NVARCHAR2 使用 national character set;
  • CLOB/NCLOB:存储大小可达 4GB 的字符串,其中 NCLOB 使用 national character set;

MYSQL 中字符数据类型主要有:

  • CHAR:存储固定长度的字符串;
  • VARCHAR:存储变长字符串
  • BLOB/TEXT:主要用来存储大的字符串。

可以看到:

  • 二者都有专门用来处理较大字符串的数据类型,如 CLOB/BLOB/TEXT;
  • 二者都有处理定长字符串的数据类型,如 CHAR;
  • 二者都有处理变长字符串的数据类型,如 VARCHAR;

以下我们重点对比下二者对定长和变长字段类型,即 CHAR 和 VARCHAR ,处理时的异同。

3 ORACLE 和 MYSQL 对 CHAR 和 VARCHAR 处理的相同点在哪里?

3.1 ORACLE 和 MYSQL 对定长字段类型 CHAR 的存储处理类似,都会对用户传入的实际的字符串进行加工处理后再存储:

  • 如果用户传入的实际的字符串的长度,跟 DDL 语句中声明的该 CHAR 字段的长度相等,则直接存储用户传入的值;
  • 如果用户传入的实际的字符串的长度,小于 DDL 语句中声明的该 CHAR 字段的长度,ORACLE 和 MYSQL 都会在字段末尾补充空格(blank-pad),直到达到声明的长度;
  • 如果用户传入的实际的字符串的长度,大于 DDL 语句中声明的该 CHAR 字段的长度,ORACLE 和 MYSQL 都会报错退出(注意:MYSQL中,可以配置使用非 STRICT SQL MODE,此时会截断超常字段然后存储截断后的值并告警,但不会报错退出);

3.2 ORACLE 和 MYSQL 对变长字段类型 VARCHAR 的存储处理类似,都不会对用户传入的实际的字符串进行加工处理,而是直接校验存储:

-如果用户传入的实际的字符串的长度,小于或等于 DDL 语句中声明的该 VARCHAR 字段的最大长度,则直接存储用户传入的值;(实际存储的数据,都是字段值的实际长度和字段的具体值);

  • 如果用户传入的实际的字符串的长度,大于 DDL 语句中声明的该 VARCHAR 字段的最大长度,ORACLE 和 MYSQL 都会报错(注意:MYSQL中,是报错还是截断,跟超长字段是正常字段还是 trailing spaces,以及是否是 STRICT SQL MODE 有关);

3.3 ORACLE 和 MYSQL 对变长字段类型 VARCHAR 的取出处理类似

  • ORACLE 和 MYSQL 对变长字段类型 VARCHAR 的取出处理类似,都不会对实际存储的字段值做加工处理,而是直接返回,因为存储时已经做了校验和加工。

3.4 ORACLE 和 MYSQL 中都是 VARCHAR(ORACLE 中是 VARCHAR2)的存储空间使用率更好

  • ORACLE 和 MYSQL 中都是 VARCHAR(ORACLE 中是 VARCHAR2)的存储空间使用率更好,因为 CHAR 类型字段在实际长度不够时会在末尾补充空格(blank-pads)并存储这些 trailing blanks 而 VARCHAR 不会,所以 VARCHAR 可以更有效地存储数据,空间使用率更高。

4 ORACLE 和 MYSQL 对 CHAR 和 VARCHAR 处理的不同点在哪里?

4.1 ORACLE 和 MYSQL 对 CHAR 和 VARCHAR 处理的不同点,体现在如何取出 CHAR 类型的字段数据上:

  • ORACLE 会将存储的值原封不动地取出,不做任何加工,所以通过LENGTH()函数返回的,就是 DDL 语句中声明的长度(当然底层存储时 pad 了 space);
  • MYSQL 会将存储的值最右边的空格全部截取后再取出,所以通过LENGTH()函数返回的,不是 DDL 语句中声明的长度,而是字段的实际有效长度(当然底层存储时 pad 了 space);

4.2 ORACLE 和 MYSQL 对 CHAR 和 VARCHAR 处理的不同点,体现在如何对比 CHAR 和 VARCHAR 类型的字段数据上:

  • Oracle 对 CHAR/NCHAR 采用的是 “blank-padded comparison semantics” 模式:如果对比的字段长度不同, Oracle 会在较短字段的末尾补充空格使得两者长度相同,然后再逐个字符进行比较。所以只有末尾空格数有差异的字段,对被认为是相等的字段;
  • Oracle 对 VARCHAR2/NVARCHAR2 采取的是 “non-padded comparison semantics” 模式:只有两个字段的长度相同且字符完全相同,才会被认为是相等的字段;
  • MySQL 对 CHAR, VARCHAR, 和 TEXT 采取的都是类似 ORACLE 的 “blank-padded comparison semantics” 的模式:即如果对比的字段长度不同, Oracle 会在较短字段的末尾补充空格使得两者长度相同,然后再逐个字符进行比较。所以只有末尾空格数有差异的字段,对被认为是相等的字段;

4 知识总结

  • ORACLE 和 MYSQL 都有对应变长字符串的数据类型,如 VARCHAR/VARCHAR2, 两者在数据的存储和取出上的处理类似;
  • ORACLE 和 MYSQL 都有对应定长字符串的数据类型,如 CHAR,两者对 CHAR 类型字段的存储处理类似,都会校验字段长度,并在字段不够时通过空格右补齐;
  • ORACLE 在取出 CHAR 类型字段时,不会做额外处理,会将存储的字段值直接取出;MYSQL 在取出 CHAR 类型字段时,会对存储的字段值做额外处理,会将字段最右端的空格截掉再返回;
  • Oracle 在对比 CHAR/NCHAR 类型字段时,采用的是 “blank-padded comparison semantics” 模式;
  • Oracle 在对比 VARCHAR2/NVARCHAR2 类型字段时,采取的是 “non-padded comparison semantics” 模式;
  • MySQL 在对比 CHAR, VARCHAR, 和 TEXT 类型字段时,采取的都是类似 ORACLE 的 “blank-padded comparison semantics” 的模式;

image.png

image.png

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
SQL NoSQL 关系型数据库
实时数仓Hologres发展问题之实时数仓的类数据库化与HTAP数据库的差异如何解决
实时数仓Hologres发展问题之实时数仓的类数据库化与HTAP数据库的差异如何解决
219 2
|
Cloud Native 数据管理 数据挖掘
核心系统转型问题之阿里云数据库用户需求的通用性和差异性如何平衡
核心系统转型问题之阿里云数据库用户需求的通用性和差异性如何平衡
164 0
|
11月前
|
Linux Shell 数据库
【YashanDB数据库】yasql登录有特殊字符@导致无法登录
【YashanDB数据库】yasql登录有特殊字符@导致无法登录
|
存储 Java Windows
java基础(9)数据类型中的char类型以及涉及到的转义字符
Java中的char类型可以存储一个中文字符,因为它占用两个字节。转义字符允许在代码中使用特殊字符,例如`\n`表示换行,`\t`表示制表符,`\\`表示反斜杠,`\'`表示单引号,`\"`表示双引号。可以使用`\u`后跟Unicode编码来表示特定的字符。
603 2
java基础(9)数据类型中的char类型以及涉及到的转义字符
|
存储 SQL JSON
介绍一下RDBMS和NoSQL数据库之间的区别
【10月更文挑战第21天】介绍一下RDBMS和NoSQL数据库之间的区别
520 2
|
关系型数据库 MySQL 数据库
MySQL数据库基础(数据库操作,常用数据类型,表的操作)
MySQL数据库基础(数据库操作,常用数据类型,表的操作)
189 5
|
存储 SQL 分布式数据库
深入解析HBase与关系数据库的关键差异
【8月更文挑战第31天】
514 1
|
存储 Oracle 关系型数据库
关系型数据库Oracle差异备份
【7月更文挑战第19天】
304 3
|
存储 数据管理 数据库
|
存储 SQL 数据库