ITPub博客

首页 > 数据库 > 国内数据库 > OceanBase 中 MySQL/Oracle 模式中的 NULL 与空字符串

OceanBase 中 MySQL/Oracle 模式中的 NULL 与空字符串

原创 国内数据库 作者:瑞蓝创_RLC_888 时间:2026-07-09 10:24:56 0 删除 编辑

OceanBase 一套内核兼容 MySQL 和 Oracle 两种租户模式,但对NULL、''(空串)的底层处理逻辑天差地别。本文基于 OB V4.2.1.7 实测验证,把两种模式下存储、查询、COUNT 统计、唯一索引四大核心场景讲透,看完直接规避线上故障。

一、总结

【NULL 与空字符串】一句话核心总结:

  • MySQL 模式:空串 '' 是普通字符串,与 NULL 完全不同;

  • Oracle 模式:空串 '' 被视为 NULL,两者等价;

操作场景 OB Oracle 模式 OB MySQL 模式
插入空串 '' 自动转为 NULL 保持为空串 ''
空串是否为 NULL 是 否
NULL 与空串比较 不相等 不相等
COUNT(column) 不统计 NULL,不统计空串 不统计 NULL,统计空串
唯一索引中多个 NULL 不冲突(允许) 不冲突(允许)
唯一索引中多个空串 不冲突(因为被转为 NULL) 冲突(不允许)

二、验证步骤-MySQL 模式

2.1 准备环境

创建 test_mysql_260527 表并插入 3 条数据,分别是:空字符串,NULL,正常值;


mysql -h192.168.xxx.xxx -P2883 -uroot@mysql_251126
#ob_4255_251126 -p'xxx' -A -Dtest


CREATE  TABLE test_mysql_260527 (  id  INT, col_1  VARCHAR( 50));            -- 创建测试表
INSERT  INTO test_mysql_260527  VALUES ( 1,  ''), ( 2,  NULL), ( 3,  'abc');    -- 插入测试数据,分别是:空字符串,NULL,正常值;
-- DROP TABLE test_mysql_260527;  -- 清理测试表

Welcome to the MariaDB monitor.  Commands 
end 
with ; or \g.

Your MySQL connection id is 6572857
Server version: 5.6.25 OceanBase 4.2.1.7 (r107010022024060601-fe709b4735794f5e577d5b14f91d9183a12f101e) (Built Jun  6 2024 01:33:55)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type ' help;' or '\h' for help.  Type  '\c'  to  clear the  current  input statement.

MySQL [ test]>  CREATE  TABLE test_mysql_260527 (  id  INT, col_1  VARCHAR( 50));            -- 创建测试表
Query OK, 0 rows affected (0.39 sec)

MySQL [test]>  INSERT  INTO test_mysql_260527  VALUES ( 1,  ''), ( 2,  NULL), ( 3,  'abc');    -- 插入测试数据,分别是:空字符串,NULL,正常值;
Query OK, 3 rows affected (0.08 sec)
Records: 3  Duplicates: 0  Warnings: 0
2.2 验证 NULL 值和空字符串是否等价

在 V 4.2.1.7 版本的 MySQL 租户模式中,验证【null 值】和【''(即空值,空字符串)】的区别;验证结果:在 OB MySQL 模式中,以上 2 者是不等价的;



-- 【sql-01】查询空字符串(应返回 id=1 的行)

SELECT *  FROM test_mysql_260527  WHERE col_1 =  '';

-- 【sql-02】查询 NULL(应返回 id=2 的行)
SELECT *  FROM test_mysql_260527  WHERE col_1  IS  NULL;

-- 【sql-03】= NULL 语法不会返回任何结果(错误用法)
SELECT *  FROM test_mysql_260527  WHERE col_1 =  NULL;   -- 返回空集

MySQL [test]> 
SELECT * 
FROM test_mysql_260527 
WHERE col_1 = 
'';

+ ------+-------+
| id   | col_1 |
+ ------+-------+
|    1 |       |
+ ------+-------+
1 row in  set ( 0.01 sec)

MySQL [ test]>  SELECT *  FROM test_mysql_260527  WHERE col_1  IS  NULL;
+ ------+-------+
| id   | col_1 |
+ ------+-------+
|    2 | NULL  |
+ ------+-------+
1 row in  set ( 0.01 sec)

MySQL [ test]>  SELECT *  FROM test_mysql_260527  WHERE col_1 =  NULL;   -- 返回空集
Empty  set ( 0.00 sec)
2.3 验证 count 函数对 null 和 空字符串的处理

在 OB MySQL 模式中: count(col_1) 函数会忽略 NULL 值,所以预期结果为 2;



-- 【sql-04】验证 count 函数对 null 和 空字符串的处理(预期结果为:2)

SELECT  count(col_1)  FROM test_mysql_260527;

MySQL [test]> 
SELECT 
count(col_1) 
FROM test_mysql_260527;

+ --------------+
| count(col_1) |
+ --------------+
|            2 |
+ --------------+
1 row in  set ( 0.01 sec)
2.4 验证对唯一索引的影响

在 OB MySQL 模式中:唯一索引是允许 NULL 值重复的;空字符串是不允许重复的;所以第 1 条 insert 语句成功,第 2 条 insert 语句失败;



-- 【sql-05】验证对唯一索引的影响:

CREATE  UNIQUE  INDEX idx_unique_col_1  ON test_mysql_260527 (col_1);   -- 在 col_1 字段上创建唯一索引
INSERT  INTO test_mysql_260527  VALUES ( 4,  NULL);
INSERT  INTO test_mysql_260527  VALUES ( 5,  '');

MySQL [test]> 
CREATE 
UNIQUE 
INDEX idx_unique_col_1 
ON test_mysql_260527 (col_1);

Query OK, 0 rows affected (0.81 sec)

MySQL [test]>  INSERT  INTO test_mysql_260527  VALUES ( 4,  NULL);
Query OK, 1 row affected (0.01 sec)

MySQL [test]>  INSERT  INTO test_mysql_260527  VALUES ( 5,  '');
ERROR 1062 (23000): Duplicate entry '' for key 'idx_unique_col_1'

三、验证步骤-Oracle 模式

3.1 准备环境

创建 test_oracle_260527 表并插入 3 条数据,分别是:空字符串,NULL,正常值;


obclient -h192.168.xxx.xxx -P2883 -uSYS@oracle_250917
#ob_4255_251126 -p'xxx' -A


CREATE  TABLE test_oracle_260527 (  id  INT, col_1  VARCHAR( 50));            -- 创建测试表
INSERT  INTO test_oracle_260527  VALUES ( 1,  ''), ( 2,  NULL), ( 3,  'abc');    -- 插入测试数据,分别是:空字符串,NULL,正常值;
-- DROP TABLE test_oracle_260527;  -- 清理测试表

Welcome to the OceanBase.  Commands 
end 
with ; or \g.

Your OceanBase connection id is 6572969
Server version: OceanBase 4.2.1.7 (r107010022024060601-fe709b4735794f5e577d5b14f91d9183a12f101e) (Built Jun  6 2024 01:33:55)

Copyright (c) 2000, 2018, OceanBase and/or its affiliates. All rights reserved.

Type ' help;' or '\h' for help.  Type  '\c'  to  clear the  current  input statement.

obclient( SYS@oracle_250917)[ SYS]>  CREATE  TABLE test_oracle_260527 (  id  INT, col_1  VARCHAR( 50));            -- 创建测试表
Query OK, 0 rows affected (0.369 sec)

obclient(SYS@oracle_250917)[SYS]>  INSERT  INTO test_oracle_260527  VALUES ( 1,  ''), ( 2,  NULL), ( 3,  'abc');    -- 插入测试数据,分别是:空字符串,NULL,正常值;
Query OK, 3 rows affected (0.054 sec)
Records: 3  Duplicates: 0  Warnings: 0
3.2 验证 NULL 值和空字符串是否等价

使用 insert into 语句插入【 ''(空字符串)】时,OB 会自动将其转换成 NULL 值并存储,但是在查询时(where 条件中),若使用【 ''(空字符串)】则不能查出数据,必须使用 IS NULL 或 IS NOT NULL;



-- 【sql-01】查询空字符串(返回空集)

SELECT *  FROM test_oracle_260527  WHERE col_1 =  '';

-- 【sql-02】查询 NULL(应返回 id = 1/2 的行)
SELECT *  FROM test_oracle_260527  WHERE col_1  IS  NULL;

-- 【sql-03】= NULL 语法不会返回任何结果(错误用法)(返回空集)
SELECT *  FROM test_oracle_260527  WHERE col_1 =  NULL; 

obclient(SYS@oracle_250917)[SYS]> 
SELECT * 
FROM test_oracle_260527 
WHERE col_1 = 
'';

Empty  set ( 0.002 sec)

obclient( SYS@oracle_250917)[ SYS]>  SELECT *  FROM test_oracle_260527  WHERE col_1  IS  NULL;
+ ------+-------+
| ID   | COL_1 |
+ ------+-------+
|    1 | NULL  |
|    2 | NULL  |
+ ------+-------+
2 rows in  set ( 0.008 sec)

obclient( SYS@oracle_250917)[ SYS]>  SELECT *  FROM test_oracle_260527  WHERE col_1 =  NULL; 
Empty  set ( 0.004 sec)
3.3 验证 count 函数对 null 和 空字符串的处理

在 OB Oracle 模式中: count(col_1) 函数会忽略 NULL 值,正常来说查询结果应该为 2,但是在 OB Oracle 模式中,会将【 ''(空字符串)】转换成 NULL 值并存储,所以查询结果预期为 1;



-- 【sql-04】验证 count 函数对 null 和 空字符串的处理(预期结果为:1)

SELECT  count(col_1)  FROM test_oracle_260527;
obclient(SYS@oracle_250917)[SYS]> SELECT count(col_1) FROM test_oracle_260527;
+--------------+
| COUNT(COL_1) |
+--------------+
|            1 |
+--------------+
1 row in set (0.003 sec)
3.4 验证对唯一索引的影响

在 OB Oracle 模式中:唯一索引是允许 NULL 值重复的;空字符串会被转换成 NULL 值并存储,所以也是允许重复的;即 2 条 insert 语句都能执行成功;



-- 【sql-05】验证对唯一索引的影响:

CREATE  UNIQUE  INDEX idx_unique_col_1  ON test_oracle_260527 (col_1);   -- 在 col_1 字段上创建唯一索引
INSERT  INTO test_oracle_260527  VALUES ( 4,  NULL);
INSERT  INTO test_oracle_260527  VALUES ( 5,  '');

obclient(SYS@oracle_250917)[SYS]> 
CREATE 
UNIQUE 
INDEX idx_unique_col_1 
ON test_oracle_260527 (col_1); 

Query OK, 0 rows affected (0.864 sec)

obclient(SYS@oracle_250917)[SYS]>  INSERT  INTO test_oracle_260527  VALUES ( 4,  NULL);
Query OK, 1 row affected (0.003 sec)

obclient(SYS@oracle_250917)[SYS]>  INSERT  INTO test_oracle_260527  VALUES ( 5,  '');
Query OK, 1 row affected (0.003 sec)

PS:本文关于以上所有验证都是在 V 4.2.1.7 版本的 OB 集群中进行。

如果在操作过程中遇到问题,欢迎在评论区留言交流,后续我们会持续分享更多实战运维干货,记得  关注不迷路,下次见~

暂无图片



来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70047467/viewspace-3175512/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
专注于企业信息科技战略咨询、数据中心规划及运维、智能化软件产品研发,致力于为金融、能源、电信、制造等行业提供智能的业务永续及流程自动化解决方案。

注册时间:2025-09-08

  • 博文量
    89
  • 访问量
    86737