怎样生成一个19位的唯一的id

clampid 2012-05-22 11:02:22
数据库中已经存在有按时间生成的id,形式如yyyyhhddHHMMSS+几个随机数。

注:id为19为字符串。

但现在在同一个时间点(毫秒级)上,生成多个id,并插入数据库。用老方法导致生产的id重复。请问是否有什么方法可以生成一个唯一的id?

想过使用guid,但是guid生成的字符串长度太大,无法存入数据库。
...全文
4260 54 打赏 收藏 转发到动态 举报
写回复
用AI写文章
54 条回复
切换为时间正序
请发表友善的回复…
发表回复
showwe 2012-05-29
  • 打赏
  • 举报
回复
那就高度精确,外加加锁
xingzhiyun 2012-05-28
  • 打赏
  • 举报
回复
看这个
public class NF
{
public static int IDSSEED=0;
public static string oldseedtime="";
/// <summary>
/// 纯数字、长度固定(23)、时间降序、多服务器不重复、
/// </summary>
/// <returns></returns>
public static string GetNextID()
{
//10091511135215000050177
//100915 11135215 00005 4位随机数
//年月日(各2位) 时分秒百分之一秒 5位种子(按1万循环) 0177
if(IDSSEED>99999)IDSSEED=0;
string newseedtime=DateTime.Now.ToString("yyMMddHHmmssff");
if(IDSSEED>9999)
{
if(newseedtime!=oldseedtime)
{
IDSSEED=0;
oldseedtime=newseedtime;
}
}
else
oldseedtime=newseedtime;
//return newseedtime + string.Format("{0,5:00000}", IDSSEED++) + ((new Random(Guid.NewGuid().GetHashCode())).NextDouble().ToString()+"123456").Substring(2, 4);
return newseedtime + string.Format("{0,5:00000}", IDSSEED++) + (Guid.NewGuid().GetHashCode().ToString()+"123456").Substring(2, 4);
}
}
sola_sky 2012-05-25
  • 打赏
  • 举报
回复
感觉可以配合数据库自增的功能,就是说生成的随机数+自增值,这样可以保证ID是唯一的。
Arcan 2012-05-25
  • 打赏
  • 举报
回复
楼主既然固执于不使用自增字段和Guid,非要用随机数的方式重复是不可避免的,就如同hash值一样,难免会重复,重复了就向下跳一个数字就是了。
或者直接在数据库中(或其它地方)记录一个时间和顺序号,当生成ID时先判断时间是否与这个时间相同,如果相同则将顺序号+1,然后生成的ID为时间+(顺序号+1),这样同一时间产生的ID就不会相同了。如果时间不相同了,则将记录的时间替换为当前时间,顺序号置0,产生的ID为当前时间+顺序号……
歪歪 2012-05-24
  • 打赏
  • 举报
回复

public static class DataBaseGenerator
{
/// <summary>
///
/// </summary>
private static Int64 seed = Int64.Parse(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds.ToString("0"));

/// <summary>
///
/// </summary>
/// <returns></returns>
public static Int64 GetPrimaryKey()
{
return Interlocked.Increment(ref seed);
}
}
sglogin 2012-05-24
  • 打赏
  • 举报
回复
1.设id为主键,这样不会有重复的记录
2.每次加入前取最大值加一
开发者孙小聪 2012-05-24
  • 打赏
  • 举报
回复
时间+随机数 应该可以
yuandonghuia 2012-05-23
  • 打赏
  • 举报
回复
调整数据库是最好的方式,你数据库主键是Guid就肯定不会出现重复.
或者数据库加个自增主键也行啊,我觉得这主要是你没数据库设计的问题,你却想从程序插入上做文章,思路就不对.
mobdx_19840908 2012-05-23
  • 打赏
  • 举报
回复
就是个大概意思 减到时间的那块你可以根据长度自己调整 如果存在并发最好加上锁
mobdx_19840908 2012-05-23
  • 打赏
  • 举报
回复
你看这样写行吗?
string no;
int num;
Random rand;
while (true)
{
Thread.Sleep(10);
rand = new Random();
no = Decimal.ToUInt64(Decimal.Divide(Decimal.Subtract(DateTime.Now.Ticks, DateTime.Parse("2012-01-01 00:00:00").Ticks), 10000)).ToString();
if (19 > no.Length)
{
num = int.Parse("1".PadRight(19 - no.Length, '0'));
no += rand.Next(num, num * 10 - num);
}
}
哥本哈根 2012-05-23
  • 打赏
  • 举报
回复

public static string job_no(string HeadName)//编码格式
{
SqlConnection conn = new SqlConnection(connectionString);
string s = "";
// SqlCommand cmd = new SqlCommand();
// cmd.Connection = conn;
conn.Open();
SqlCommand cmd2 = new SqlCommand();
cmd2.Connection = conn;
cmd2.CommandText = "declare @s varchar(30)" +
"set @s=convert(varchar,getdate(),111)+convert(varchar,getdate(),14)" +
" set @s=replace(@s,'/','')" +
" set @s=replace(@s,':','')" +
" set @s=replace(@s,'.','')" +
" select @s";
SqlDataReader r = cmd2.ExecuteReader();
while (r.Read())
{
//s = "CL"+r[0].ToString();
s = r[0].ToString();
}
r.Close();
conn.Close();
s = HeadName + s;
return s;
}
for(int i=0;i<10;i++)
{
string _no=jobno("TE")+i;
//这个 _no永远都不会重复
}



在循环插入信息时,再加上变量
clampid 2012-05-23
  • 打赏
  • 举报
回复
[Quote=引用 36 楼 的回复:]

感觉无重复阿~


private string GetRandomNum()
{
Random ro = new Random(Guid.NewGuid().GetHashCode());
string iFirst = ro.Next(10, 99).ToString();
return iFirst;
}

string newName = DateT……
[/Quote]
会重复的,可以用个循环试试
xuan.ye 2012-05-23
  • 打赏
  • 举报
回复
declare @i int
declare @str varchar(19)
set @i=100

while(@i>0)
begin
set @str= SUBSTRING(REPLACE(NEWID(),'-',''),1,19)
print @str
set @i=@i-1
end
xingzhiyun 2012-05-23
  • 打赏
  • 举报
回复
看看我的这个,非常符合你的需求.
http://blog.csdn.net/xingzhiyun/article/details/7594233
dalmeeme 2012-05-22
  • 打赏
  • 举报
回复
我刚才试了下:string r = DateTime.Now.ToString("yyyyMMddHHmmssfffff");也不行,生成的都相同,期待更好的方法。
Lugyedo 2012-05-22
  • 打赏
  • 举报
回复
为什么不在数据库表里使用自增字段呢
anzhiqiang_touzi 2012-05-22
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
如果不存在并发的话,可以在插入前取到yyyyhhddHHMMSS,再定义一个自增整数变量。得到的id为时间后面跟上这个变量,生成多个id时,这个变量值往前加。

如果要更精细,可以把yyyyhhddHHMMSS取到毫秒。
[/Quote]
dalmeeme 2012-05-22
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

默认情况下,.net的随机数发生器会使用时间作为种子,这是导致重复的关键,因为瞬时的时间种子一样,一样的种子产生的随机数序列也一样。
[/Quote]
用随机数的方法是错误的,至少说不是一个好方法。根据楼主的需求,要求产生的id唯一。假设2个id产生的前15位完全相同(精确到秒),那么用随机数产生最后5位仍有相同的可能性。换句话说,Guid产生的字符序列变化数远大于5位数字的变化数,存在着多对一的映射,因此仍会最后生成的2个5位数字重复。

就本问题而言,可以试一下:
string r = DateTime.Now.ToString("yyyyMMddHHmmssfffff");
当yyyyMMddHHmmss相同时,fffff肯定不同。
clampid 2012-05-22
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

left(guid,x)& hhmmss
[/Quote]

这个应该不可以,因为数据库中已经存在了根据老方法产生的id。如果这样的话,可能和已经存在的数据重复。现在需要根据yyyyhhddHHMMss然后加上一些数字来产生唯一id。
clampid 2012-05-22
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

用Guid作为种子产生随机数。
[/Quote]

我曾经使用NewGuid().GetHashCode()作为种子,然后生成一个7位的随机数,再配合yyyyhhddHHMMss,生成一个id。但是,这样最后还是出现了重复的。
加载更多回复(30)

62,041

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧