有許多類型的數(shù)據(jù)與 SQL Server 兼容,重要的是要了解它們是什么以避免不兼容的數(shù)據(jù)類型出現(xiàn)問題。理解兼容的數(shù)據(jù)類型也是理解數(shù)據(jù)類型優(yōu)先級(jí)的基礎(chǔ),它決定了在處理兩種不同類型的對(duì)象時(shí)會(huì)產(chǎn)生什么類型的數(shù)據(jù)。 在本指南中,我們將介紹 SQL Server 支持的所有數(shù)據(jù)類型,以及使用 Transact-SQL 或 Microsoft .NET Framework 定義自定義數(shù)據(jù)類型的過程。
什么是 SQL Server?
在深入了解 SQL Server 支持的許多數(shù)據(jù)類型之前,先快速回顧一下 SQL Server 是什么。Microsoft 開發(fā)了 SQL Server 作為關(guān)系數(shù)據(jù)庫管理系統(tǒng) (RDBMS)。SQL Server 使用 SQL,這是使用各種關(guān)系數(shù)據(jù)庫的標(biāo)準(zhǔn)語言。 Microsoft 的 SQL Server 不再專屬于 Windows 環(huán)境,現(xiàn)在可以在 Linux 上使用,這對(duì)于有興趣使用 SQL Server 的人來說是個(gè)好消息。此外,微軟的云平臺(tái) Azure 支持 SQL Server。因此,如果您需要一個(gè)地方來托管它,那么沒有比原生解決方案更好的地方了。
微軟將其稱為“最了解 SQL Server 的云”,Azure SQL Server 確實(shí)受益于無縫集成、簡單性和可靠性,因?yàn)榉?wù)器和云基礎(chǔ)設(shè)施都是由同一家公司開發(fā)和維護(hù)的。 但是,無論您在何處托管 SQL Server,都必須注意 SQL Server 使用的 SQL 語言略有不同。Microsoft 開發(fā)了 Transact-SQL (T-SQL),它與標(biāo)準(zhǔn) SQL 非常相似,但定義了一組對(duì) SQL Server 編程所必需的專有概念。 如果您熟悉 SQL,則使用 Transact-SQL 并不難,您將能夠輕松使用 SQL Server。但有效使用 SQL Server 的另一個(gè)關(guān)鍵方面是了解它支持的所有數(shù)據(jù)類型。
為什么數(shù)據(jù)類型很重要?
錯(cuò)誤的數(shù)據(jù)類型會(huì)導(dǎo)致數(shù)據(jù)庫性能、查詢優(yōu)化和數(shù)據(jù)截?cái)嗟葐栴}。這些問題通常是開發(fā)團(tuán)隊(duì)首先意識(shí)到的,因?yàn)樗鼈兪歉櫵俣群托阅艿膯栴}。盡管如此,問題可能會(huì)蔓延到整個(gè)組織,導(dǎo)致數(shù)據(jù)完整性問題和其他嚴(yán)重挑戰(zhàn)。 如果您是 SQL Server 的新手,那么數(shù)據(jù)類型的絕對(duì)數(shù)量可能會(huì)讓人不知所措。
但是,它們組織得井井有條并且有據(jù)可查,只要您了解計(jì)劃存儲(chǔ)的數(shù)據(jù)類型,就可以更容易地找到所需的內(nèi)容。當(dāng)然,雖然您可以隨時(shí)參考,但獲得 SQL Server 數(shù)據(jù)類型的知識(shí)對(duì)于長期的效率和優(yōu)化至關(guān)重要。深入研究后,您會(huì)發(fā)現(xiàn)存在一些重疊,并且只有在您完全了解所有選項(xiàng)的情況下,才能知道何時(shí)選擇浮點(diǎn)數(shù)而不是十進(jìn)制數(shù)或選擇可變長度而不是固定值。
有哪些不同的數(shù)據(jù)類別?
下面是 SQL Server 中每個(gè)數(shù)據(jù)類別的概覽,以及適合每個(gè)數(shù)據(jù)類型的所有數(shù)據(jù)類型。
精確數(shù)字
使用精確的數(shù)字?jǐn)?shù)據(jù)類型時(shí),了解您的選項(xiàng)很重要,這樣您就可以選擇適合您的用例的最小數(shù)據(jù)類型。還需要選擇與您存儲(chǔ)的數(shù)字類型相對(duì)應(yīng)的數(shù)據(jù)類型,例如貨幣的貨幣或小貨幣。
- tinyint:最小的整數(shù)存儲(chǔ)類型,能夠存儲(chǔ) 0 到 255 之間的數(shù)字。
- smallint:整數(shù)存儲(chǔ)類型,大小為兩倍,最多 2 個(gè)字節(jié)。
- int:整數(shù)存儲(chǔ)類型,最多存儲(chǔ) 4 個(gè)字節(jié)。
- bigint:最大的整數(shù)存儲(chǔ)類型,最多可容納 8 個(gè)字節(jié)的數(shù)據(jù)。
- 十進(jìn)制和數(shù)字:這些同義詞指的是相同的數(shù)據(jù)類型,其特點(diǎn)是其固定的小數(shù)位數(shù)和精度。
- bit:此數(shù)據(jù)類型的值始終為 1、0 或 NULL。您可以將真/假數(shù)據(jù)轉(zhuǎn)換為位,其中 1 等于 True,0 等于 False。
- smallmoney:此數(shù)據(jù)類型表示貨幣值,最多允許兩位小數(shù)。
- money:這是另一種貨幣數(shù)據(jù)類型,但最多允許四位小數(shù)。
Unicode 字符串
如果您不熟悉 Unicode,它是一種通用標(biāo)準(zhǔn),它為每個(gè)字符分配一個(gè)唯一編號(hào),從而允許對(duì)書面文本進(jìn)行一致的編碼和表示。例如,Unicode 中的“嘿”將被分解如下:U+0048(“H”)、U+0065(“E”)和 U+0059(“Y”)。SQL Server 支持使用這些字符串的所有 Unicode 字符數(shù)據(jù)。它們可以是固定的或可變的。
- nchar:大小固定,推薦在列數(shù)據(jù)大小一致時(shí)使用。
- nvarchar:大小可變,建議在列中的數(shù)據(jù)大小變化很大時(shí)使用。
- ntext:計(jì)劃在 SQL Server 的未來版本中刪除,設(shè)計(jì)為 Unicode 的可變長度數(shù)據(jù)類型。Microsoft 建議改為使用 nvarchar(max)。
近似數(shù)值
當(dāng)數(shù)值數(shù)據(jù)不能精確表示時(shí),它被稱為“浮點(diǎn)”數(shù)值數(shù)據(jù),您可以使用近似數(shù)數(shù)據(jù)類型來存儲(chǔ)它。對(duì)于浮點(diǎn)數(shù)據(jù)類型,數(shù)字使用科學(xué)計(jì)數(shù)法寫入,因此 825,000 將存儲(chǔ)為 8.5 x 10 5。浮點(diǎn)數(shù)可以非常大或非常小。浮點(diǎn)數(shù)和十進(jìn)制數(shù)據(jù)類型都可以存儲(chǔ)帶有小數(shù)的數(shù)字——不同之處在于浮點(diǎn)數(shù)需要更少的存儲(chǔ)空間,而小數(shù)則更精確。SQL Server 支持浮點(diǎn)數(shù)和實(shí)數(shù)數(shù)據(jù)類型的兩種近似數(shù)值。
- float:雙精度浮點(diǎn)數(shù),相當(dāng)于 8 個(gè)字節(jié)或 64 位。
- real:單精度浮點(diǎn)數(shù),相當(dāng)于 4 個(gè)字節(jié)或 32 位。
字符串
字符串有一個(gè)不言自明的名稱:這些數(shù)據(jù)類型用于存儲(chǔ)字符。它們的大小可以是固定的或可變的。
- char:使用靜態(tài)內(nèi)存位置的固定大小的字符串?dāng)?shù)據(jù)。當(dāng)您知道字符串的長度并且列中的所有字符串都相同時(shí)是理想的。
- varchar:使用動(dòng)態(tài)內(nèi)存位置的可變大小的字符串?dāng)?shù)據(jù)。如果您不確定字符串的長度或列中字符串的長度會(huì)有很大差異時(shí)使用。
- text:計(jì)劃在 SQL Server 的未來版本中刪除,設(shè)計(jì)為非 Unicode 數(shù)據(jù)的可變長度數(shù)據(jù)類型。Microsoft 建議將其替換為 varchar (max)。
二進(jìn)制字符串
二進(jìn)制數(shù)據(jù)類型支持固定或可變的數(shù)據(jù)字符串。字符串和二進(jìn)制字符串之間的區(qū)別在于它們包含的數(shù)據(jù):字符串通常存儲(chǔ)文本,但也可以存儲(chǔ)數(shù)字或符號(hào)。二進(jìn)制字符串通常以字節(jié)的形式存儲(chǔ)非傳統(tǒng)數(shù)據(jù),例如圖片。
- binary:固定長度,當(dāng)列中的數(shù)據(jù)大小一致時(shí)非常適合使用。
- varbinary:當(dāng)列中的數(shù)據(jù)大小變化很大時(shí),可變長度是理想的。
- 圖片:計(jì)劃在 SQL Server 的未來版本中刪除,旨在存儲(chǔ)可變長度的二進(jìn)制數(shù)據(jù)。Microsoft 建議將其替換為 varbinary (max)。
日期和時(shí)間
這些數(shù)據(jù)類型明確設(shè)計(jì)用于存儲(chǔ)日期和時(shí)間。有些支持時(shí)區(qū)意識(shí),有些則不支持。在處理日期和時(shí)間時(shí),選擇一種保持條目格式一致的數(shù)據(jù)類型并選擇一種足夠靈活以支持您需要的詳細(xì)程度(即一天中的時(shí)間、時(shí)區(qū)等)的數(shù)據(jù)類型至關(guān)重要。
- date:定義日期。默認(rèn)格式為 YYYY-MM-DD,但可以采用 20 多種不同的方式進(jìn)行格式化,包括 DMY、DYM 和 YMD。
- datetimeoffset:定義日期和時(shí)間。此數(shù)據(jù)類型可識(shí)別時(shí)區(qū)。 datetime2:上述數(shù)據(jù)類型的擴(kuò)展,具有可選的小數(shù)秒精度。
- datetime:與 datetime2 類似,但小數(shù)秒精度較低。
- smalldatetime:定義日期和時(shí)間,但秒始終為零。
- time:定義一天中的某個(gè)時(shí)間,但不知道時(shí)區(qū)。
其他數(shù)據(jù)類型
SQL Server 中存在其他數(shù)據(jù)類型,但它們并不完全適合上述任何類別。因此,這些數(shù)據(jù)類型僅存在于“其他”下。其他數(shù)據(jù)類型包括:
- rowversion:用于在表中標(biāo)記行的版本。不保留日期或時(shí)間的簡單遞增數(shù)字。
- ?hierarchyid:可變長度系統(tǒng)數(shù)據(jù)類型,用于表示層次結(jié)構(gòu)中的位置。
- uniqueidentifier:能夠存儲(chǔ)多達(dá) 16 個(gè)字節(jié)的全局唯一標(biāo)識(shí)符 (GUID)。
- sql_variant:存儲(chǔ) SQL 支持的各種數(shù)據(jù)類型。sql_variant 最重要的部分是它是可變的。例如,一個(gè) sql_variant 列可以在一行中包含一個(gè) int,而在另一行中包含一個(gè)二進(jìn)制值。為了應(yīng)用算術(shù)運(yùn)算,如 SUM 或 PRODUCT,必須首先將類型轉(zhuǎn)換為與該運(yùn)算一起使用的東西。
- xml:存儲(chǔ) XML 數(shù)據(jù)。
- 空間幾何類型:表示平面坐標(biāo)系中的數(shù)據(jù)。
- 空間地理類型:表示圓形地球坐標(biāo)系中的數(shù)據(jù)。
- 表:用于存儲(chǔ)結(jié)果以供稍后處理的特殊數(shù)據(jù)類型。
定義自定義數(shù)據(jù)類型
如果您的自定義數(shù)據(jù)類型在上述任何類別中都不是特定的,您仍然可以將其帶到 SQL Server 上,只要您提前設(shè)置它。使用 Transact-SQL 或 Microsoft .NET Framework,開發(fā)人員可以為他們的項(xiàng)目定義自定義數(shù)據(jù)類型。
在創(chuàng)建自定義數(shù)據(jù)類型時(shí),SQL Server 的界面有一些工具可以幫助您生成 Transact-SQL。您需要指定的字段包括架構(gòu)、名稱、基礎(chǔ)數(shù)據(jù)類型、長度、允許空值、字節(jié)大小、默認(rèn)值中的可選字段以及數(shù)據(jù)類型必須遵循的任何規(guī)則。例如,電子郵件字段可能會(huì)使用 varchar 基礎(chǔ)類型,并且必須包含 @ 和 .,以及不允許使用的字符列表。然后,您將設(shè)置一個(gè)適合您需要的最大長度,并且字節(jié)數(shù)將自動(dòng)填充到界面中。
如果您需要?jiǎng)?chuàng)建自己的數(shù)據(jù)類型,Microsoft 會(huì)提供更多信息。
選擇正確的數(shù)據(jù)類型
使用 SQL Server 時(shí),為正在使用的任何數(shù)據(jù)選擇正確的數(shù)據(jù)類型至關(guān)重要。不這樣做可能會(huì)導(dǎo)致數(shù)據(jù)質(zhì)量問題或數(shù)據(jù)丟失,例如在您使用數(shù)據(jù)類型來存儲(chǔ)不打算這樣做的日期和時(shí)間的情況下。錯(cuò)誤的數(shù)據(jù)類型也會(huì)對(duì)??查詢和性能產(chǎn)生負(fù)面影響。
例如,如果您需要存儲(chǔ)整數(shù),您可能會(huì)認(rèn)為只需選擇精確的數(shù)字?jǐn)?shù)據(jù)類型就不會(huì)出錯(cuò)。但是,不必要地使用 bigint 類型來存儲(chǔ)像年齡這樣的小而簡單的數(shù)字會(huì)導(dǎo)致資源浪費(fèi)。
大多數(shù)人會(huì)告訴您在處理數(shù)字?jǐn)?shù)據(jù)時(shí)從 smallint、integer、bigint 或 decimal 中進(jìn)行選擇。如果您正在處理非常大的數(shù)字,他們可能會(huì)建議 decfloat 或 float。但是,當(dāng)您處理特定用例時(shí),此建議過于簡單和籠統(tǒng)。