Cassandra中存储0.0-999999.99数值的类型选择及疑问
问题解决
1. Cassandra DECIMAL类型语法错误的原因及修复
Cassandra的DECIMAL是任意精度的十进制类型,语法上不需要像传统SQL那样指定(精度,刻度),你写的DECIMAL(8,2)是MySQL等关系型数据库的写法,Cassandra不支持这种格式,因此抛出语法错误。
修复后的建表语句:
CREATE TABLE IF NOT EXISTS products.test( id TEXT PRIMARY KEY, price DECIMAL);
该类型可完美覆盖0.0至999999.99的数值范围,且不会丢失精度。
2. NodeJS/TypeScript的number类型处理
JavaScript的number是双精度浮点数,存在小数运算精度丢失风险(比如0.1 + 0.2 !== 0.3),而Cassandra的DECIMAL在Node驱动(如cassandra-driver)中会映射为驱动自带的Decimal类型(types.Decimal),需要做简单的类型转换:
- 存入数据:将
number转换为驱动的Decimal,例如new types.Decimal(price); - 取出数据:可将
Decimal转换为number(你的数值范围完全在number安全范围内),或直接保留Decimal类型用于计算,避免精度丢失。
示例TypeScript代码:
import { Client, types } from 'cassandra-driver'; const client = new Client({ /* 数据库配置 */ }); // 存入数据 const saveProduct = async (id: string, price: number) => { await client.execute( 'INSERT INTO products.test (id, price) VALUES (?, ?)', [id, new types.Decimal(price)] ); }; // 查询数据 const getProduct = async (id: string) => { const result = await client.execute('SELECT * FROM products.test WHERE id = ?', [id]); const product = result.first(); if (product) { // 转换为number类型 product.price = product.price.toNumber(); } return product; };
3. 是否选择string类型更合适?
需结合业务场景判断:
- 不推荐用string的场景:如果需要在Cassandra中对price做数值运算(如筛选
price > 100的商品),string无法直接支持,必须先转换,效率低且易出错; - 可考虑string的场景:如果仅需存储和展示价格,不需要数据库层面的数值操作,用string存储格式化后的字符串(如"999999.99")可避免精度转换问题,但需前后端统一格式(如固定两位小数)。
综合来看,使用DECIMAL类型是更标准的方案,既符合数值存储规范,又能支持后续数值操作,只需做好前后端类型转换即可。
内容的提问来源于stack exchange,提问作者lovecode
相关产品推荐
相关产品推荐

