1

次のような数値:

0.000000000000000000000000000000000000000123456

postgres で使用可能な数値型を使用して、パフォーマンスを大幅に低下させずに格納することは困難です。この質問は同様の問題に対処していますが、受け入れられる解決策に達したとは思いません。現在、私の同僚の 1 人は、このような数値を小数点以下 15 桁に丸め、次のように格納することにしました。

0.000000000000001

倍精度数値型を使用できるようにすることで、10 進数値型への移行に伴うペナルティを回避できます。私の目的にとってこのように小さい数値は、どちらも非常に小さい (そしてほぼ同じことを意味する) ため、多かれ少なかれ機能的に同等です。ただし、これらの結果をグラフ化しており、データセットの大部分がこのように丸められると、非常に愚かに見えます (グラフの平らな線)。

ここに画像の説明を入力

これらの数値を何万も保存して操作しているため、10 進数の数値型はパフォーマンスのペナルティが大きすぎるため、適切なオプションではありません。

私は科学者であり、これらの種類の数値を科学表記法で保存するのが私の自然な傾向ですが、postgres にこの種の機能があるようには見えません。実際には数値のすべての精度は必要ありません。4桁程度を保持したいだけなので、float数値型が提供する15桁も必要ありません。これらの数値を次のように 2 つのフィールドに格納することの利点と欠点は何ですか。

1.234 (real)
-40 (smallint)

これは 1.234*10^-40 に相当しますか? これにより、最大 32000 の先頭の 10 進数を格納するために使用される 2 バイトと実際の値を格納するために 4 バイトのみが使用され、数値ごとに合計で最大 6 バイトになります (格納したい正確な数値が得られ、 8 バイトを消費する既存のソリューション)。また、最初に smallint フィールドをソートし、次に real フィールドをソートするだけでよいため、これらの数値のソートは大幅に改善されるようです。

4

2 に答える 2

3

あなたやあなたの同僚は、浮動小数点形式を使用して表現できる数値について混乱しているようです。

(double precision別名float) 数値は、約 1e-307 から 1e+308 の範囲で、少なくとも 15 桁の有効数字を格納できます。あなたはそれを科学的表記法と考えなければなりません。すべてのゼロを削除し、それを指数に移動します。科学的表記法で一度持っていたものが 15 桁未満で、指数が -307 から +308 の間である場合は、そのまま保存できます。

つまり、それ0.000000000000000000000000000000000000000123456は間違いなく として保存できdouble precision、すべての有効数字 ( 123456) を保持できます。それを丸める必要はありません0.000000000000001

浮動小数点数には、10 進数の正確な表現に関するよく知られた問題があります (基数 10 の 10 進数が基数 2 の 10 進数にマップされるとは限らないため) が、それはおそらく問題ではありません (必要な場合は問題です)。そのような数値で正確な比較を行うことができます)。

于 2016-02-07T23:12:37.583 に答える
0

これらの数値をこのように 2 つのフィールドに格納することの長所と短所は何ですか?

1 つではなく 2 つの列を管理する必要があります。

大まかに言えば、精度の低い浮動小数点数を格納してスペースを節約することになります。4 桁の精度のみが必要な場合は、さらに進んで、smallint + smallint (1000-9999 + exponent) を使用してさらに 2 バイトを節約できます。その形式を使用すると、2 つの smallint を 1 つの 32 ビット int (指数 * 2^16 + 仮数) に詰め込むことができます。これも機能するはずです。

これは、記憶域を節約する必要がある、および/または倍精度浮動小数点数の +/-308 桁の指数制限を超える必要があることを前提としています。そうでない場合は、標準フォーマットで問題ありません。

于 2016-02-07T23:02:29.110 に答える