跟著小郭郭一起學 SQL Server-05 資料類型-數字

騎著一台被精心地調校過的單車本身就是種娛樂,你的上半身會放鬆但穩定,雙手輕輕地扣著握把,核心肌群隱隱地發力,讓雙腿的踩踏規律而流暢,那會讓你理所當然地想要挑戰更高、更快、更遠

0812更新:我發現wordepress 在我貼上語法時會把單引號轉換成奇怪的符號,如果你的語法執行上有出現錯誤,請將文字前後的單引號刪除並重新輸入。

在上兩篇我們透過了建立資料庫、資料表、Schema 以及 資料 來解釋了 他們之間的關係。
這次我們要介紹的是在 SQL Server 中所使用的資料類型,從數字類型開始。

SQL Server 提供了許多種資料類型來對應各式各樣的需求,當我們決定資料的類型時,同時也決定了
資料本身佔的硬體空間大小、範圍、精確程度以及能被怎樣地呈現/處理/計算。
每個類型的泛用度不一,通常我們可以決定一個泛用的類型用以設計資料表,但考慮到大小、精準度、範圍等因素之後,最佳解跟泛用解可能不會是一致的。

我們可以在 SSMS 的 object explorer 中的 table底下的 Columns 去檢視已經被建立的資料表中,各欄位的類型。

這次的數字類型內容包含了:

bit
int、bigint、smallint & tinyint
float & real
decimal & numeric
money & smallmoney

詳細的官方說明如下:

https://docs.microsoft.com/en-us/sql/t-sql/data-types/numeric-types?view=sql-server-ver15

bit—————————————————————————————————-

首先是 bit ,bit 的特性是只會儲存資料為空值、0和1,所有非0數字都會被儲存為1,
0則儲存為0。

請打開一個 New Query,在輸入以下的指令之後,以F5執行:

declare @bit_test bit
set @bit_test=1
select @bit_test as ‘呈現結果1’
set @bit_test=0
select @bit_test as ‘呈現結果2’
set @bit_test=-2
select @bit_test as ‘呈現結果3’
set @bit_test=0.1
select @bit_test as ‘呈現結果4’


結果如前所述, 所有非0數字都會被儲存為1,
各位可以將 set @bit_test=1 這段改成其他數字後去嘗試,看會得出怎樣的結果。

至於上面的語法中,
declare 是宣告變數類型,set 則是指派變數的值,select則是將這個值叫出來。
結構如下:
declare @變數名稱 資料類型 –宣告變數型態
set @變數名稱=值 –指派值給這個變數
select @變數名稱 as 別名– 叫出該變數,並賦予其別名

在後續的章節我們會很常用到這些指令,但今天我們的焦點會放在資料類型上,


請打開一個 New Query,在輸入以下的指令之後,以F5執行:

declare @bit_test_non_numeric bit
set @bit_test_non_numeric=’Michael’
select @bit_test_non_numeric as ‘呈現結果5’

會發現出現錯誤,這是因為 SQL Server 沒辦法把 Michael 這個字串轉換並儲存為 bit 型態。
只有 True 或 False 的字串可以被儲存成 bit,

請打開一個 New Query,在輸入以下的指令之後,以F5執行:

declare @bit_test_non_numeric_2 bit
set @bit_test_non_numeric_2=’true’
select @bit_test_non_numeric_2 as ‘呈現結果6’

set @bit_test_non_numeric_2=’FALSE’
select @bit_test_non_numeric_2 as ‘呈現結果7’

順便說一下,在預設的狀態中,SQL server 是不分大小寫 (case insensitive) 的。
之後視情況可能會說明如何調整這些設定。

而 bit 的大小計算方式如下:在一張資料表中,如果有1~8個欄位是以 bit 類型儲存資料,則這些資料每筆的大小會是 1 byte,如果是9~16個欄位,則是 2 byte,以此類推。

bit —————————————————————————————————-
int—————————————————————————————————–

接下來則是 int 系列,分別為 int、bigint、smallint & tinyint
int 也就是整數 (integer) 的縮寫,這些類型會將資料儲存為整數類型,整數之後則無條件捨去。

請打開一個 New Query,在輸入以下的指令之後,以F5執行:

declare @int_test int
set @int_test=365
select @int_test as ‘呈現結果8’
set @int_test=0.9
select @int_test as ‘呈現結果9’
set @int_test=-10/3
select @int_test as ‘呈現結果10’

值得注意的事情是,這些 int 都有各自可以儲存的資料內容範圍,如果超過這個範圍,
就會出現溢位錯誤。

接下來則是 int 系列,分別為 int、bigint、smallint & tinyint
int 也就是整數 (integer) 的縮寫,這些類型會將資料儲存為整數類型,整數之後則無條件捨去。

請打開一個 New Query,在輸入以下的指令之後,以F5執行:

declare @int_test_overflow int
set @int_test_overflow=10000000000000
select @int_test_overflow as ‘呈現結果11’


就會出現溢位錯誤,各種 int 的範圍及儲存大小如下表所示:

Data typeRangeStorage
bigint-2^63 (-9,223,372,036,854,775,808) to 2^63-1 (9,223,372,036,854,775,807)8 Bytes
int-2^31 (-2,147,483,648) to 2^31-1 (2,147,483,647)4 Bytes
smallint-2^15 (-32,768) to 2^15-1 (32,767)2 Bytes
tinyint0 to 2551 Byte
資料來源 : https://docs.microsoft.com/en-us/sql/t-sql/data-types/int-bigint-smallint-and-tinyint-transact-sql?view=sql-server-ver15



int—————————————————————————————————–
float & real ——————————————————————————————-

float & real 則可以用於儲存帶有小數點的數字資料,他們能儲存的是相對近似的值,
使用 float 做為資料儲存類型時 ,會有一個引數 (argument) n 需要決定,實際寫作 float(n),
不輸入時,n預設為53,當 n <=24時,能儲存的精確度最高到小數點後7位,而當24<n<=53時, 能儲存的精確度最高到小數點後15位 ,但能儲存的資料皆為近似值,而將資料儲存為 real 的效果等同於儲存為 float (24)。

接下來則是 int 系列,分別為 int、bigint、smallint & tinyint
int 也就是整數 (integer) 的縮寫,這些類型會將資料儲存為整數類型,整數之後則無條件捨去。

請打開一個 New Query,在輸入以下的指令之後,以F5執行:

declare @float_test float (53)
set @float_test=0.123456789123456789
select @float_test as ‘呈現結果12’

set @float_test=convert(real,10)/convert(real ,3)
select @float_test as ‘呈現結果13’

set @float_test=convert(real,100)/convert(real ,7)
select @float_test as ‘呈現結果14’

declare @real_test real
set @real_test=0.0123456789123456789
select @real_test as ‘呈現結果15’

set @real_test=convert(real,10)/convert(real ,3)
select @real_test as ‘呈現結果16’
set @real_test=convert(real,100)/convert(real ,7)
select @real_test as ‘呈現結果17’


當我們拿起小算盤,我們就會發現其中,13跟14的計算結果好像怪怪的,應該分別是 3.33333333….. 跟 14.28571428571…..,即使將四捨五入納入考量,也很奇怪,這就是因為他儲存的是計算結果的近似值。

這使得會使得我們在實際上比較少使用 float & real ,而是更偏好接下來的 decimal & numeric,
不過如果需求中的資料範圍相當大,或是空間配置相對吃緊並且對精確程度要求相對不高的話,float & real 會是可用的選項。

Data typeRangeStorage
float– 1.79E+308 to -2.23E-308, 0 and 2.23E-308 to 1.79E+308Depends on the value of n
當n=<24時,4bytes,當24<n<=53時,8bytes
real– 3.40E + 38 to -1.18E – 38, 0 and 1.18E – 38 to 3.40E + 384 Bytes
資料來源 :https://docs.microsoft.com/en-us/sql/t-sql/data-types/float-and-real-transact-sql?view=sql-server-ver15


float & real ——————————————————————————————-

decimal & numeric ———————————————————————————-

decimal & numeric 基本上幾乎相同,其中 numeric 是為了相容較舊版本的 SQL server,
所以實務上現在還是較常使用 decimal ,使用 decimal 做為資料儲存類型時,則需要決定兩個引數:

(p,s)

其中p 決定了這個欄位可以放下多少位數字,超過的話會產生溢位錯誤, s則決定這些數字中有多少可以用於呈現小數點後的位數,超過的部分會被四捨五入。。

舉例來說,decimal (10,2)代表的是這個類型能夠儲存的資料上限是8位數,並精確到小數點後兩位。
p的上限是38,預設則是18。 s的上限取決於p,預設值則是0。

請打開一個 New Query,在輸入以下的指令之後,以F5執行:

declare @decimal_test decimal (30,15)
set @decimal_test=0.123456789123456789
select @decimal_test as ‘呈現結果18’

set @decimal_test=convert(decimal (10,5),10)/convert(decimal (10,5),3)
select @decimal_test as ‘呈現結果19’

set @decimal_test=convert(decimal (10,5),100)/convert(decimal (10,5) ,7)
select @decimal_test as ‘呈現結果20’

declare @numeric_test numeric (30,15)
set @numeric_test=0.123456789123456789
select @numeric_test as ‘呈現結果21’

set @numeric_test=convert(numeric (10,5),10)/convert(numeric (10,5),3)
select @numeric_test as ‘呈現結果22’

set @numeric_test=convert(numeric (10,5),100)/convert(numeric (10,5) ,7)
select @numeric_test as ‘呈現結果23’

會發現有四捨五入的狀況,但計算結果已經不再會出現如 float 那樣的近似值。

以下則是 decimal & numeric 的資料大小,由p決定:

PrecisionStorage bytes
1 – 95
10-199
20-2813
29-3817
資料來源:https://docs.microsoft.com/en-us/sql/t-sql/data-types/decimal-and-numeric-transact-sql?view=sql-server-ver15

decimal & numeric ———————————————————————————

money & smallmoney ——————————————————————————-

你可以分別把 money看成decimal(19,4),以及smallmoney視為 decimal(10,4),你會發現他們所占空間相對更小,並且可以在轉換成文字的過程中,自動加上千分號。

請打開一個 New Query,在輸入以下的指令之後,以F5執行:

declare @money_test money
set @money_test=123456789
select convert(nvarchar,@money_test,1) as ‘呈現結果24’

以下則是 money & smallmoney 的範圍及大小:

Data typeRangeStorage
money-922,337,203,685,477.5808 to 922,337,203,685,477.5807 (-922,337,203,685,477.58
to 922,337,203,685,477.58 for Informatica. Informatica only supports two decimals, not four.)
8 bytes
smallmoney– 214,748.3648 to 214,748.36474 bytes
資料來源: https://docs.microsoft.com/en-us/sql/t-sql/data-types/money-and-smallmoney-transact-sql?view=sql-server-ver15

money & smallmoney ——————————————————————————-

以上是會在 SQL server 中使用的數字類型,
下次我們會進入字串的資料類型。

發表留言