主键“a”和“a ”被识别成相同主键,请问除了设置sql_mode以外,还有其他配置干扰吗?

【 TiDB 使用环境】生产环境
【 TiDB 版本】6.1.2 6.5
【复现路径】做过哪些操作出现的问题
【遇到的问题:问题现象及影响】主键“a”和“a ”被识别成相同主键,该字段为varchar,且为联合主键,sql_mode已经设置为 不忽略空格。请问还有其他配置项影响吗。
【资源配置】
sql_mode此时为STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH
【附件:截图/日志/监控】

不太明白要问什么?
表名(索引名 字段名)有特殊字符或者空格的时候,可以用反引号引起来,如:a,a

编辑出来格式有点问题,截图如下:

1 个赞


这个是mysql 5.7 测试结果。


这个是tidb v6.5.0测试结果

经过对比发现:似乎都会将第一个非空字符值开始计算,最后一个非空字符开始,删除后面的所有空字符

这种算吗?


https://docs.pingcap.com/zh/tidb/stable/character-set-and-collation

主键的特性:主键是为了标识数据库记录唯一性,不允许记录重复,且键值不能为空,主键也是一个特殊索引。

“a ”, "a ", "a " :这些值后面的空值都被自动过滤掉了


“ ”, " ", " ", 不管多少个空字符串 都会被视为kong

结论:字符前面或中间有空字符串,可以确定唯一性。最后一个字符串不能确定唯一性。也无法确定唯一性

1 个赞

你是要测试 varchar 对字符串中空格的处理方式吧

主键的唯一性?怎么确定存储的数据唯一,

编码规则的意义:
image

不管是iuft8_bin还是 utf8mb4_general_ci; 都违反主键唯一性

结论:在还没有存储就判断了。并且自动将最后一个非空字符串后面的空字符自动过滤掉

处理方式不一样,存储的内容不一样。 人家 boss咨询的是 “a” "a " 有什么区别对于主键。

抱歉确实是我表述有误。我表述的意思确实是 风华月貌 的意思。对于结尾带空格的varchar字段值,tidb往往自动将尾部空格去除,导致主键重复的错误。

非常感谢您的测试。经过我这两天的测试,发现问题可能出现在Tidb 6.0之后的排序规则的改动。

我分别测试了三种场景:
A、集群版本5.4.0
B、原集群版本5.4.0,升级到v6.5.0
C、集群版本6.1.2和6.5.0

发现A、B两个场景的 【new_collations_enabled_on_first_bootstrap】值均为false、C场景的值为True。这确实符合预期。因为新版本使用了新的排序规则支持。且该值只能在初次部署集群之前规定,无法后期修改。

但是测试尾部空格时发现,【new_collations_enabled_on_first_bootstrap】为 True 的集群时无法通过修改sql_mode 来规避 主键重复 这个错误。而 为False 的版本均可以正确处理尾部空格。

我不确认这是bug还是tidb修改了这个特性后做的限制。

你好
这是较新版本的 tidb 对于空格处理方式的改变。较新版本已与 mysql 行为一致,但实现方式不太一样。可以关注下 排序规则支持 中的新旧框架下的排序规则支持,其中有描述对末尾空格处理的支持。

这个应该去设置排序规则

此话题已在最后回复的 60 天后被自动关闭。不再允许新回复。