高效安全地分配唯一ID

时间:2013-09-10 11:25:13

标签: c++ database performance unique

我正在编写一个数据库,我希望为特定类型的每个项目分配一个唯一的ID(用于内部数据管理)。但是,数据库预计会运行很长时间(理论上无限),条目周转率很高(如删除并定期添加条目)。

如果我们将唯一ID建模为unsigned int,并假设数据库中的条目总是少于2^32 - 1(我们不能使用0作为唯一ID),我们可以做类似以下的事情:

void GenerateUniqueID( Object* pObj )
{
    static unsigned int iCurrUID = 1;
    pObj->SetUniqueID( iCurrUID++ );
}

但是,在条目开始删除并在其位置添加其他条目之前,这很好,可能仍然会有少于2^32-1条目,但我们可能会溢出iCurrUID并最终分配“唯一” “已经使用的ID。

我的一个想法是使用std::bitset<std::numeric_limits<unsigned int>::max-1>,然后遍历它以找到第一个免费的唯一ID,但这会占用大量内存并且线性复杂度会找到一个免费的唯一ID,所以我如果有的话,我正在寻找更好的方法吗?

提前致谢!


我知道将数据类型更改为64位整数而不是32位整数可以解决我的问题;但是,因为我在Win32环境中工作,并且使用列表(DWORD_PTR为32位),我正在寻找替代解决方案。此外,数据通过网络发送,我试图通过使用更小的唯一ID来减少带宽消耗。

2 个答案:

答案 0 :(得分:5)

使用uint64_t(64位),即使你每秒插入接近100k条目的地方,也会花费100多年的时间。 超过100年,你应该插入大约315,360,000,000,000条记录(不考虑闰年和闰秒等)。这个数字将适合49位。

您预计应用程序运行多长时间? 超过100年?

这是数据库管理员在具有应用于32位限制的自动增量字段时所做的常见事情。它们将数值更改为其数据库系统的本机64位类型(或128位)。

答案 1 :(得分:1)

真正的问题是,除非你有多少条目 保证删除第一个。你多久一次 创建新条目。保证unsigned long long 最大值至少为2 ^ 64,约为1.8×10 ^ 19。即使在 每微秒创造一次,这将持续几个 千世纪。实际上,你无法做到 快速创建条目(因为磁盘速度不允许), 而且你的程序不会运行数百个世纪 (因为硬件不会持续那么久)。如果是唯一的id 对于基于磁盘的东西,使用unsigned long long作为id是安全的。

否则,当然,生成你认为你的位数 可能需要。如果你真的是偏执狂,那么使用它是微不足道的 256位无符号整数,甚至更长。在某一点, 即使宇宙中的每个原子都创造了新的原子,你也会没事的 进入每皮秒,直到宇宙结束。 (但 现实地...... unsigned long long就足够了。)