【问题标题】:How do I generate a positive long integer in C#? [closed]如何在 C# 中生成正长整数? [关闭]
【发布时间】:2018-01-26 20:12:33
【问题描述】:

如何在 C# 中生成正长整数?

背景信息:我没有共享状态,并且正在将条目插入 dynamodb,它没有自动递增的主键。一个典型的模式是插入一个向导,检查冲突;根据桌子的占用情况,这是一个可行的解决方案。我想使用修改后的策略,而不是使用 guid(16 字节),我将使用正长整数(63 位)。

这是一个安全计划的理由:

我预计最终最多会使用总可用空间的千亿分之一 (1/10**8)。

2**63 == 9223372036854775808

如果我存储 100b 条记录,占用率为:

2**63/10**11 == 92233720 ~= 10**8

这意味着碰撞的机会大约是每亿次尝试。由于我在插入时检测到冲突,因此必须以该频率重试生成是可以接受的。

所以问题是:

如何在 C# 中生成随机正数?

【问题讨论】:

  • 标准 id 约定意味着您应该让它由您的数据库生成...只是随机生成一个会导致插入查询失败,如果您不考虑这一点,可能会导致许多问题.. 那就是整个原因是所有数据库都有自动递增的 ID..
  • DynamoDB 不支持随机自动生成的 ID。我将在插入时检查重复项。此外,对于这个域来说,长空间就足够了。
  • 问题是如何生成这样一个数字,它不是C#标准库内置的,并且有合理的商业用途。诸如“好吧,你不应该那样做”之类的评论是不相关的。
  • 获取id字段,初始化为0,递增1 id++
  • @crunchy 我在数据库本身之外的所有客户端之间没有共享状态,因此无法协调。

标签: c# random


【解决方案1】:

问题询问如何在 C# 中生成正长。这段代码就是这样做的。 该问题概述了处理重复项的计划。因此,以下代码不会生成 PK 或声称唯一性 - 它声称分布良好,并且依赖于概述的框架来处理多头。

所以,这里是如何在 C# 中生成正长,这就是问题所要求的:

public static long GeneratePositiveLong(Random random)
{
    byte[] buf = new byte[8];
    random.NextBytes(buf);

    //the last byte must be from 0-127
    buf[7] = buf[7] &= 0x7f;
    long res = BitConverter.ToInt64(buf, 0);
    return res;
}

【讨论】:

  • 随机并不意味着任何 PK 都需要的唯一性
  • 为了确保一个正/无符号字节,您可以屏蔽掉潜在的符号位,即buf[7] &= 0x7f;
  • @Plutonix 这取决于域大小,冲突的可能性有多大,因此它们的使用有多可行。使用 GUID 作为主键有点常见,它们也大多是随机的,虽然是 128 位而不是像 long 那样的 64 位。
  • 无论域大小如何,唯一 ID 都是唯一的。
【解决方案2】:

一种可能性是使用一个表来跟踪下一个 PK 以用于您的其他表。当你需要一个新的主键时锁定这个表,读取当前值,增加它,然后解锁。这样多个客户端不会重叠键。

【讨论】:

  • 是的,我可以使用 dynamoDb 作为主键的存储,但是会有问题 - 对一个键的请求太多,并且可能存在锁定问题。有分布式密钥分配服务,但我希望由于我的占用率很低,我可以不用创建一个。
【解决方案3】:

一种可能的解决方案是您可以使用当前时间戳(以纳秒为单位),这将是唯一的,因此您也可以将其用作唯一的主键

【讨论】:

  • 这大致相当于使用long——问题指定long为其他原因(主要是为了让我们使用整个id空间)。如果我们准时有纳秒级分辨率,将其限制为 currentTimestamp 将起作用 - 但该分辨率可能不可用。还有一些有趣的东西,比如夏令时。
  • 好吧,您在任何时间点以纳秒为单位的时间戳仍然是唯一的,并且为了重复记录,您应该拥有非常庞大的无符号长数据条目集,您将非常大正如我所说的那样,这是一种可能的选择
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-13
  • 2019-09-02
  • 2013-02-11
  • 1970-01-01
  • 2010-10-23
  • 1970-01-01
相关资源
最近更新 更多