设为首页 收藏本站
查看: 635|回复: 0

[经验分享] 精準比較文字與UNIQUEIDENTIFIER資料型態

[复制链接]
累计签到:91 天
连续签到:1 天
发表于 2016-8-2 12:18:25 | 显示全部楼层 |阅读模式
首先先介紹一個GUID在資料庫的產生方式,當應用程式系統無法產生一個唯一值時候,可以有以下幾種方式
1.  IDENTITY
2.  ROWVERSION
3.  SEQUENCE
4.  UNIQUEIDENTIFIER
其中UNIQUEIDENTIFIER的資料屬性,可以使用DB的NEWID()函數,產生一個類似這樣的資料值。
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx ,例如實際為(88B2A026-6049-46F0-AED0-8E940EDF3B01)
其中x值為0-9或是A-F。
基本上使用它時機,就是產生一個亂數值,並且希望是可以全域唯一(Global Unique)。所以首先讓我們驗證一個資料表,同時產生大量包含UNIQUEIDENTIFIER的資料列,並且同時間使用兩連線大量新增,驗證重複性與唯一性。
--第一條連線,建立TABLE與連續新增10000資料
use [TSQL2014]
GO
IF OBJECT_ID('tblGUID') is not null
   DROP TABLE tblGUID
GO
CREATE TABLE tblGUID
(xid INT IDENTITY , --自動加號
xguid uniqueidentifier, --GUID 編碼
xapp sysname default(app_name())--記錄那種應用程式新增
)
GO
--連續產生10000
INSERT INTO tblGUID(xguid) SELECT NEWID()
GO 10000
--第二條連線,使用SQLCMD新增5000資料
C:\>sqlcmd
1> use TSQL2014
2> INSERT INTO tblGUID(xguid) SELECT NEWID()
3> go 5000
接下來就是開始比較是否會重複,過程中可以開啟【包含實際執行計畫】,查看比較的結果與成本,因為UNIQUEIDENTIFIER欄位屬性,難使用INDEX 去加速查詢,原因就是該類型資料是屬於沒有次序的資料屬性,建立INDEX之後,很快就因為INSERT大量資料之後,讓INDEX發生FRAGMENTATION。
當然結果是不會重複
緊接著重頭戲要來,該部分就是查詢其中一筆資料,根據xguid值找尋資料表中是否對應資料行。
--查詢其中一個GUID是否存在於稍早新增的資料
SELECT *
FROM tblGUID
WHERE xguid='0296716C-A9B2-4968-917F-51CDC37715BD'
GO
如果這時候如果給定指定的xguid欄位的數值過長,依然可以比對出來結果L 原因很簡單,因為GUID與文字字串的比較,當輸入文字字串過長的時候,系統會自動TRUNCATE(截斷)過長的字串,所以超過的36個字元之後文字都會被自動截斷。
--查詢其中一個GUID是否存在於稍早新增的資料
SELECT *
FROM tblGUID
WHERE xguid='0296716C-A9B2-4968-917F-51CDC37715BD.....'
GO
要解決上述的字串過長,自動被截斷的狀況,可以參考以下的方式使用CAST AS VARCHAR(MAX)轉換後進行比對。
--使用CAST AS VARCHAR(MAX)轉換後進行比對
--解決字串過長問題轉換成 varchar(max)
SELECT *
FROM tblGUID
WHERE cast(xguid as varchar(max))=cast('0296716C-A9B2-4968-917F-51CDC37715BD' as varchar(max))
GO
--過長字串就已經可以被濾掉
SELECT *
FROM tblGUID
WHERE cast(xguid as varchar(max))=cast('0296716C-A9B2-4968-917F-51CDC37715BD....' as varchar(max))
GO
結果再進一步測試的時候,發現上述的CAST AS VARCHAR(MAX)轉換後進行比對,竟然無法處理多於空白的字串
--使用CAST AS VARCHAR(MAX)轉換後進行比對
--無法處理空白字元
SELECT *
FROM tblGUID
WHERE cast(xguid as varchar(max))=cast('0296716C-A9B2-4968-917F-51CDC37715BD' as varchar(max))
GO
SELECT *
FROM tblGUID
WHERE cast(xguid as varchar(max))=cast('0296716C-A9B2-4968-917F-51CDC37715BD   ' as varchar(max))
GO
--結果空白無法被處理
為了要解決這樣的狀況,過程中讓我想到就是再轉換成varbinary(max)的方式,因為binary的部分針對空白會視為不一樣,果真就可以順利解決該問題。
--使用CAST AS VARCHAR(MAX)尚未有能力處理空白字元
SELECT *
FROM   tblGUID
WHERE  cast(xguid as varchar(max))=cast('0296716C-A9B2-4968-917F-51CDC37715BD   ' as varchar(max))
GO
--使用CAST AS VARCHAR(MAX)與CAST AS VARBINARY(MAX)轉換後進行比對
SELECT *
FROM tblGUID
WHERE cast(cast(xguid as varchar(max))as varbinary(max))=
      cast(cast('0296716C-A9B2-4968-917F-51CDC37715BD   ' as varchar(max)) as varbinary(max))
GO
--結果空白可以被處理
結論
基本上使用資料庫的UNIQUEIDENTIFIER資料型別處理跟字串比較時候,要特別留意,基本上該資料型態長度為CHAR(36)超過的部分,自動會在比較的時候被去除,導致異狀發生。過程中可以搭配CAST AS VARCHAR(MAX)方式,處理過長字元的比較,但是該方式仍無法處理字串緊接空白字元的特殊狀況,唯一可以解決UNIQUEIDENTIFIER資料型別處理跟字串比較時候可能情境,就是搭配CAST AS VARCHAR(MAX)與CAST AS VARBINARY(MAX)兩種組合。當然各位擔心的成本問題,一併分享給大家,就是差異不大,況且任何UNIQUEIDENTIFIER資料型別的欄位,都強烈不建議建立INDEX,因為任何新增UNIQUEIDENTIFIER資料後,該INDEX就會有很高的FRAGMENTATION,導致最佳化執行器捨棄對該索引的使用,另外UNIQUEIDENTIFIER資料欄位,若是有INDEX也會導致新增過程效能變慢。
--成本cost比較
--直接比較,無法處理過長問題
SELECT *
FROM  tblGUID
WHERE xguid='0296716C-A9B2-4968-917F-51CDC37715BD   '
GO
--可以無法處理過長問題,但是無法處理空白字元
SELECT *
FROM  tblGUID
WHERE cast(xguid as varchar(max))=cast('0296716C-A9B2-4968-917F-51CDC37715BD   ' as varchar(max))
GO
--可以處理過長問題,也可以處理空白字元
SELECT *
FROM tblGUID
WHERE cast(cast(xguid as varchar(max))as varbinary(max))=
      cast(cast('0296716C-A9B2-4968-917F-51CDC37715BD   ' as varchar(max)) as varbinary(max))
GO


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-252065-1-1.html 上篇帖子: SQL SERVER数据库文件收缩 下篇帖子: CROSS APPLY 與 OUTER APPLY查詢
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表