本文介紹了字符類型的定義及相關語法。
字符類型
名字 | 說明 |
| 有限制的變長。 |
| 定長,空格填充。 |
| 無限變長。 |
CLOB | 大型可變長度字符串,最大為1 GB。 |
LONG | 可變長度字符串,長度無限制。 |
NVARCHAR(n) | 可變長度的字符串,長度有限制。 |
NVARCHAR2(n) | 可變長度的字符串,長度有限制。 |
STRING | VARCHAR2的別名。 |
VARCHAR2(n) | 可變長度字符串,長度有限制。 |
SQL 定義了兩種基本的字符類型: character varying(``n``)
和character(``n``)
, 其中n
是一個正整數。兩種類型都可以存儲最多n
個字符長的串。試圖存儲更長的串到這些類型的列里會產生一個錯誤, 除非超出長度的字符都是空白,這種情況下該串將被截斷為最大長度(這個看上去有點怪異的例外是 SQL 標準要求的)。 如果要存儲的串比聲明的長度短,類型為character
的值將會用空白填滿;而類型為character varying
的值將只是存儲短些的串。
如果我們明確地把一個值造型成character varying(``n``)
或者character(``n``)
, 那么超長的值將被截斷成n
個字符,而不會拋出錯誤(這也是 SQL 標準的要求)。
varchar(``n``)
和char(``n``)
的概念分別是character varying(``n``)
和character(``n``)
的別名。沒有長度聲明詞的character
等效于character(1)
。如果不帶長度說明詞使用character varying
,那么該類型接受任何長度的串。后者是一個本數據庫的擴展。
另外,本數據庫提供text
類型,它可以存儲任何長度的串。盡管類型text
不是 SQL 標準,但是許多其它 SQL 數據庫系統也有它。
類型character
的值物理上都用空白填充到指定的長度n
, 并且以這種方式存儲和顯示。不過,拖尾的空白被當作是沒有意義的,并且在比較兩個 character
類型值時不會考慮它們。在空白有意義的排序規則中,這種行為可能會產生意料之外的結果,例如SELECT 'a '::CHAR(2) collate "C" < E'a\n'::CHAR(2)
會返回真(即便C
區域會認為一個空格比新行更大)。當把一個character
值轉換成其他字符串類型之一時,拖尾的空白會被移除。請注意,在character varying
和text
值里, 結尾的空白語意上是有含義的,并且在使用模式匹配(如LIKE
和正則表達式)時也會被考慮。
這些類型的存儲需求是 4 字節加上實際的字串,如果是 character 的話再加上填充的字節。長的字串將會自動被系統壓縮, 因此在磁盤上的物理需求可能會更少些。長的數值也會存儲在后臺表里面,這樣它們就不會干擾對短字段值的快速訪問。 不管怎樣,允許存儲的最長字串大概是 1 GB。 (允許在數據類型聲明中出現的 n 的最大值比這還小。 修改這個行為沒有甚么意義,因為在多字節編碼下字符和字節的數目可能差別很大。 如果你想存儲沒有特定上限的長字串,那么使用 text 或者沒有長度聲明詞的 character varying, 而不要選擇一個任意長度限制。) 一個短串(最長 126 字節)的存儲要求是 1 個字節外加實際的串,該串在character
情況下包含填充的空白。長一些的串在前面需要 4 個字節而不是 1 個字節。長串會被系統自動壓縮,這樣在磁盤上的物理需求可能會更少。非常長的值也會被存儲在背景表中,這樣它們不會干擾對較短的列值的快速訪問。在任何情況下,能被存儲的最長的字符串是 1GB(數據類型定義中n
能允許的最大值比這個值要小。修改它沒有用處,因為對于多字節字符編碼來說,字符的數量和字節數可能完全不同。如果你想要存儲沒有指定上限的長串,使用text
或沒有長度聲明的character varying
,而不是給出一個任意長度限制)。
這三種類型之間沒有性能差別,只不過是在使用填充空白的類型的時候需要更多存儲尺寸,以及在存儲到一個有長度約束的列時需要少量額外 CPU 周期來檢查長度。雖然在某些其它的數據庫系統里,character(``n``)
有一定的性能優勢,但在本數據庫里沒有。事實上,character(``n``)
通常是這三種類型之中最慢的一個,因為它需要額外的存儲開銷。在大多數情況下,應該使用text
或者character varying
。
使用字符類型
CREATE TABLE test1 (a character(4));
INSERT INTO test1 VALUES ('ok');
SELECT a, char_length(a) FROM test1; -- (1)
a | char_length
------+-------------
ok | 2
CREATE TABLE test2 (b varchar(5));
INSERT INTO test2 VALUES ('ok');
INSERT INTO test2 VALUES ('good ');
INSERT INTO test2 VALUES ('too long');
ERROR: value too long for type character varying(5)
INSERT INTO test2 VALUES ('too long'::varchar(5)); -- explicit truncation
SELECT b, char_length(b) FROM test2;
b | char_length
-------+-------------
ok | 2
good | 5
too l | 5
在本數據庫里另外還有兩種定長字符類型。 name
類型只用于在內部系統目錄中存儲標識符并且不是給一般用戶使用的。該類型長度當前定為 64 字節(63 可用字符加結束符)但在C
源代碼應該使用常量 NAMEDATALEN
引用。這個長度是在編譯的時候設置的(因而可以為特殊用途調整),缺省的最大長度在以后的版本可能會改變。類型"char"
(注意引號)和 char(1)
是不一樣的,它只用了一個字節的存儲空間。它在系統內部用于系統目錄當做簡化的枚舉類型用。
特殊字符類型
名字 | 存儲尺寸 | 描述 |
| 1字節 | 單字節內部類型 |
| 64字節 | 用于對象名的內部類型 |