通過實戰探索資料庫中的char、varchar、varchar2、nvarchar2的部分區別
前言
注:本文的實踐是在oracle資料庫中進行的,主要基於位元組與字元以及定長與變長方面考慮,探索這四個型別的部分區別
Oracle資料庫中,char、varchar、varchar2、nvarchar2是我們常用到的資料型別
(MySQL中沒有varchar2和nvarchar2,也可以參考本文來比較MySQL中char和varchar的區別)
下面我們做一個簡單的實驗吧:
首先建立一個表,裡面有aa,bb,cc,dd四個欄位,型別分別是char、varchar、varchar2、nvarchar2。如下圖所示:
一、變長與定長
我們用下面的SQL語句插入一條資料,所有的欄位都是5個位元組代表的數字,排除了字元和位元組的影響:
- insertinto test (aa, bb, cc, dd)
- values
- ('01234', '01234', '01234', '01234');
我們看下下圖中的藍底背景:
aa欄位(藍色部分較長,因為右邊有5個空格):
bb欄位
cc欄位
dd欄位
對比上面的4張圖中的藍色部分長度,aa欄位的值最長,其他都相同。
我們可以得出下面的結論:
char是固定長度,長度不夠的情況下,用空格代替
varchar、varchar2、nvarchar2是可變長度,按照實際的長度儲存
二、儲存單位
1、預設儲存單位
我們再用下面的SQL語句插入一條資料,所有的欄位都是10個漢字(因為漢字是字元型別,排除變長與定長的影響)
- insertinto test (aa, bb, cc, dd)
- values
- ('一二三四五六七八九十', '一二三四五六七八九十', '一二三四五六七八九十', '一二三四五六七八九十');
出現如下錯誤,提示最大值是10:
我們把aa改為一二三四五,其他欄位不變,又報錯,提示最大值是10:
我們把bb改為一二三四五,cc、dd欄位不變,又出現錯誤,提示最大值是10
我們把cc改為一二三四五試一下,插入成功!查詢一下:
我們再用下面的SQL語句插入一條資料,所有的欄位都是數字(因為數字是位元組型別)
- insertinto test (aa, bb, cc, dd)
- values
- ('0123456789'
直接插入了,沒有報錯!得到下面的結果:
上面的操作可以得出:char、varchar、varchar2預設儲存單位是位元組,nvarchar2預設儲存單位是字元
2、其它儲存單位
2.1 char、varchar、varchar2還可以用字元作為單位
既然char、varchar、varchar2預設儲存單位是位元組,那麼這三種類型能不能用字元作為儲存單位呢?
用下面的例子來測試,結果是都可以插入:
2.2 nvarchar2不能用位元組作為儲存單位
char、varchar、varchar2的長度單位可以是byte和char,那麼nvarchar2的長度單位能不能是byte呢?
請看下面這個實驗:把四個欄位都設定成byte型別,則發生報錯:
而把前三個設定為byte,最後一個預設呢?下面的實驗表示可以成功建立表以及插入資料:
通過上面的操作,我們可以得出以下結果:
char、varchar、varchar2儲存長度單位可以是位元組,也可以是字元。
nvarchar2儲存長度單位是字元!
3 探索過程中的一個問題
建立表時,nvarchar2 型別裡不能有長度單位char,否則會報錯:
結論
1、長度的區別:
char是固定長度,長度不夠的情況下,用空格代替
varchar、varchar2、nvarchar2是可變長度,按照實際的長度儲存
2、儲存單位的區別:
char(byte), char(char),其中位元組是預設單位
varchar(byte), varchar(char),其中位元組是預設單位
varchar2(byte), varchar2(char),其中位元組是預設單位
nvarchar2() 預設儲存單位是char,且括號裡不能有單位
3、其他區別
關於其他的區別,有最大儲存、儲存效率等,這裡不做實驗,推薦兩篇文章作為參考