Cassandra建表遇SyntaxException:UNIQUE关键字错误及修复方案
Cassandra创建表时UNIQUE约束报错的原因及修复方案
报错原因
Cassandra(以及同类型分布式NoSQL数据库)不支持在非主键列上使用UNIQUE约束。这是由它的分布式架构设计决定的:强制跨节点的唯一约束会带来极高的一致性开销,违背了NoSQL数据库高可用、高性能的设计目标,因此语法层面直接禁用了这种写法。
修复方案
要实现user_id的唯一性,根据业务场景有两种可行方式:
方式1:将user_id设为主键(适合单用户对应单条图书记录的场景)
如果你的业务逻辑里一个用户只对应一本图书,可以直接把user_id设为表的主键,利用主键的天然唯一性来约束:
CREATE KEYSPACE IF NOT EXISTS books WITH REPLICATION = { 'class': 'SimpleStrategy', 'replication_factor': 3 }; CREATE TABLE IF NOT EXISTS books ( user_id TEXT PRIMARY KEY, id UUID NOT NULL, scale TEXT NOT NULL, title TEXT NOT NULL, description TEXT NOT NULL, reward map<INT,TEXT> NOT NULL, image_url TEXT NOT NULL, video_url TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
方式2:创建反向查找表(适合单用户对应多条图书记录的场景)
如果一个用户需要对应多本图书,就需要额外创建一张专门的约束表,通过插入时的主键冲突来保证user_id唯一:
- 先创建主表(移除
UNIQUE关键字):
CREATE KEYSPACE IF NOT EXISTS books WITH REPLICATION = { 'class': 'SimpleStrategy', 'replication_factor': 3 }; CREATE TABLE IF NOT EXISTS books ( id UUID PRIMARY KEY, user_id TEXT NOT NULL, scale TEXT NOT NULL, title TEXT NOT NULL, description TEXT NOT NULL, reward map<INT,TEXT> NOT NULL, image_url TEXT NOT NULL, video_url TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
- 创建用于唯一约束的反向表:
CREATE TABLE IF NOT EXISTS books_by_user_id ( user_id TEXT PRIMARY KEY, book_id UUID NOT NULL );
- 插入数据时,先向
books_by_user_id表插入记录(主键重复会直接报错),确认插入成功后再写入主表,以此实现user_id的唯一性校验。
内容的提问来源于stack exchange,提问作者best_of_man
相关产品推荐
相关产品推荐

