国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 數(shù)據(jù)庫(kù) > 文庫(kù) > 正文

SQL利用Function創(chuàng)建長(zhǎng)整形的唯一ID示例代碼

2020-10-29 21:46:39
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

前言

在設(shè)計(jì)表的時(shí)候考慮主鍵的數(shù)據(jù)類(lèi)型是長(zhǎng)整形還是字符串,最簡(jiǎn)單的方式當(dāng)然是newid(),但這也有個(gè)問(wèn)題,就是主鍵長(zhǎng)度過(guò)長(zhǎng)(36個(gè)字),數(shù)據(jù)量一多,必然會(huì)影響數(shù)據(jù)庫(kù)操作的效率,而且大大增加了數(shù)據(jù)文件和索引文件所占用的空間。而且,newid返回的字符串是隨機(jī)的,查詢(xún)結(jié)果不能保證按保存順序返回。這對(duì)于有順序要求的系統(tǒng)來(lái)說(shuō),需要額外增加順序列來(lái)進(jìn)行排序,這也導(dǎo)致查詢(xún)語(yǔ)句更加復(fù)雜。這也是主要放棄newid作為主鍵的主要原因。因此考慮用長(zhǎng)整形來(lái)作數(shù)據(jù)表主鍵的數(shù)據(jù)類(lèi)型。

實(shí)現(xiàn)方法

一開(kāi)始在C#等面向?qū)ο裾Z(yǔ)言中編寫(xiě)一個(gè)獲取PK的方法,那是很順序就完成了。

接著是SQL中,如果要用腳本導(dǎo)入數(shù)據(jù),那就要提供一個(gè)SQL的方法來(lái)獲取PK。

最初設(shè)計(jì)PK的組成:時(shí)間(yyMMddHHmmssmsS) + '4位隨機(jī)數(shù)'   ,于是卡卡很快完成dbo.pk()

Create function dbo.pk()returns bigintasbegin  declare @pk as bigint,@fix bigint,@idx int,@ts as datetime set @ts = GETDATE() set @pk = convert(bigint,convert(varchar(6),@ts,12) + replace(convert(varchar(12),@ts,114),':',''))*10000 select @idx = A*10000 from vRand return (@pk + @idx)endgo

然后來(lái)獲取一個(gè)10000PK測(cè)試:

declare @tab as table(pk bigint)declare @i as integerset @i =0while(@i<10000)begininsert @tabselect dbo.pk() set @i = @i+1endselect pk,count(1) cntfrom @tab group by pk having COUNT(1)>1

oh my god!竟然有30多個(gè)重復(fù)的。

可見(jiàn)這個(gè)方法,做為獲取單個(gè)PK,那問(wèn)題不大,但在做批量保存的時(shí)候,可能會(huì)發(fā)生主鍵沖突。

因此再設(shè)計(jì)一個(gè)支持批量保存的。

既然4位隨機(jī)數(shù)不能保證毫秒級(jí)的唯一,那就只能用有序數(shù)了,把PK的組成改為:時(shí)間(yyMMddHHmmssmsS) + '4位有序數(shù)'

再考慮到年份只是2位數(shù),跟面向?qū)ο裰械腜K組成有機(jī)會(huì)在202x年之后存在沖突,因此增加一個(gè)標(biāo)識(shí) ‘1'+yy作為年以延長(zhǎng)千年蟲(chóng)問(wèn)題,雖然還是有機(jī)會(huì)發(fā)生沖突,但那也是幾百年以后的事情了。

但是為了保持效率和沖突的概率,還是將PK改為:'1'+時(shí)間(yyMMddHHmmssms) + '4位有序數(shù)'.

接下來(lái)又是一頓卡卡卡,dbo.pks(@count)已出:

CREATE function dbo.pks(@count as int)returns @pks table(pk bigint,id int)asbegin   declare @pk as bigint,@fix bigint,@idx int,@ts as datetime,@lop int,@i int  set @ts = GETDATE()  set @pk = convert(bigint,'1'+convert(varchar(6),@ts,12) + replace(convert(varchar(11),@ts,114),':',''))*10000  set @idx =0  set @lop = CEILING(@count/10000.0)   set @i = 1  while(@lop >0)  begin    set @pk = @pk + 10000    set @idx = 0    while(@idx<10000 and @idx<@count)    begin      insert @pks(pk,id)      values(@pk+@idx,@idx+ @i)      set @idx = @idx +1    end    set @lop = @lop -1    set @i = @i+10000  end  returnendgo

批量測(cè)試一下

select * from dbo.pks(500000)

正常返回500000行,沒(méi)有一行重復(fù)!

在返回的結(jié)果列中,ID是從1開(kāi)始編號(hào)的,這也保持與SQL的Row_number保持一致,方便SQL編程引用。

OK,到這里用利用SQL function獲取PK就搞定了!

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)武林網(wǎng)的支持。

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 罗平县| 铜陵市| 平邑县| 阜康市| 西城区| 邓州市| 德惠市| 贡嘎县| 澄城县| 那坡县| 九龙城区| 临潭县| 大埔区| 八宿县| 隆尧县| 奈曼旗| 大港区| 孟州市| 苗栗县| 大冶市| 阜宁县| 自治县| 鹰潭市| 聂荣县| 镇江市| 罗田县| 周口市| 孟村| 秦皇岛市| 远安县| 云和县| 渝北区| 武定县| 建水县| 乐陵市| 思南县| 黎川县| 礼泉县| 张家川| 枣强县| 佛学|