ycql与ysql协议层完全不同:ycql兼容cassandra的cql协议,需用datastax驱动;ysql兼容postgresql协议,须用libpq等pg驱动;混用会因协议版本错位直接报错。

YCQL 和 YSQL 的协议层根本不同,别指望用同一套驱动连通两者
YCQL 是 Cassandra 兼容的 CQL 协议实现,走的是 cqlsh、DataStax Java Driver 这条线;YSQL 则是 PostgreSQL 协议兼容,必须用 libpq、psycopg2、pgx 等 PG 生态驱动。混用会直接报错,比如用 Java Driver 连 ysqlsh 端口(5433),收到的响应是 Protocol error: Expected protocol version 4, got 196608 —— 那是 PostgreSQL 协议 magic number 被当成了 CQL 版本号。
实操建议:
- 确认连接端口:
yb-tserver默认开9042(YCQL)和5433(YSQL),别靠猜 - 检查驱动依赖:Java 项目里同时引了
java-driver-core和postgresqljar?那得拆成两个模块,各自配独立数据源 - Docker 启动时注意服务暴露:
-p 9042:9042 -p 5433:5433要写全,否则本地连不上对应协议
INSERT/UPDATE 的语义差异会让应用逻辑悄悄出错
YCQL 的 INSERT 默认是 upsert(存在则覆盖),而 YSQL 的 INSERT 默认报错(duplicate key violates unique constraint)。更隐蔽的是 TTL 行为:YCQL 支持 per-row TTL(USING TTL 3600),YSQL 不支持原生 TTL,得靠后台 job 或 pg_cron + DELETE 模拟。
实操建议:
- 写入逻辑含“存在即更新”意图时:YCQL 可直接
INSERT;YSQL 必须用INSERT ... ON CONFLICT DO UPDATE - 需要自动过期数据:选 YCQL;若已用 YSQL,别硬套
EXPIRE IN语法——那会报Syntax error: extraneous input 'IN' - 批量写入性能敏感场景:YCQL 的轻量级事务 + 分区键局部性通常比 YSQL 的 MVCC 写放大更低,但前提是主键设计合理
JOIN 和子查询能力差距大,别在 YCQL 里硬写复杂分析 SQL
YCQL 的 SELECT 不支持 JOIN、不支持 GROUP BY(除单表聚合)、不支持相关子查询。所谓“SQL-like”只是表象。YSQL 支持完整 PostgreSQL 11+ 的查询能力(含窗口函数、CTE、LATERAL),但代价是跨分片 JOIN 可能触发广播或落盘临时表,延迟明显升高。
实操建议:
- 要做多表关联统计?只能用 YSQL,但得加
/*+ SET enable_mergejoin=off */提示避免低效计划(YugabyteDB 3.4+ 支持 hint) - YCQL 里想“模拟 JOIN”?别拼应用层多次查询再 merge——网络往返叠加序列化开销可能比 YSQL 一次 JOIN 还慢
- 分页需求强(
LIMIT/OFFSET)且数据量大:YSQL 的游标分页(WHERE id > $last_id)比 YCQL 的ALLOW FILTERING更稳,后者在非主键条件上扫全表风险极高
事务隔离级别和一致性模型实际表现不一致
YSQL 声称支持 READ COMMITTED 和 REPEATABLE READ,但底层仍基于分布式 Raft + Hybrid Logical Clocks,无法做到传统 PostgreSQL 的快照隔离强度;YCQL 默认是 LOCAL_QUORUM 读写,不提供跨分区事务,所谓“轻量级事务(LWT)”仅限单行 IF EXISTS,且吞吐骤降 5–10 倍。
实操建议:
- 强一致性更新(如库存扣减):YSQL 的
SELECT FOR UPDATE比 YCQL LWT 更可靠,但要避免长事务阻塞 - 高并发计数器场景:YCQL 的
COUNTER类型是原子的,YSQL 得靠UPDATE ... SET count = count + 1,若无索引支撑易成热点 - 跨表/跨行事务必要时:只能选 YSQL,但得接受它不是 ACID 完整体——比如
REPEATABLE READ下仍可能读到其他事务中途提交的部分结果
真正麻烦的不是语法像不像,而是协议栈、事务引擎、索引结构、甚至时钟同步机制都分属两套系统。换驱动只是第一步,业务逻辑里的假设得一条条重验。











