我试图存储一个非常大的数字,它大于整数和实数字段类型可以容纳的8字节。我需要能够返回该字段中包含小于或大于我指定的另一个大数字的行。我不知道怎么做。似乎我唯一的选择是将它存储为文本,但是当我尝试在查询中使用>和感谢任何帮助。
谢谢!
最佳答案
对于存储,您唯一的选择是文本或blob,因此您必须以某种方式对数字进行编码,以便词典和数字顺序相同。
对于无符号数字,可以使用类似于sqlite4的varint
encoding机制:
让编码的字节称为a0,a1,a2,…,a8。
如果a0介于0和240之间(包括0和240),则结果为a0的值。
如果a0介于241和248之间(包括241和248),则结果为240+256*(a0-241)+a1。
如果a0是249,则结果是2287+256*a1+a2。
如果a0是250,那么结果是a1..a3,作为一个3字节的大端整数。
如果a0是251,则结果是a1..a4,作为一个4字节的大端整数。
如果a0是252,则结果是a1..a5,作为一个5字节的大端整数。
如果a0是253,则结果是a1..a6,作为一个6字节的大端整数。
如果a0是254,则结果是a1..a7,作为7字节的大端整数。
如果a0是255,那么结果是a1..a8,作为一个8字节的大端整数。
上面的设计最多可用于64位数字。
只要你有一个上界,把这个机制扩展到更大的数字是微不足道的。
如果可以对数字进行签名,则必须将A0
范围一分为二,并将前半部分用于负数。
如果不需要进行计算,则可以使用相同的原理来存储ascii数字,而不是二进制值。
也就是说,使用一个固定长度的前缀来指定数字的长度,然后是数字。
假设您的号码不超过9999位,则可以使用前缀长度4,例如:
0001|0 ...
0001|9
0002|10 ...
0002|99
0003|100 ...
0060|321741185926535897932384626433832795281828459045235360287471
如果这里需要负值,则必须为正确排序的负数/正数选择一个附加前缀(ascii顺序
-
/+
错误,因此最好使用类似n
/p
的前缀)。你必须使用一个前缀,比如9999–length表示负数,这样较小的负数就有一个较小的前缀。