您的位置:首页 > 其它

分步式系统中全局唯一主键

2016-04-08 22:30 369 查看
前几天看到一篇Java版的全局唯一主键,觉得写的很不错,就直接简化了成C#,

long共 64个字节

其中0-9是随机数,10-19是计算机唯一值,20-22是区域唯一值,23-63是时间毫秒数

这样 随机数小于 2^10=1024

计算机唯一值 小于 2^10=1024

区域唯一值 小于 2^3=8

毫秒数 2^41,可以用上 99年(感觉有点少啊)

class GlobalUniqueId
{
const int MaxRegionId = 8;
const int MaxComputerId = 1024;
private long _regionId;
private long _computerId;
static GlobalUniqueId _Instance = null;
private GlobalUniqueId()
{
}
static object objLock = new object();
public static GlobalUniqueId Instance
{
get
{
if (_Instance == null)
{
lock (objLock)
{
if (_Instance == null)
_Instance = new GlobalUniqueId();
}
}
return _Instance;
}
}
static readonly DateTime BASE_DATE = new DateTime(2010, 1, 1, 0, 0, 0);

long getMillSeconds()
{
TimeSpan ts = DateTime.Now - BASE_DATE;
return (long)ts.TotalMilliseconds;
}
void addRegionId(ref long r)
{

r = r | (_regionId << (64 - 41 - 3));

}
void addComputerId(ref long r)
{

r = r | (_computerId << (64 - 41 - 3 - 10));

}
void addMillSecondId(ref long r)
{
long ms = getMillSeconds();
r = r | (ms << (64 - 41));

}
static readonly Random rand = new Random();
static readonly int MaxRandId = (int)(Math.Pow(2, 10));
void addRandomId(ref long r)
{
long rndId = rand.Next(0, MaxRandId);

r = r | rndId;

}
public long NextId(int regionId, int computerId)
{
if (regionId >= MaxRegionId) throw new Exception("区域号超过最大值");
if (computerId >= MaxComputerId) throw new Exception("机器号超过最大值");
this._regionId = regionId;
this._computerId = computerId;
long r = 0;//
addMillSecondId(ref r);
addRegionId(ref r);
addComputerId(ref r);
addRandomId(ref r);
return r;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: