我正在编写一个数据库,我希望为特定类型的每个项目分配一个唯一的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来减少带宽消耗。
答案 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
就足够了。)