【问题标题】:What are the options for storing Python long integers in MySQL?在 MySQL 中存储 Python 长整数的选项有哪些?
【发布时间】:2013-06-01 00:26:41
【问题描述】:

我需要在 MySQL 中表示 Python“长整数”的实例。我想知道我应该使用哪种最合适的 SQL 数据类型。

Python 文档 (v2.7) 说(对于 numbers.Integral):

长整数

这些代表无限范围内的数字,仅受可用(虚拟)内存的限制。出于移位和掩码操作的目的,假设使用二进制表示,负数表示为 2 的补码的变体,这给人一种向左延伸的无限符号位串的错觉。

我对 MySQL 文档的阅读表明 BIGINT 仅限于 64 位。 DECIMAL 类型似乎限制为 65 位。当然,我可以使用 BLOB。

应用程序需要支持非常大量的数据,但我还不知道这些长整数可能会有多大,也不知道我可能会看到多少。

我想保留 Python 长整数定义的精神,它建议使用 BLOB。我还想避免重新发明轮子,所以我呼吁 stackoverflow hive-mind。

建议?

【问题讨论】:

    标签: python mysql mysql-python


    【解决方案1】:

    是的,如果您真的需要无限精度,那么您将不得不使用 blob,因为即使是 strigns 也是有限的。

    但实际上,我几乎可以保证您可以使用 NUMERIC/DECIMAL 数据类型。 65 位表示可以表示 (-10^65, 10^65) 范围内的数字。这是多大?给你一些想法:整个宇宙中的原子数量估计约为10 ^ 80。如果您只需要正数,您可以通过预先减去 10^65 -1 将范围进一步扩大 2 倍。

    【讨论】:

    • 每种数据类型都有一定的界限(虚拟内存也是一个界限);那么问题是允许实际数据是什么以及哪种数据类型最能支持这种情况。
    • @user2246674 除了由于内存/硬盘驱动器限制而出现的限制之外,MySQL 是否定义了对 blob 大小的任何限制?显然,由于我们没有无限资源这一事实,一切都是有限的,但是在拥有像 VARCHAR(1000) 这样的固定最大大小和您不必明确指定上限的 BLOB 之间存在很大差异
    • 听起来我最终会得到一个 BLOB。我喜欢使用pickle(或类似的东西)转换为字符串的建议(我想知道base64)。
    • 我决定使用 blob。我已经有了处理持久字符串的表,所以我可以使用它们。首先,我将原生 long 拆分为一个字节数组。然后我对结果进行base64编码,并将其存储。我反转加载过程。我已经确认它适用于我下面的示例 ((2**64)**1024 - 1),并且消耗 10K 字节而不是 pickle/str 的 19K+ 字节。
    • @Tom 如果你真的存储这么大的数字,那么我真的会使用 blob 而不是 base64 编码的字符串,它们的开销为 33%。如果您使用的是 ORM(如果不是您真的应该使用),那么实现起来应该很简单,否则也不应该太难。 ((2**64)**1024 - 1) 应该只花费你 7.5k 字节来存储。
    【解决方案2】:

    您可以腌制并存储为字符串。也许将字符串限制为 VARCHAR(1000)?真的可以比这更长吗?您必须对您的应用有所了解。

    >>> pickle.dumps(x)
    'L122222222222222222222222222222222222222222222222222222222222222222223L\n.'
    >>> x
    122222222222222222222222222222222222222222222222222222222222222222223L
    >>> 
    

    【讨论】:

    • 啊,这个想法很有趣。知道 pickle.dump(aLong) 的长度与 str(aLong) 相比如何吗?
    • @DavidJashi 我不喜欢 BLOB,我宁愿拥有像 VARCHAR 这样更常见和更便携的东西。
    • 经过编辑和汤姆澄清他的需求后,您的解决方案更有意义。
    • 尝试“aLargeInteger=(2**64)**1024 - 1”。当我腌制它时,我得到了 19,729 个字符。然而aLargeInteger.bit_length()/8 = 8,192。再加上 30% 左右的 base64 效率低下,仍然是 10K 字节左右。这比 pickle/str 小得多。我认为 BLOB 是列类型的答案,并且我认为我在存储之前对 long 进行了 base64 编码(当然,在加载时对其进行解码)。
    【解决方案3】:

    好吧,正如 Python documentation 所说,“长整数具有无限精度。”从任何数据库的角度来看,这都是可悲的。您必须估计每个字段的最大值,您打算将它们存储在哪里,并选择最小大小的整数数据类型,以确保您的数据库保持紧凑和高效。 BLOB 不是您想要建立索引的类型。

    【讨论】:

    • 从某些数据类型的角度来看这是可悲的:D Postgres 支持“非常大的精度数”。 (当然,这在某些时候都是有限的,但up to ~150k digits 应该 对于大多数用例来说已经足够了......)
    • 纠正我,如果我错了,但不是 tinyint、int 和 bigint(我建议从中选择)固定精度数据类型?
    • 当然,但这些并不是唯一允许的数据库类型。这个答案断言这是数据库的普遍限制(它可能是 MySQL 限制,但不是普遍限制)。
    • 我将引用最初的问题:“我需要在 MySQL 中表示 Python“长整数”的实例。”当然,我可以建议使用 Oracle 的 number 类型,它最多可以容纳 38 个十进制数字,但是对他有什么用吗?
    • "..从 any 数据库的角度来看,这很可悲。"通用限定词可以很容易地使真实的陈述成为错误的 - 或者可以说是“不太真实”。此外,MySQL 最多可以支持 60 位数字。但在数万到数万之间仍有一个实际(出于某些目的)精度范围。
    【解决方案4】:

    应用程序需要支持非常大量的数据,但我 还不知道这些长整数可能有多大,也不知道有多少 他们我很可能会看到。

    所以你必须正视这种情况:

    (我们):不可能比这个更大。
    (数据):THIS+1
    (计算机):船长,我该怎么做?

    这让我充满了疑问。

    在选择 (a) 类型之前,您是否考虑过敲定一些方法?发明算术(匹配容器)听起来比编造容器来匹配数学要难。

    第一个想法:假设您想在给定时间内对确定的结果进行一些计算。随着输入大小无限制地增加,我认为有两件事变得越来越重要:

    a) 操作的确切性质。

    b) 定义收敛结果的过程。

    假设我给你一个任意大的数 N,你想做操作 a1。然后您可能会寻找一种表示 N 的方法,以便您可以说明相应的数字 M,即在给定输入 N 的情况下,您完成 a1 所需的固定长度的步数。

    关于这些数字的问题:

    • 您想从他们那里检索哪些信息?
    • 它们会被操作/转换吗? (......以及在变换下保留了哪些数值属性?)
    • 它们会混杂(涉及与其他类型的计算)吗?
    • 近似或部分结果有什么意义吗?
    • 您希望他们如何表现? (有没有你不想发生的事情?)
    • 表示的数据真的是整数吗:离散的、可枚举的量以绝对精度测量?

    它会帮助您检查现有的实现,或者找到做这种数学的人吗? mpmath (最近)正在积极开发中。作者blogs regularly关于相关置顶。而且,总的来说,SAGE 数学收集了广泛的(渐近快速的)库;其中有几个可以处理任意大的数字。


    如果这些考虑过于幼稚或显而易见,我深表歉意。

    【讨论】:

    • 感谢您的洞察力。我认为我的申请比你建议的更务实。我需要可靠地存储和加载 Python “long”的实例(我引用了上面的 Python 文档)。不多也不少。我只需要在数据库中表示它们(至少现在是这样),所以现在 BLOB 表示可以正常工作。其余问题的答案都取决于 Python。一旦我从数据库中加载了持久长并将其作为 Python 长(例如 123456L)回答,我的工作就完成了。
    • 是的。让我担心的是实际问题。我描绘了 Python 用户/数据 你的数据库 用户 X(不一定是 Python)。所以实际上是“长”引文让我思考。好的,当然,但是你怎么去……哈哈哈,你不必这样做。杰出的。感谢您的回复。
    猜你喜欢
    • 2011-05-02
    • 2011-03-23
    • 1970-01-01
    • 1970-01-01
    • 2014-02-10
    • 2010-09-28
    • 1970-01-01
    相关资源
    最近更新 更多