这篇文章是谈这个题目的,LZ看看有没有帮助:http://www.vbdotnetheaven.com/Uploadfile/stangershen/GenerateintegerIDs11132005232951PM/GenerateintegerIDs.aspx

解决方案 »

  1.   

    有两种 方法
    A:数据库字段ID设为识别种子,自动增长
    B:用一个方法去取该表的下一个值:
      代码:
       int32 nextId=GetNextId(yourTable); public Int32 GetNextId(string tableName)
            {
                //throw new System.NotImplementedException();
                Int32 newProdID = 0;
                try
                {
                    string sqlstring = "SELECT   IDENT_CURRENT(@table)   +   (SELECT   IDENT_INCR(@table)) ";
                    SqlCommand sqlcmd = new SqlCommand(sqlstring, this.cnn);
                    sqlcmd.Parameters.Add(new SqlParameter("@table", tableName));
                    if (cnn.State == ConnectionState.Open)
                    {
                        cnn.Close();
                    }
                    cnn.Open();
                    newProdID = Convert.ToInt32(sqlcmd.ExecuteScalar());
                }
                catch (Exception ex)
                {
                    MessageBox.Show("此表不存在!" + ex.Message, "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
                finally
                {
                    cnn.Close();
                }
                return newProdID;
            }
    ================================================
    给多点分,我现在还差40分就到500的专家分,就可以多一个小三角了...
      

  2.   

    public class tools
        {
            private static long x;
            private static object objectLock = new object();
            public static long getID()
            {
                lock (objectLock)
                {
                    return x++;
                }
            }
            public static long maxID
            {
                set
                {
                    lock (objectLock)
                    {
                        x = value;
                    }
                }
            }
        }=======================================
    取ID时
    long newID= tools.getID(); 
      

  3.   

    是这样的,系统现在是用类来驱动,每个类都继承了一个叫BaseInfo的基类.如果类中有多个属性类(子类)都要进行新增到数据库时(如 有个City类 ,Province类,Country类都继承了BaseInfo类.City.Province是Province类,City.Country同理.当要对CIty类新增时调用Bussiness Rule层的Commit()方法时, 有可能对其子类也要新增.系统会 重复调用一个GetIdentityPropValue()方法返回LONG类型.这时有可能用随即数处理会得到一样的Id.应为系统运行时间很快,随即数来不及变化.)
      

  4.   

    public class tools
        {
            private static long x;
            private static object objectLock = new object();
            public static long getID()
            {
                lock (objectLock)
                {
                    return x++;
                }
            }
            public static long maxID
            {
                set
                {
                    lock (objectLock)
                    {
                        x = value;
                    }
                }
            }
        }
      

  5.   

    我觉得用时间戳是个不错的选择就是会出现系统运行时间很快,时间来不及变化,即使用DateTime.Now.Ticks也不行,我测试了的.如果我单步调试慢慢一步一步的调试这样不会重复,因为系统的运行时间在调试时降低了.当然用DateTime.Now.Ticks这个方法不会重复,随机数是一样的.同理因为随机数生成的原理和时间戳差不多,要时间种子的.我觉得关键是在如何让系统运行很快时怎样不重复,用lock的方式.不行吧,我现在还没有考虑多线程,就单线程都要重复,所以用LOCK同样不能解决
      

  6.   

    我以前,设计这种字段时候就只用GUID类型的,省掉好多麻烦的。
      

  7.   

    在SQLServer里面,ID字段基本都用GUID类型的,但是名字不叫GUID实际上就是GUID类型,还有个函数的NewId()返回的就是Guid类型的。GUID按照时间和网卡地址进行计算得到的唯一值,128位长度,网卡的MAC地址全世界都唯一。
      

  8.   

    在MySql里面没有Guid类型的玩意,可以用字符串类型的,存的是Guid的字符串样式,效率有点低。但是MySql里面可以用自增类型的long类型也可以,唯一的毛病,有个大毛病,就是新增记录的时候无法定位新增记录的Id,如果Id的确是唯一的键,而他又是自增数据库自己生成的,那就会麻烦,逻辑上,用户新增后却无法定位刚刚插入的那个记录行,真失败。不过实际上,Id一般都是内部使用。
      

  9.   

    用 GUID  做为唯一标识
      

  10.   

    自已写随机数太难了,还是用GUID方便。
      

  11.   

    这种需求 Guid 是最合用的...对于不支持 Guid 数据类型的数据库读写时自己转换...字符串或二进制...至于说 Guid 查询效率低的问题...主键是不应该有业务意义的...除了关系它很少参与查询...
      

  12.   

    使用自动增量的不行么?
    如果达不到LONG类型的目的.
    建立一个自动增量为1的字段,每次写入前先找当前最新的增量值.
    然后使用多位数的随机数,末尾加上下一个增量值就OK了.例如:
    建立ID字段为自动增量为1.(这样每条新记录里的这个字段会依次加1)
    写入新记录前,先查询当前数据库里最新的ID字段的值.(例如为1973)
    然后产生个多位数的随机数(比如:204856)
    把随机数后附上下一个ID值(1974)
    你就得到2048561974了.这样做,绝对没有重复.希望有帮助.
      

  13.   

    建立ID字段为自动增量为1.(这样每条新记录里的这个字段会依次加1)
    写入新记录前,先查询当前数据库里最新的ID字段的值.(例如为1973)
    然后产生个多位数的随机数(比如:204856)
    把随机数后附上下一个ID值(1974)
    你就得到2048561974了.这样做,绝对没有重复.
    -----------
    说话不要那么绝对...这世上没有绝对的事情...Guid都不敢保证绝对没有重复...按你的方法举例:
    写入新记录前,先查询当前数据库里最新的ID字段的值.(例如为61973)
    然后产生个多位数的随机数(比如:20485)
    把随机数后附上下一个ID值(61974)
    你就得到2048561974了.您觉得这种情况发生的几率有多大?
      

  14.   

    可以的话,使用类似大型数据库的Sequence,即写一个存储过程或者函数来解决。
      

  15.   

    "写入新记录前,先查询当前数据库里最新的ID字段的值.(例如为1973)
    然后产生个多位数的随机数(比如:204856)"如果是这样就根本没有发帖探讨的必要了,我之所以不用GUID是应为,我们现在的数据裤结构是已Id为主键的,在SQL中会自动以Id为索引,而且有些数据表也是以各表的Id来发生联系的.如果用上GUID128位你想想效率问题吧
      

  16.   

    因为我们现在的框架是这样设计的.以类来驱动作相应的数据库操作,例如有一个Order类和OrderTails类,这个是一对多的关系.
    比如:
    OrderTails[] tails= new OrderTails[3];
    tails[0] = new OrderTails("99999999",  "999999999", "99999999");
    tails[1] = new OrderTails("999999999999999", "999999999999999", "99999999");
    tails[2] = new OrderTails("99999999999999999", "999999999999999", "9999999");
    //这时我对tails的所有属性付了值.(这三个类是要新增的.)
    Order ai = new Order("9999999999","999999999999", "9999999999999", tails);
    //这时对ai的所有属性已付值(包括Order类的Details属性)
    ai.Commit();//对ai进行新增,如果当ai有子类(tails)且子类也需要新增则同样要生成Insert语句.所以这时是4个Insert语句.并且要先生成Id不然就不好处理外键的关系.而且不好处理成一个事务.所以,Id不能设为自动增加
      

  17.   

    同理,如果是4个Insert的话,不可能在tails[0]新增进数据库后,我要增tails[1]还要到数据库查tails[0]Id,同理tails[2].这4个Insert是一个事务中
      

  18.   

    我也觉得就用 用 GUID  做为唯一标识
      

  19.   

    数据库刷新
    排序
    移到最后,
    取其ID值,++
    做为新的ID值。
    如果不是网络调用,可以一次取最大值,然后多次累加
      

  20.   

    GUID太长了,能不能截掉前面一小些?
      

  21.   

    大家想想,我在ai.Commit()时,计算机会在每个类实例的时候计算Id值(我定义的一个GetIdentityPropValue()方法).如果用毫秒或100微秒的时间戳,则很有可能tails[0],tails[1],tails[2]的Id都是一样的.我用了 DateTime.Now.Ticks,同样是重复的,Id,DateTime.Now.Ticks已到达100微秒级了.但是不知道微秒如何处理?
    后来我改写了GetIdentityPropValue() internal static long GetIdentityPropValue()
            {
                long i = long.Parse(DateTime.Now.ToString("yyyyMMddHHmmss") + DateTime.Now.Millisecond.ToString());
                Random rand = new Random();
                string j = rand.Next(99).ToString();
                long k = long.Parse(i.ToString() + j.ToString());  
                return k;
            }
    同样会重复.
      

  22.   

    把GUID 前面截掉,肯定会重复!
      

  23.   

    DateTime.Now.Ticks已到达100微秒级了.但是不知道微秒如何处理?
    ---------------------
    放心吧...PC + Windows 环境下 DateTime.Now.Ticks 不可能达到 100 微秒级...说了 n 多次了,10 ms 级...10 ms 后面的数字都是不精确的...并发处理中 Guid 是代价最小的...
      

  24.   

    提 最大值加1的、自动增长的,都没认真看lz的需求...预生成ID还要考虑并发...Oracle的Sequence也许可以解决...但还是不如Guid可靠...
      

  25.   

    vrhero(专业路过/有一天我躺下来/从此不再结帖...) ”但还是不如Guid可靠“的确能解决我的问题,关键是效率问题,因为位数是128位,如果一但在业务逻辑中的某个类对应的数据表中找不到一个字段能表示唯一的PK,那我要把这个GUID 的ID 作为主键标识,同理相应的表与表的连接时,也会有相应的128位的Id为外键。那么在一个有100-200多个表的系统中,这样用guid作为主键和外键的表不在少数,那么SQL是安主键来建立索引的。这样效率低。这就是我为什么不干用GUID的原因。
      

  26.   

    我不相信毫秒级别还会有相同,测试过在SQL里执行两条件更新时间字段的语句,毫秒数不相同的
      

  27.   

    架构设计的难点就在这里了...取舍之间如何权衡...我的观点是,由于Guid导致的性能损失应该可以忽略不计...Windows系统中也在大量应用Guid啊...128位数字再怎么说也是数字,处理起来应该比字符串快...
      

  28.   

    GUID的确能给它变成128位的数字,但是SQL中最大时BigInt是64位,如果用SQL的uniqueidentifier类型,uniqueidentifier这个是专门处理GUID的。好像要在Insert 语句中直接用NEWId()对Id赋值。这样不能在程序级对ID进行赋值。我的要求是在程序级的时候就要得到这些ID值。所以只有用字符串。汗!
      

  29.   

    GUID的确能给它变成128位的数字,但是SQL中最大时BigInt是64位,如果用SQL的uniqueidentifier类型, uniqueidentifier这个是专门处理GUID的。好像要在Insert 语句中直接用NEWId()对Id赋值。这样不能在程序级对ID进行赋值。我的要求是在程序级的时候就要得到这些ID值。所以只有用字符串。汗!
    ------------
    谁说不能在程序级对ID进行赋值?Guid.NewGuid()...直接传入参数即可...Sql Server 保存时是按二进制数字处理的...字符串是给我们看的...底层可不是...
      

  30.   

    vrhero(专业路过/有一天我躺下来/从此不再结帖...) 你的意思是在数据库中,ID设为uniqueidentifier这个类型,而在程序级用一个OBJECT或GUID类型来表示Id是不是,Guid.NewGuid()。
      

  31.   

    xie_xingan() ,不是我每次都要查数据库?
      

  32.   

    当然,.NET中多数DbParameter都支持Guid类型...如果不支持例如OracleParameter写个转换方法即可...