我可以添加到数据库中的Cassandra十进制类型的最大允许数是多少而不会爆炸。
答案 0 :(得分:0)
decimal
是Java java.math.BigDecimal
(see CQL documentation)。由于它具有任意精度,因此受限于Cassandra对单元格大小的限制,即2Gb max(建议使用1Mb)。 Here is good discussion关于BigDecimal类的限制,以及Cassandra限制的here is a list。
答案 1 :(得分:0)
我原以为在网上很容易找到这个问题的答案,但我很惊讶它绝对不是:-(所以我开始自己弄清楚:
Cassandra documentation 只是说 decimal
类型是“可变精度”,但没有给出关于其精度或规模是否有任何限制的任何线索。 Cassandra 的 Datastax's documentation 提供了一个额外的线索:这种类型是使用 Java 的 java.math.BigDecimal
实现的。所以给人的印象是,要了解其限制,您需要检查 Java's BigDecimal documentation。该文档声称 BigDecimal 的 scale(十进制尾数)是一个 32 位有符号整数。 unscaled 值是一个无限的整数(虽然在实践中显然受内存限制)。
这一切意味着什么?
首先,有一个smallest(最接近于零的)可表示值,它是最小整数(1)乘以最负比例(-2147483648
),所以最小值是10^-2147483648
。
对于最大可表示值没有这样的限制。最大的标度是 10^2147483647
但乘以这个未标度的值是一个可以任意大的整数!然而,有一个问题——对于更高的数字,我们不能再有效地表示 10 的幂。数字 10^3147483647
需要表示 10 亿位数字,除一位外,所有数字都为零。
说了这么多,问题来了,Cassandra 是否真的使用了这么高的数字。如果您尝试使用 CQL 命令将微不足道的 10^309
分配给十进制列
INSERT INTO tab (p, dec) VALUES (0, 1e309)
结果是神秘的消息:
Failed parsing statement: [INSERT INTO tab (p, dec) VALUES (0, 1e309)] reason: NumberFormatException null
事实证明,尽管该语句根本没有分配双精度值,但对于超过 double 值的最大值(略高于 1e308
),这样的语句将失败!
然而,一切都没有丢失。可以使用准备好的语句插入更大的数字。例如,使用 Python CQL 驱动程序,您可以执行以下操作:
stmt = cql.prepare(f"INSERT INTO {table1} (p, dec) VALUES ({p}, ?)")
cql.execute(stmt, [Decimal('1e10000')])
这按预期工作。
由于上面的解释,1e2147483647
效果很好。
1e2147483648
也是如此。
如果您尝试使用更大的指数,Cassandra Python 驱动程序会出现错误 - 例如,如果您尝试使用 1e2147483649
,则会导致来自 Python 驱动程序的神秘错误消息:
E TypeError: Received an argument of invalid type for column "dec". Expected: <class 'cassandra.cqltypes.DecimalType'>, Got: <class 'decimal.Decimal'>; ('i' format requires -2147483648 <= number <= 2147483647)
但这仍然不是限制 - 您可以编写 10000e2147483648
并且结果有效,并且意味着 1e2147483652
。
这证明了我上面的说法,1e2147483647
不是一个硬性限制,但在以下情况下,您仍然明智地将自己限制在该数字上: 1. 您希望它可以在 Python 驱动程序中轻松表示,和 2. 如果您不希望这些只有一位有效数字但规模很大的数字占用大量内存。