Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Postgresql中高效地存储具有多个前导零的十进制数_Postgresql_Precision_Leading Zero - Fatal编程技术网

在Postgresql中高效地存储具有多个前导零的十进制数

在Postgresql中高效地存储具有多个前导零的十进制数,postgresql,precision,leading-zero,Postgresql,Precision,Leading Zero,像这样的数字: 0.000000000000000000000000000000000000000123456 在postgres中使用可用的数字类型时,如果没有较大的性能损失,则很难存储。这解决了一个类似的问题,但我觉得这并不是一个可以接受的解决方案。目前,我的一位同事将这样的数字四舍五入到小数点后15位,并将其存储为: 0.000000000000001 因此,可以使用双精度数字类型,以防止与移动到十进制数字类型相关的惩罚。就我而言,这么小的数字在功能上或多或少是等效的,因为它们都非常小

像这样的数字:

0.000000000000000000000000000000000000000123456
在postgres中使用可用的数字类型时,如果没有较大的性能损失,则很难存储。这解决了一个类似的问题,但我觉得这并不是一个可以接受的解决方案。目前,我的一位同事将这样的数字四舍五入到小数点后15位,并将其存储为:

0.000000000000001
因此,可以使用双精度数字类型,以防止与移动到十进制数字类型相关的惩罚。就我而言,这么小的数字在功能上或多或少是等效的,因为它们都非常小(并且意味着或多或少相同的东西)。然而,我们正在绘制这些结果,当数据集的很大一部分像这样四舍五入时,它看起来异常愚蠢(图上的平面线)

因为我们存储了成千上万个这样的数字并对它们进行操作,所以十进制数字类型对我们来说不是一个好的选择,因为性能损失太大了

我是一名科学家,我的自然倾向是将这些类型的数字存储在科学记数法中,但postgres似乎没有这种功能。实际上我并不需要数字的所有精度,我只想保留4位左右,所以我甚至不需要浮点数字类型提供的15位数字将这些数字存储在如下两个字段中的优点和缺点是什么:

1.234 (real)
-40 (smallint)
其中这相当于1.234*10^-40?这将允许约32000个前导小数,其中只有2个字节用于存储它们,4个字节用于存储实际值,每个数字最多6个字节(提供了我要存储的确切数字,并且比现有解决方案占用的空间更少,该解决方案消耗8个字节)。看起来对这些数字的排序也会有很大的改进,因为您只需要先对smallint字段进行排序,然后再对实字段进行排序

将这些数字存储在内存中的优点和缺点是什么 像这样的两个领域

您必须管理两列,而不是一列

大致来说,您将要做的是通过存储精度较低的浮点值来节省空间。如果您只需要4位精度,则可以进一步使用smallint+smallint(1000-9999+exponent)再节省2个字节。使用这种格式,您可以将两个smallint填充到一个32位int(指数*2^16+尾数)中,这应该也可以


这是假设您需要节省存储空间和/或需要超出双精度浮点的+/-308位指数限制。如果不是这样,标准格式就可以了。

您和/或您的同事似乎对使用浮点格式可以表示哪些数字感到困惑

一个
双精度
(又称
浮点
)数字可以存储至少15个有效数字,范围大约在1e-307到1e+308之间。你必须把它看作是科学符号。删除所有零并将其移动到指数。如果科学记数法中的任何一个数字少于15位,且指数介于-307和+308之间,则可以按原样存储

这意味着
0.000000000000000000000000000123456
绝对可以存储为
双精度
,并且您将保留所有有效数字(
123456
)。无需将其四舍五入到
0.00000000000001
或类似的值


浮点数有一个众所周知的问题,即十进制数的精确表示(因为10进制的十进制数不一定映射到2进制的十进制数),但这对您来说可能不是问题(如果您需要能够对这些数字进行精确比较,这是个问题)。

我肯定不明白。双精度数字的IEEE标准8字节格式允许将非常小的数字表示为有效位和指数。如果你能接受大约15位的精度,为什么不使用双精度格式?@scottb因为,正如我在问题中提到的,将所有结果舍入到15位精度会导致我的图形在该精度下变平,所以尽管数据的含义在功能上是等效的,显示看起来很糟糕。如果您的图形是“扁平化”的,则更有可能是图形的缩放或无意中将值转换为整数类型存在问题。IEEE双精度数字能够代表非常小的数字,达到精度极限,因为它们是非常大的数字。特别是,正如您所建议的,在数据库中单独存储有效位和指数应该没有什么好处,因为这就是双精度数字在内部的表示方式。“将所有结果四舍五入到15位精度会导致我的图形平直”。。。我只是想澄清一下。你在文章中描述的并不是精确到15位数。事实上,你在操作中失去了很多精确性。更准确地说,结果被截断为1个有效数字。完全同意@scottb,使用
双精度
aka
浮点
有什么问题?你确定你没有在Postgresql和图形之间的链中进行取整/截断吗?当然,如果您的数字实际上更像
123.000000000000000456
而不是
0..000000000000000456
,您将遇到一个问题,但对于其他表示法也是如此。谢谢您的帮助。我很可能会将此标记为正确答案。既然@scottb已经让我走上了正确的道路,我会给他一个机会,让他先回答,如果他愿意的话,然后选择最好的答案。@sage88所以你不需要节省空间,也不需要多达32000个小数,那么。。。?