多年来厂商选用,先看错误

 汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql

http://www.cnblogs.com/heyuquan/p/global-guid-identity-maxId.html

几日前在多少迁移的时候因为手贱碰着贰个坑爹难点,发来大家乐乐,也传授新手点经历

又多个多月没冒泡了,其实多年来学了些东西,不过从未配置时间整合治理成博文,后续再奉上。近来还写了二个发邮件的组件甚至品质测量试验请看 《NET开辟邮件发送作用的巨细无遗教程(含邮件组件源码)》 ,还弄了个MSSQL参数化语法生成器,会在11月收拾出来,风野趣的园友能够关注下作者的博客。

搬迁惯用正是有时表可能新库,常常用的语法有非常多,此次首要说的是其风流浪漫:select * into 数据库名..表名 from xxx

 

先不扯了,先看错误:

享受原由,近日厂家利用,何况在找最合适的方案,希望大家多参加探讨和提议新方案。作者和本身的同伙们也钻探了这几个主题,作者受益良多啊……

图片 1

 

赶忙看看是否数码再度~事实注解,木有重复数据。。。

博文示例:

图片 2

  1. GUID生成Int64值后是还是不是还享有唯意气风发性测量试验
  2. Random生成高唯生龙活虎性随机码

有人会问,你怎么这么求count?。。。额,作者会的是最大旨的议程,常见的三种其实品质相通的,相比较图:(有更加好写法能够提点一下四哥^_^

 

图片 3

今日享受的宗旨是:如何在高并发遍布式系统中生成全局唯生龙活虎Id。

图片 4

但那篇博文实际上是“半共享半研商”的博文:

得了,查下改ID下的数据:到底是否再次~~~不是。。。

1)         半分享是本身将说下自个儿所了然到的关于今天宗旨所涉及的三种方案。

图片 5

2)         半谈谈是自家希望大家对黄金年代一方案都说说本身的观念,特别期望大家能提议更加好的方案。(作者还别的提问在这:http://q.cnblogs.com/q/53552/上边原来就有三位园友回复(谢谢dudu站长的参加),若你们有眼光和新方案就在本博文留言吧,方便我整理更新到博文中,感激!)

行吧,那大家就看看同一个ID重复次数

 

图片 6

自己打听的方案如下……………………………………………………………………

紧凑想了下,整个搬迁进度,貌似木有怎样错误,难道是其一手贱的来头??(命令没履行完,点了几许次加快,也不明了是还是不是那几个原因导致的,好啊就当是他了===》( ̄— ̄))

1、  使用数据库自增Id

图片 7

优势:编码轻便,没有必要思考记录独一标志的题目。

化解方法:三种,后生可畏种便是再次来二遍数据迁移整理

缺陷:

第三种正是Id先删了,再建(因为数量没难题,借使多少出标题了,那不管怎么说都得重来叁次)

1)         在大表做水平分表时,就不可能使用自增Id,因为Insert的记录插入到哪些分表依分表准则剖断决定,要是自增Id,各类分表中Id就可以再一次,在做询问、删除时就能够有卓绝。

图片 8

2)         在对表进行高并发单记录插入时需求参与事物机制,不然会现出Id重复的标题。

脚本:

3)         在工作上操作父、子表(即关联表)插入时,须要在插入数据库之前获得max(id)用于标志父表和子表关系,若存在并发获取max(id)的事态,max(id)会同时被别的线程获取到。

alter table Info01 drop column Id
go
alter table info01 add Id int identity(1,1) primary key
go

4)         等等。

 未来终于精通,为啥异常的大多据库的主键都以在最后一列了

敲定:切合小应用,不要求分表,未有高并发品质须要。

图片 9

2、  单独开叁个数据库,获取全局唯一的自增种类号或各表的马克斯Id

末段说提出的话,对于这种多表的最佳依旧用程序来支配和管理数量(你得保障标识唯风度翩翩),借使不管标志就随意搞了~

1)         使用自增类别号表

 

专程多少个数据库,生成连串号。开启事物,每回操作插入时,先将数据插入到系列表并赶回自增类别号用于做为唯大器晚成Id实行作业数据插入。

在意:须求定时清理系列表的数目以保障收获种类号的频率;插入体系表记录时要拉开事物。

选择此方案的难点是:每一回的查询类别号是八本性质损耗;若是这一个队列号列暴了,这就杯具了,你不知底哪些表使用了哪些连串,所以就必需换另大器晚成种唯生龙活虎Id方式如GUID。

2)         使用马克斯Id表存款和储蓄各表的马克斯Id值

专程二个数据库,记录各类表的MaxId值,建三个累积进程来取Id,逻辑差不离为:开启事物,对于在表中不设有记录,直接重临二个暗中认可值为1的键值,同不经常间插入该条记录到table_key表中。而对此已存在的笔录,key值直接在本来的key基础上加1更新到马克斯Id表中并回到key。

使用此方案的标题是:每一遍的询问MaxId是几特特性损耗;可是不会像自增系列表那么轻便列暴掉,因为是摆表进行剪切的。

详细可参看:《使用马克斯Id表存款和储蓄各表的马克斯Id值,以获取全局唯大器晚成Id》

                   笔者截取此文中的sql语法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
第一步:创建表
create table table_key
(
       table_name   varchar(50) not null primary key,
       key_value    int         not null
)
 
 
第二步:创建存储过程来取自增ID
create procedure up_get_table_key
(
   @table_name     varchar(50),
   @key_value      int output
)
as
begin
     begin tran
         declare @key  int
          
         --initialize the key with 1
         set @key=1
         --whether the specified table is exist
         if not exists(select table_name from table_key where table_name=@table_name)
            begin
              insert into table_key values(@table_name,@key)        --default key vlaue:1
            end
         -- step increase
         else   
            begin
                select @key=key_value from table_key with (nolock) where table_name=@table_name
                set @key=@key+1
                --update the key value by table name
                update table_key set key_value=@key where table_name=@table_name
            end
        --set ouput value
    set @key_value=@key
 
    --commit tran
    commit tran
        if @@error>0
      rollback tran
end

多谢园友的好提出:

  1. @辉_辉)建议给table_key中为各种表早先化一条key为1的记录,那样就不用每一回if来剖断了。
  2. @乐活的CodeMonkey)建议给存款和储蓄进程中数据库事物隔开品级提升级中学一年级下,因为现身在CS代码层上利用如下事物代码会形成出现重复难题.
1
2
3
4
5
6
7
8
TransactionOptions option = new TransactionOptions();
option.IsolationLevel = IsolationLevel.ReadUncommitted;
option.Timeout = new TimeSpan(0, 10, 0);
  
using (TransactionScope transaction = new TransactionScope(TransactionScopeOption.RequiresNew, option))
{
        //调用存储过程
}

在咨询过DBA后,那几个蕴藏进程提升数据库隔绝等级会加大数据库访谈压力,导致响应超时难点。所以那些提议大家只可以在代码编写宣传引导上做。

  1. @洋芋烤肉)存款和储蓄进程中不接收事物,生龙活虎旦采用到东西性质就霸道下滑。直接使用UPDATE获取到的改革锁,即SQL
    SEQX56VE福特Explorer会保险UPDATE的相继奉行。(已在顾客过相对化的面世系统中运用)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
create procedure [dbo].[up_get_table_key]
(
   @table_name     varchar(50),
   @key_value      int output
)
as
begin
 
    SET NOCOUNT ON;
    DECLARE @maxId INT
    UPDATE table_key
    SET @maxId = key_value,key_value = key_value + 1
    WHERE table_name=@table_name
    SELECT @maxId
 
end

敲定:适用中型应用,此方案消除了分表,关联表插入记录的难点。然则力所不及满足高并发品质供给。同期也存在单点难点,固然那几个数据库cash掉的话……

小编们脚下正咳嗽这几个标题,因为大家的高并发平日现身数据库访谈超时,瓶颈就在此个马克斯Id表。大家也会有考虑使用分布式缓存(eg:memcached)缓存第三回访谈MaxId表数据,以升高再一次访问速度,并依期用缓存数据更新贰遍马克斯Id表,但大家忧虑的主题材料是:

a)         若是缓存失效或暴掉了,那缓存的MaxId未有校订到数据库导致数据错过,必得停掉站点来实践Select
max(id)各类表来同步马克斯Id表。

b)         分布式缓存不是风姿罗曼蒂克封存下去,其余服务器上就顿时能够获取到的,即数据存在不分明性。(其实也是缓存的三个误用,缓存应该用来存的是一再探访况且比相当少改进的从头到尾的经过)

         修正方案:

全体构思:建构两台以上的数据库ID生成服务器,每一种服务器都有一张记录各表当前ID的马克斯Id表,不过MaxId表中Id的滋长幅度是服务器的数据,早先值依次错开,那样相当于把ID的转移散列到每一种服务器节点上。比方:假使大家设置两台数据库ID生成服务器,那么就让大器晚成台的马克斯Id表的Id最早值为1(或当前最大Id+1),每一回增幅为2,另生机勃勃台的MaxId表的ID开头值为2(或当前最大Id+2),每一次步长也为2。那样就将发出ID的压力均匀分散到两台服务器上,相同的时间相称应用程控,当贰个服务器失效后,系统能自行切换来另三个服务器上得到ID,从而缓和的单点难点保障了系统的容错。(Flickr观念)

可是要留神:1、多服务器就亟须面前蒙受负载均衡的难题;2、假若加多新节点,须要对本来数据再度依据步长总结迁移数据。

结论:适合大型应用,生成Id比较短,友好性比较好。(刚烈推荐)

3、  Sequence特性

其黄金时代性情在SQL Server
二〇一二、Oracle中可用。那么些特点是数据库级其他,允许在七个表之间分享连串号。它能够解决分表在同一个数据库的气象,但只要分表放在分裂数据库,那将分享不到此系列号。(eg:Sequence使用情形:你要求在四个表之间公用贰个流水号。将来的做法是外加营造多个表,然后存款和储蓄流水号)

连锁Sequence性格资料:

SQL
Server2012中的SequenceNumber尝试

SQL Server
2012 开垦新功用——体系对象(Sequence)

identity和sequence的区别

Difference between Identity and Sequence in SQL Server
2012

结论:适用中型应用,此方案不可能一心缓慢解决分表难点,而且不能满意高并发品质须求。同一时间也设有单点难题,假如这些数据库cash掉的话……**

4、  通过数据库集群编号+集群内的自增类型三个字段协同构成唯大器晚成主键

亮点:达成轻便,维护也比较简单。

缺欠:关联表操作相对比较复杂,须求多少个字段。何况作业逻辑必得是后生可畏在那早先就安顿为管理复合主键的逻辑,倘假如到了前期,由单主键转为复合主键那改变耗费就太大了。

敲定:符合大型应用,但须求职业逻辑合营处理复合主键。

5、  通过设置每种集群中自增 ID 早先点(auto_increment_offset),将顺序集群的ID实行相对的分支来兑现全局唯豆蔻年华。当蒙受有些集群数据拉长过快后,通过命令调治下一个 ID 先河地点跳过可能存在的冲突。

可取:达成轻巧,且比较便于依据 ID 大小直接判别出多少处在哪个集群,对运用透明。劣点:维护相对较复杂,要求中度关注各样集群 ID 增加境况。

敲定:符合大型应用,但供给中度关注各类集群 ID 增加现象。

6、  GUID(Globally Unique
Identifier,全局唯黄金时代标记符)

GUID平时表示成叁十个16进制数字(0-9,A-F)组成的字符串,如:{21EC2020-3AEA-1069-A2DD-08002B30309D},它实质上是多个1二十六人长的二进制整数。

GUID制定的算法中动用到顾客的网卡MAC地址,以保险在处理器集群中生成唯后生可畏GUID;在同等Computer上任性生成几个相近GUID的或者性是丰裕小的,但并不为0。所以,用于生成GUID的算法平常都步入了非随机的参数(如时间),以保障这种重新的气象不会发出。

可取:GUID是最简便的方案,跨平台,跨语言,跨业务逻辑,全局唯风姿洒脱的Id,数据间合营、迁移都能差十分少完毕。

缺点:

1)         存款和储蓄占了31人,且无可读性,重回GUID给客商出示特不正规;

2)         占用了宝贵的聚焦索引,平时大家不会依附GUID去查单据,何况插入时因为GUID是不用的,在集中索引的排序法则下或者移动大量的笔录。

有两位园友首荐GUID,无须顺序GUID方案原因如下:

@徐少侠           GUID冬季在并发下功用高,况兼叁个数据页内加多新行,是在B树内扩张,本质没有啥数据被活动,唯意气风发或许的,是页填充因子满了,要求拆页。而GUID方案导致的拆页比顺序ID要低太多了(数据库不是很懂,暂且无法看清,我们温馨认知)

@无色                大家要精晓id是怎么,是身价标记,标志身份是id最大的作业逻辑,不要引进什么时间,什么客商业务逻辑,那是此外一个字段干的事,使用base64(guid,uuid),是通盘挂念,完全可以更加好的合作nosql,key-value存储。

(推荐),不过假若你系统黄金时代起首未有安排贰个职业Id,那么将变成大气的改正,所以这些方案的特级状态是黄金年代此前就统筹专门的学问Id,当然事情Id的唯大器晚成性也是大家要考虑的。

结论:切合大型应用;生成的Id缺乏自个儿;攻克了三拾10位;索引效用十分低。

改进:

1)         (@dudu提点)在SQL Server
贰零零伍中新增加了NEWSEQUENTIALID函数。

详细请看:《理解newid()和newsequentialid()》

在钦命Computer上开创大于先前经过该函数生成的别的 GUID 的 GUID。 newsequentialid 发生的新的值是有规律的,则索引B+树的生成是有规律的,就不会导致索引列插入时移动大量笔录的标题。

但万大器晚成服务珍视新起动,其再度转移的GUID大概反倒变小(但照样维持唯后生可畏)。那在不小程度上加强了目录的习性,但并不能够确定保证所生成的GUID一贯增大。SQL的那一个函数爆发的GUID很简单就能够预测,因而不符合用来安全目标。

a)         只好做为数据库列的DEFAULT VALUE,不可能施行相近SELECT
NEWSEQUENTIALID()的语句.

b)         怎样得到生成的GUID.

借使生成的GUID所在字段做为外键要被其它表使用,大家就要求获得这几个变化的值。常常,PK是一个IDENTITY字段,大家得以在INSERT之后实施 SELECT
SCOPE_IDENTITY()来获得新生成的ID,但是出于NEWSEQUENTIALID()不是四个INDETITY类型,那些方式是做不到了,而她本人又不能不在默许值中应用,不得以先行SELECT好再插入,那么大家怎么样猎取呢?有以下三种艺术:

1
2
3
4
5
6
7
8
9
10
11
12
--1. 定义临时表变量
DECLARE @outputTable TABLE(ID uniqueidentifier)
INSERT INTO TABLE1(col1, col2)
OUTPUT INSERTED.ID INTO @outputTable
VALUES('value1', 'value2')
SELECT ID FROM @outputTable
  
--2. 标记ID字段为ROWGUID(一个表只能有一个ROWGUID)
INSERT INTO TABLE1(col1, col2)
VALUES('value1', 'value2')
--在这里,ROWGUIDCOL其实相当于一个别名
SELECT ROWGUIDCOL FROM TABLE1

敲定:切合大型应用,消亡了GUID冬辰个性导致索引列插入移动大批量笔录的标题。然而在关联表插入时须求重临数据库中变化的GUID;生成的Id非常不够本身;攻下了32个人。

2)         “COMB”(combined guid/timestamp,意思是:组合GUID/时间截)

(感谢:@
ethan-luo
 ,@lcs-帅 )

COMB数据类型的主导安排思路是如此的:既然GUID数据因并不是规律可言变成索引功能低下,影响了系统的质量,那么能或不可能通过整合的方法,保留GUID的12个字节,用另6个字节表示GUID生成的时刻(DateTime),这样我们将时刻消息与GUID组合起来,在保留GUID的唯生机勃勃性的同一时候扩张了有序性,以此来增进索引功效。

在NHibernate中,COMB型主键的变型代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/// <summary> /// Generate a new <see cref="Guid"/> using the comb algorithm.
/// </summary>
private Guid GenerateComb()
{
    byte[] guidArray = Guid.NewGuid().ToByteArray();
 
    DateTime baseDate = new DateTime(1900, 1, 1);
    DateTime now = DateTime.Now;
 
    // Get the days and milliseconds which will be used to build   
    //the byte string   
    TimeSpan days = new TimeSpan(now.Ticks - baseDate.Ticks);
    TimeSpan msecs = now.TimeOfDay;
 
    // Convert to a byte array       
    // Note that SQL Server is accurate to 1/300th of a   
    // millisecond so we divide by 3.333333   
    byte[] daysArray = BitConverter.GetBytes(days.Days);
    byte[] msecsArray = BitConverter.GetBytes((long)
      (msecs.TotalMilliseconds / 3.333333));
 
    // Reverse the bytes to match SQL Servers ordering   
    Array.Reverse(daysArray);
    Array.Reverse(msecsArray);
 
    // Copy the bytes into the guid   
    Array.Copy(daysArray, daysArray.Length - 2, guidArray,
      guidArray.Length - 6, 2);
    Array.Copy(msecsArray, msecsArray.Length - 4, guidArray,
      guidArray.Length - 4, 4);
 
    return new Guid(guidArray);
}

敲定:符合大型应用。即保留GUID的唯风流浪漫性的同有时间扩大了GUID有序性,升高了索引功效;消除了关联表业务问题;生成的Id远远不足本身;并吞了三11人。(生硬推荐)

3)         长度难点,使用Base64或Ascii85编码消除。(要注意的是上述有序性方案在进展编码后也会变得严节)

如:

GUID:{3F2504E0-4F89-11D3-9A0C-0305E82C3301}

当需求接收更加少的字符表示GUID时,只怕会利用Base64或Ascii85编码。Base64编码的GUID有22-二十三个字符,如:

7QDBkvCA1+B9K/U0vrQx1A

7QDBkvCA1+B9K/U0vrQx1A==

Ascii85编码后是十多个字符,如:

5:$Hj:Pf\4RLB9%kU\Lj

                   代码如:

         Guid guid = Guid.NewGuid();

         byte[] buffer = guid.ToByteArray();

         var shortGuid = Convert.ToBase64String(buffer);

                   结论:切合大型应用,减弱GUID的长短。生成的Id相当不够本身;索引功用好低。

7、  GUID TO Int64

对于GUID的可读性,有园友给出如下方案:(谢谢:@稻草黄的双翅

1
2
3
4
5
6
7
8
/// <summary>
/// 根据GUID获取19位的唯一数字序列
/// </summary>
public static long GuidToLongID()
{
    byte[] buffer = Guid.NewGuid().ToByteArray();
    return BitConverter.ToInt64(buffer, 0);
}

就要GUID转为了17个人数字,数字反映给客户能够鲜明水平上消除友好性难题。EG:

GUID: cfdab168-211d-41e6-8634-ef5ba6502a22    (不友好)

Int64:
5717212979449746068                                      (友好性勉强能够)

唯独作者的同伙说ToInt64后就不独一了。由此作者刻意写了个冒出测验程序,后文将交给测量试验结果截图及代码轻松表达。

(唯后生可畏性、业务切合性是能够度量的,那么些唯意气风发性肯定比可是GUID的,常常程序上都会铺排错误管理机制,举例特别后实行二回重插的方案……)

敲定:切合大型应用,生成相对友好的Id(纯数字)–—-因轻便和事情友好性而引入。**

8、  自身写编码准则

优点:全局唯生机勃勃Id,相符业务持续浓郁的提升(可能具体作业要求本人的编码准则等等)。

劣势:依照实际编码法规达成而分化;还要思量假使主键在事情上同意改造的,会带来外键同步的分神。

自身这边写五个编码法则方案:(只怕不唯风度翩翩,只是私家方案,也请大家建议自身的编码法则)

1)         十一人年月日时分秒+5位随机码+3位服务器编码  (那样就全盘单机完结生成全局独一编码)—共二十一位

短处:因为附带随机码,所以编码缺少一定的顺序感。(生成高唯生机勃勃性随机码的方案稍后给给出程序)

2)         10个人年月日时分秒+5位流水码+3位服务器编码 (那样流水码就需求整合数据库和缓存)—共贰拾位  (将影响顺序权重大的“流水码”放前边,影响顺序权重小的服务器编码放后)

症结:因为运用到流水码,流水码的成形必然会遇上和马克斯Id、种类表、Sequence方案中好像的标题

(为何平昔不阿秒?皮秒也不富有业务可读性,小编改用5位随机码、流水码取代,估算1秒内相应不会下99999[五位]条语法)

 

结论:符合大型应用,从作业上来说,有二个准绳的编码能展示产品的标准成度。(猛烈推荐)

 

 

GUID生成Int64值后是或不是还保有唯黄金时代性测验

测量检验遇到

 

重要测量试验思路:

  1. 依据内核数使用多线程并发生成Guid后再转为Int61人值,放入群集A、B、…N,多少个线程就有个别许个汇集。
  2. 再使用Dictionary字典高效查key的特色,将步骤第11中学变化的八个聚众全部加到Dictionary中,看是不是有重复值。

身体力行评释:测了 Dictionary<long,bool> 最大体量就在5999470左右,所以每一次并发生成的唯大器晚成值总的数量调节在这限制内,让测量试验高达最有效话。

关键代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
for (int i = 0; i <= Environment.ProcessorCount - 1; i++)
{
    ThreadPool.QueueUserWorkItem(
        (list) =>
        {
            List<long> tempList = list as List<long>;
            for (int j = 1; j < listLength; j++)
            {
                byte[] buffer = Guid.NewGuid().ToByteArray();
                tempList.Add(BitConverter.ToInt64(buffer, 0));
            }
            barrier.SignalAndWait();
        }, totalList[i]);
}

测验数据截图:                                                                           

 

 

数据一(循环1000次,测试数:1000*5999470)

 

数据二(循环5000次,测试数:5000*5999470)–跑了八个晚上……

 

 

感谢@Justany_WhiteSnow的正规化回答:(我们深入解析下,小编数学比较不好,稍后再说本身的敞亮)

GUID桶数量:(2 ^ 4) ^ 32 = 2 ^ 128

Int64桶数量: 2 ^ 64

设若种种桶的空子是均等的,则各种桶的GUID数量为:

(2 ^ 128) / (2 ^ 64) = 2 ^ 64 = 18446744073709551616

约等于说,其实重复的机会是风流倜傥对,只是概率难点。

楼主测量检验数是29997350000,发生再一次的票房价值是:

1 – ((1 – (1 / (2 ^ 64))) ^ 29997350000) ≈ 1 – ((1 – 1 / (2 ^ 64)) ^ (2
^ 32)) < 1 – 1 + 1 / (2 ^ 32) = 1 / (2 ^ 32) ≈ 2.3283064e-10

(唯生龙活虎性、业务适合性是能够衡量的,那一个唯少年老成性确定比可是GUID的,平常程序上都会配备错误处理机制,举例极度后施行一回重插的方案……)

(唯生龙活虎性、业务契合性是足以度量的,那些唯风流倜傥性明显比可是GUID的,通常程序上都会计划错误管理机制,例如非常后进行二回重插的方案……)

敲定:GUID转为Int64值后,也可以有所高唯生机勃勃性,能够选拔与品种中。

 

Random生成高唯朝气蓬勃性随机码

小编使用了八种Random生成方案,要Random生成唯风流洒脱首要成分便是种子参数要唯生龙活虎。(这是比较久早先写的测量检验案例了,向来找不到特别的博文放,前几天到底找到适合的地点了)

只是该测验是在单线程下的,八线程应选用不一致的Random实例,所以对结果影响不会太大。

  1. 选拔Environment.TickCount做为Random参数(即Random的暗中认可参数),重复性最大。
  2. 接收Date提姆e.Now.Ticks做为Random参数,存在重新。
  3. 利用unchecked((int)DateTime.Now.Ticks)做为Random参数,存在重新。
  4. 行使Guid.NewGuid().GetHashCode()做为random参数,测量试验空中楼阁重复(或存在性非常小)。
  5. 应用昂CoraNGCrypto瑟维斯Provider做为random参数,测量试验荒诞不经双重(或存在性一点都不大)。

即:

        static int GetRandomSeed()

        {

            byte[] bytes = new byte[4];

            System.Security.Cryptography.RNGCryptoServiceProvider rng

= new System.Security.Cryptography.RNGCryptoServiceProvider();

            rng.GetBytes(bytes);

            return BitConverter.ToInt32(bytes, 0);

        }

测量检验结果:

 

敲定:随机码使用OdysseyNGCrypto瑟维斯Provider或Guid.NewGuid().GetHashCode()生成的唯黄金时代性较高。

 

 

有的赏心悦目探讨(部分更新到原博文对应的地点)

一、

数据库文件体量只是一个参谋值,可水平扩张系统本性(如nosql,缓存系统)并不和文书体量有高指数的线性相关。

如taobao/qq的种类比拼byte系统慢,关键在于索引的命中率,缓存,系统的品位扩张。

假设数据库很少,你搞这么多byte能加强质量?

假若数据库比较大,你搞这么多byte不包容索引不相配缓存,不是害自已吗?

比方数据库要求伸缩性,你搞这么多byte,需求不停改程序,不是自找苦呢?

若果数据库供给移植性,你搞这样多byte,移植起来比不上重新设计,那是或不是众多商家不断加班的原委?

 

不依靠于于数据存款和储蓄系统是分支设计观念的精髓,完结战术性质量最大化,实际不是追求战略单机质量最大化。

 

毫无迷信数据库质量,不要迷信三范式,不要接纳外键,不要采纳byte,不要采纳自增id,不要使用存款和储蓄进程,不要使用在这之中等高校函授数,不要接收非标准sql,存储系统只做存款和储蓄系统的事。当出现系统本性时,如此设计的数据库能够越来越好的兑现迁移数据库(如mysql->oracle),实现nosql更改((mongodb/hadoop),实现key-value缓存(redis,memcache)。

 

二、

无尽程序猿有对品质认知有误区,如使用存款和储蓄进程替代符合规律程序,其实采纳存款和储蓄进程只是追求单服务器的高品质,当必要服务器水平扩张时,存款和储蓄进程中的业务逻辑正是您的晦气。

 

三、

除数字日期,能用字符串存款和储蓄的字段尽量接收字符串存款和储蓄,不要为节约那不值钱的1个g的硬盘而使用相近字节之类的字段,进而大幅就义系统可伸缩性和可扩大性。

永不为了追求所谓的性质,引进byte,使用byte注定是为期不远和困难移植,想想怎么html,email一贯流电行,因为它们接纳的是字符串表示法,只要有人类世世代代都能分析,如email把二进制转成base64存款和储蓄。除了实时系统,摄像外,提议使用字符串来囤积数据,系统质量的关键在于布满式,在于水平扩张。

 

 

这一次博文到此甘休,希望大家对这一次主题“如何在高并发分布式系统中生成全局唯豆蔻梢头Id”多提出自身宝贵的观念。此外望着以为适意,还请多帮推荐…推荐……

 

 

引入阅读

         
 C#生成唯风流倜傥值的办法汇总

相关:http://www.cnblogs.com/studyzy/archive/2008/11/28/1342950.html  

在SQL Server中选取种子表生成流水号注意顺序

.NET:“事务、并发、并发难题、事务隔开品级、锁”小议,珍视介绍:“事务隔开等第”怎么着影响 “锁”?

相关文章