腾讯云 TDSQL PostgreSQL 版 无法创建唯一索引问题

5 小时 41 分钟前
 wuhunyu

问题描述

假设我的建表语句是

create table users
(
    id        bigint primary key,
    user_name varchar(120) not null
);

现在想要为 user_name 字段新增一个唯一索引。如果是在 postgresql 中,如下 sql 是可以正常执行的

create unique index uni_user_name on users (user_name);

但在 TDSQL 环境下,这条 sql 执行失败了,报错提示

ERROR:  Unique index of partitioned table must contain the hash/modulo distribution column.

探索

TDSQL 是一款腾讯开发的分布式数据库系统,近期公司有打算兼容 TDSQL 。目前使用的数据库是 postgresql 。迁移数据时遇到了一个有关唯一索引的问题

以下是 TDSQL 官网的资料:

  1. 非 shard key 字段不能建立唯一索引
  2. 不指定 shard key 建表方法,系统默认使用第一个字段作为表的 shard key

分布键选择原则:

创建和删除数据表

创建和删除索引

尝试解决

  1. 将唯一索引的创建语句修改为包含 shard key
create table users
(
    id        bigint primary key,
    user_name varchar(120) not null
) distribute by shard(id);

create unique index uni_user_name_id on users (user_name, id);

可以正常执行,但这个组合的唯一索引失去了 user_name 字段唯一的限制

  1. user_name 设置为 shard key
create table users
(
    id        bigint,
    user_name varchar(120) not null
) distribute by shard(user_name);

create unique index uni_user_name on users (user_name);

这种情况下,如果表有多个唯一索引,也是不行的,因为 shard key 只能是一个字段,更不要说我的业务里面还有组合的唯一索引

  1. 创建一个新表,命名为 uni_users_user_name,将 user_name 作为主键和 shard key 。创建一个触发器,在新增或者修改时,也去修改 uni_users_user_name,通过 uni_users_user_name 来校验 user_name 是否唯一

这种方案我并没有实践,一方面触发器现在已经很少使用了,使用的话会对现有的业务造成哪些影响也需要评估。另一方面,多个唯一索引需要建立多张表,如果组合唯一索引的话,又应该怎么处理呢?

create table uni_users_user_name
(
    user_name varchar(120) primary key,
    id        bigint
) distribute by shard(user_name);

我的疑问

我想这个问题应该在其他分布式数据库中也存在的,但目前好像并没有好的解决方案。我去咨询了官方客服,她们给我的反馈是分布式数据库是有挺多的限制,建议我使用她们的 postgresql

我想问问各位,有没有较好的方案可以在不改动业务,或者小改动的情况下,解决业务上强依赖数据库唯一索引的问题

340 次点击
所在节点    程序员
6 条回复
mark2025
5 小时 18 分钟前
普通项目根本用不到分布式数据库,单机 pg 数据库足以。不要自己给自己挖坑
mark2025
5 小时 15 分钟前
分布式数据库是不是伪需求?
https://pigsty.cc/zh/blog/db/distributive-bullshit/
wuhunyu
5 小时 4 分钟前
@mark2025 领导想要适配 TDSQL ,我也清楚现在的系统即便迁移到了分布式数据库,但没有改造 sql ,性能可能会不如单机的 pg
263
4 小时 56 分钟前
其实可以用,TDSQL-C PostgreSQL 版

https://cloud.tencent.com/product/tdcpg
wuhunyu
4 小时 3 分钟前
@263 领导不买账呐,而且这个数据库的 pg 引擎都买不了
liuhan907
55 分钟前
@wuhunyu
用 CRDB 就没这个问题(

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1082970

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX