Python 从非常大的数字范围中分配数字的最佳解决方案是什么? 需求描述

Python 从非常大的数字范围中分配数字的最佳解决方案是什么? 需求描述,python,mongodb,algorithm,Python,Mongodb,Algorithm,有一个数字为1-160000的游泳池 创建obj时,需要为obj分配一个编号。有一些规则 池中的号码 其他obj未采用的编号 此外,用户有时会指定一个数字用于obj创建 下面是一些解决方案,每个都有自己的问题,所以我希望有更好的解决方案 请注意,我们在这里使用mongo DB。我不想更改数据库,因为这是一个问题 解决方案1 生成一个包含160000000项的大表(集合)。 集合的结构如下所示 number,allocated 分配号码时,使用find_one_和_update方法更新一条记录,

有一个数字为1-160000的游泳池

创建obj时,需要为obj分配一个编号。有一些规则

  • 池中的号码
  • 其他obj未采用的编号
  • 此外,用户有时会指定一个数字用于obj创建

    下面是一些解决方案,每个都有自己的问题,所以我希望有更好的解决方案

    请注意,我们在这里使用mongo DB。我不想更改数据库,因为这是一个问题

    解决方案1 生成一个包含160000000项的大表(集合)。 集合的结构如下所示

    number,allocated
    
    分配号码时,使用find_one_和_update方法更新一条记录,将分配的号码从false改为true

    问题 此解决方案的问题是生成160000000的集合太重

    解决方案2 与解决方案1类似,只是我们不一次性生成160000000。相反,我们每次生成1000个。当这1000条记录用完时,我们再生成1000条记录

    问题 问题是用户有时可以指定数字。例如,我们在集合中生成了1000条记录,但我们希望使用数字5000。这就是现在的问题,因为我们没有生成它

    解决方案3 每次创建一个obj时,我们都会生成一个1-160000000范围内的随机数,并将其保存在数据库中

    问题
    很难避免您生成的随机数以前没有使用过

    通常的方法是使用一个(切分的)原子计数器。计数器最初的值为零。当需要索引时,应调用一个API,该API将自动递增此计数器并给出其旧值

    虽然这可能比您提到的方法快得多,但根据您的需要,这可能还不够快。上述情况中的瓶颈是使增量原子化时通常使用的单个锁。这在某些分布式情况下并不理想

    使用分片计数器:

    在这种分布式场景中提高性能的常用方法是使用分片计数器:

  • 分割计数器(将值的范围
    1..160000000
    划分为
    N
    不相交的范围)
  • 在具有不同锁的线程/进程/实体/机器中运行相同的原子增量服务
  • 根据某些属性(可能是对象的地址或对象的散列),选择一个范围(在分布式系统中,可以使用分布式散列)
  • 请咨询(2)中提到的相应服务以获取下一个索引
  • 上述操作将使性能提高一倍,并可能根据您的应用程序需要进行扩展

    关于碎片计数器的一些有趣的阅读是在这里


    请注意,若要使用随机数生成(解决方案3),可以使用优化来查找密钥的存在性。这可能就足够了,具体取决于您的性能需求。

    如果您想在某个范围内生成一系列(伪)随机数而不重复,如果您不能重复使用某个数字,则可以使用具有完整周期的,似乎您必须维护一个已用物品的集合,这些物品的长度最终至少为15999999件。@samgak用户指定的数字可以解释吗?
    。。。太重了
    -这是指时间还是空间?@wwii,如果用户指定的数字只占总数的一小部分,则可以将其保存在单独的表中,如果已经使用过,则跳过该随机数并使用下一个(或下一个,等等)