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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 对比下不同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

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3月前
|
SQL NoSQL 关系型数据库
实时数仓Hologres发展问题之实时数仓的类数据库化与HTAP数据库的差异如何解决
实时数仓Hologres发展问题之实时数仓的类数据库化与HTAP数据库的差异如何解决
54 2
|
3月前
|
Cloud Native 数据管理 数据挖掘
核心系统转型问题之阿里云数据库用户需求的通用性和差异性如何平衡
核心系统转型问题之阿里云数据库用户需求的通用性和差异性如何平衡
|
25天前
|
存储 SQL JSON
介绍一下RDBMS和NoSQL数据库之间的区别
【10月更文挑战第21天】介绍一下RDBMS和NoSQL数据库之间的区别
54 2
|
2月前
|
存储 Java Windows
java基础(9)数据类型中的char类型以及涉及到的转义字符
Java中的char类型可以存储一个中文字符,因为它占用两个字节。转义字符允许在代码中使用特殊字符,例如`\n`表示换行,`\t`表示制表符,`\\`表示反斜杠,`\'`表示单引号,`\"`表示双引号。可以使用`\u`后跟Unicode编码来表示特定的字符。
56 2
java基础(9)数据类型中的char类型以及涉及到的转义字符
|
1月前
|
关系型数据库 MySQL 数据库
MySQL数据库基础(数据库操作,常用数据类型,表的操作)
MySQL数据库基础(数据库操作,常用数据类型,表的操作)
34 5
|
5月前
|
存储 关系型数据库 MySQL
MySQL数据库的数据类型、语法和高级查询
MySQL数据库的数据类型、语法和高级查询
72 0
|
3月前
|
存储 数据管理 数据库
|
3月前
|
存储 SQL 数据库
|
3月前
|
存储 SQL 分布式数据库
|
3月前
|
SQL 关系型数据库 MySQL
SQL Server、MySQL、PostgreSQL:主流数据库SQL语法异同比较——深入探讨数据类型、分页查询、表创建与数据插入、函数和索引等关键语法差异,为跨数据库开发提供实用指导
【8月更文挑战第31天】SQL Server、MySQL和PostgreSQL是当今最流行的关系型数据库管理系统,均使用SQL作为查询语言,但在语法和功能实现上存在差异。本文将比较它们在数据类型、分页查询、创建和插入数据以及函数和索引等方面的异同,帮助开发者更好地理解和使用这些数据库。尽管它们共用SQL语言,但每个系统都有独特的语法规则,了解这些差异有助于提升开发效率和项目成功率。
376 0