informix Oracle 字元型別比較整理
informix oracle字元資料型別
在informix中有如下幾種對字串操作的型別:
char(character),varchar,nchar,nvarchar,lvarchar,text
在ORACLE中有如下幾種對字串操作的型別:
char(character),varchar(varchar2),nchar,nvarchar2,long,long raw及LOB型別
一、基本概念:
1、字元儲存單位:
一般一個漢字是兩個位元組,一個字母或標點符號為一個位元組。
8個位為一個位元組,一個字母或標點符號為8個位,一個漢字是16個位。
儲存字母字元的長度。
2、char:定長的字串型別。當存放的資料沒有達到設定的最大限度時,會以空格補齊。
informix:
當存放的資料超過了設定的最大限度時,會自動截斷,不會報錯。
create table char_len (a char(3),b char(4));
insert into char_len(a,b) values('1234','123');
select * from char_len;
#a b
#
#123 123
insert into char_len(a,b) values('億陽','億陽');
select * from char_len;
#a b
#
#123 123
#億?[C億陽
oracle:
當存放的資料超過了設定的最大限度時,會報錯。
create table char_len (a char(3),b char(4));
insert into char_len(a,b) values('1234','123');
#ERROR at line 1:
#ORA-12899: value too large for column "NIOSDB"."CHAR_LEN"."A" (actual: 4,
#maximum: 3)
insert into char_len(a,b) values('123','123');
#A B
#--- ----
#123 123
3、varchar:描述變長字串。
informix:
當存放的資料超過了設定的最大限度時,會自動截斷,不會報錯。
oracle:
當存放的資料超過了設定的最大限度時,會報錯。
二、INFORMIX ORACLES資料型別長度比較
informix Oracle
範圍 預設長度 作為資料儲存 變數
char 1~32767 1 1~2000 1~32767
varchar 1~255 1 1~4000 1~32767
nchar 1~32767 1 1~2000 1~32767
nvarchar/nvarchar2 1~255 1 1~4000 1~32767
lvarchar/long 1~32739 2048 1~2GB 1~32760
text/CLOB 1~2千兆位元組 1~4GB 1~32760
三、字元比較:
1、char和varchar
區別:
CHAR的長度是固定的,而VARCHAR的長度是可以變化的, 比如,儲存字串“abc",對於CHAR (20),表示你儲存的
字元將佔20個位元組(包括17個空字元),而同樣的VARCHAR2 (20)則只佔用3個位元組的長度,20只是最大值,當你儲存
的字元小於20時,按實際長度儲存。
CHAR的效率比VARCHAR2的效率稍高。
何時該用CHAR,何時該用varchar2:
VARCHAR2比CHAR節省空間,在效率上比CHAR會稍微差一些,即要想獲得效率,就必須犧牲一定的空間,這也就是我們在
資料庫設計上常說的‘以空間換效率’。
char是用空間換時間,而varchar2是用時間換空間,char型別雖然一定會填滿設定的空間,但由於長度和順序規則所以
速度會比較快,varchar2則是以降低速度為代價節省空間。
VARCHAR2雖然比CHAR節省空間,但是如果一個VARCHAR2列經常被修改,而且每次被修改的資料的長度不同,這會引起‘行
遷移’(Row Migration)現象,降低資料庫的速度,而這造成多餘的I/O,是資料庫設計和調整中要盡力避免的,在這種情
況下用CHAR代替VARCHAR會更好一些。
2、char和nchar,varchar和nvarchar
NCHAR、NVARCHAR2,國家字符集,與環境變數NLS指定的語言集密切相關,使用方法和CHAR、VARCHAR相同。
CHAR如果存放字母數字佔1個位元組,存放GBK編碼的漢字存放2個位元組,存放UTF-8編碼的漢字佔用3個位元組;
NCHAR根據所選字符集來定義存放字元的佔用位元組數,一般都為2個位元組存放一個字元(不管字元或者漢字)。
例如:char中一個簡單字元(如:a)佔一個位元組,存放GBK編碼的漢字存放2個位元組,存放UTF-8編
碼的漢字佔用3個位元組,而nchar中根據所選字符集來定義存放字元的佔用位元組數,一般都為2個位元組存放一
個字元(無論是簡單字元或是漢字),後者專門針對如:中文,韓文這樣的字元。
oracle裡字元型別比較:
1、VARCHAR VARCHAR2比較
Oracle裡目前VARCHAR是VARCHAR2的同義詞。工業標準的VARCHAR型別可以儲存空字串,但是oracle不這樣做,儘管它保留以後
這樣做的權利。Oracle自己開發了一個數據型別VARCHAR2,這個型別不是一個標準的VARCHAR,它將在資料庫中varchar列可以存
儲空字串的特性改為儲存NULL值。如果你想有向後相容的能力,Oracle建議使用VARCHAR2而不是VARCHAR。
2、char(20),varchar(20),varchar2(20),nchar(20),nvarchar2(20)測試。
首先,提供一個測量資料長度的函式DUMP(),此函式的輸出格式如下:
型別 <[長度]>,符號/指數位 [數字1,數字2,數字3,......,數字20]
型別程式碼是oracle中對每種型別定義的ID名,型別程式碼可以在oracle文件中找到,圖"oracle常用資料型別程式碼"
中列出了幾種常見的型別程式碼。冒號後面的部分叫"符號/指數位"。
我們借用此函式來確定上述幾種字串型別的長度和區別,另外大物件操作的資料型別(比如:long)無法使用DUMP()函式。
1、建立張測試表名為typetest,在其中設定5種類型的資料分別為,
char(20),varchar(20),varchar2(20),nchar(20),nvarchar2(20).
2、在5個欄位中都插入字元'a'
3、用DUMP函式查詢出結果
create table typetest(
cha char(20),
var1 varchar(20),
var2 varchar2(20),
ncha nchar(20),
nvar nvarchar2(20)
);
insert into typetest values('a','a','a','a','a');
select
dump(cha) "char(20)",
dump(var1) "varchar(20)",
dump(var2) "varchar2(20)",
dump(ncha) "nchar(20)",
dump(nvar) "nvarchar(20)"
from typetest;
結果顯示char和nchar的型別程式碼為96,其他3個程式碼為1,
char(20):
Typ=96 Len=20: 97,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32
char的長度為20,說明'a'佔住第一個位元組,省下19個位元組則用空格補齊。
nchar(20):
Typ=96 Len=40: 0,97,0,32,0,32,0,32,0,32,0,32,0,32,0,32,0,32,0,32,0,32,0,32,0,32,0,32,0,32,0,32,0,32,0,32,0,32,0,32
nchar也是用空格補齊剩下的位元組,之所以長度是40,是因為在建表的時候nchar(20)括號中的20是指20個字元,在nchar非特殊情況
下每個字元都佔了2位元組,所以上限為40位元組。
varchar(20):
Typ=1 Len=1: 97
varchar2(20):
Typ=1 Len=1: 97
varchar與varchar2的結果完全一樣,說明2種類型現在還沒有什麼區別,並且長度為1,說明只有'a'所佔的一個位元組的空間。
nvarchar(20):
Typ=1 Len=2: 0,97
nvarchar2則同varchar2一樣為可變長,並且由於也是一個字元佔2位元組,所以a所佔的長度為'2'
四、oracle裡的資料型別:
1、char,character,varchar,varchar2,nchar,nvarchar2的共同特點:
當插入空字串時,則都會被轉變為null
1、long:
LONG 資料型別是一個遺留下來的而且在將來不會被支援的資料型別。它將被LOB(Large Object)資料型別所代替。特點如下:
1、LONG 資料型別中儲存的是可變長字串,最大長度限制是2GB。
2、對於超出一定長度的文字,基本只能用LONG型別來儲存,資料字典中很多物件的定義就是用LONG來儲存的。
3、LONG型別主要用於不需要作字串搜尋的長串資料,如果要進行字元搜尋就要用varchar2型別。
4、很多工具,包括SQL*Plus,處理LONG 資料型別都是很困難的。
5、LONG 資料型別的使用中,要受限於磁碟的大小。
能夠操作 LONG 的 SQL 語句:
1、Select語句
2、Update語句中的SET語句
3、Insert語句中的VALUES語句
限制:
1、一個表中只能包含一個 LONG 型別的列。
2、不能索引LONG型別列。
3、不能將含有LONG型別列的表作聚簇。
4、不能在SQL*Plus中將LONG型別列的數值插入到另一個表格中,如insert into ...select。
5、不能在SQL*Plus中通過查詢其他表的方式來建立LONG型別列,如create table as select。
6、不能對LONG型別列加約束條件(NULL、NOT NULL、DEFAULT除外),如:關鍵字列(PRIMARY KEY)不能是 LONG 資料型別。
7、LONG型別列不能用在Select的以下子句中:where、group by、order by,以及帶有distinct的select語句中。
8、LONG型別列不能用於分佈查詢。
3、long raw 無可變長二進位制資料,最大長度是2GB。Oracle用這種格式來儲存較大的圖形檔案或帶格式的文字檔案,如Miceosoft
Word文件,以及音訊、視訊等非文字檔案。在同一張表中不能同時有long型別和long raw型別,long raw也是一種較老的資料型別,
LOB資料型別即能儲存結構化資料外,也能儲存非結構化資料,最大長度為4GB,比long和long raw更加靈活,
Oracle公司建議,對大物件的操作儘量使用LOB,將來會逐漸被BLOB、CLOB、NCLOB等大的物件資料型別所取代。
2、LOB:Large Object的簡寫,
是專門用於處理大物件的資料型別,一個表中可以有多個LOB欄位,每個欄位可以儲存達4GB的資料,LOB主要分為以下兩類
1、BLOB(Binary Large Object):適合於存放程式、圖片、影音等非結構化檔案。
2、CLOB(Character Large Object):適用於儲存文字型資料,例如文章、新聞、記錄、日誌等。
五、informix裡的字元:
1、lvarchar在9.4版本之後才可以用帶指定長度的方式,如lvarchar(3000),不帶長度則預設是2048位元組,最大長度是32,739位元組。
所以對於9.4之前的版本,不能用帶長度的表示式,資料庫會報語法錯誤。
預設情況下,資料庫伺服器把加引號的字串,認為lvarchar型別。
2、text與oracle中的long型別一樣,用來應對超長字串的型別,最大長度為2GB
可以儲存、檢索、更新、刪除text列中的值,但是不能在算術或字串中使用text運算元,也不能使用update語句的set自居將
文字指定給text,不可以用以下任何方法使用text值:
聚集函式、in子句、matches或like子句,group by組合一、order by子句。
不能使用帶引號的文字字串、數字或其它實際值來插入或更新TEXT列。
僅當正在使用is null或is not null運算子測試null時,可以在布林表示式中使用test運算元,可以用下列方式將資料插入到text:
dbload,onload實用程式,load(dbaccess),ESQL從TEXT主變數
六、oracle和informix表的限制
1、在informix的一個表中對以上字串型別定義的總長度不能超過32767(不包括對大欄位處理的text型別)
但是遇到varchar與nvarchar會再減1(為該列設定索引會留一位),而遇到lvarchar則需要減3。
create table test (a char(32767))---success
create table test (a char(32766),b varchar(1))---error
create table test (a char(32765),b varchar(1))---success
create table test (a char(32764),b lvarchar(1))---error
create table test (a char(32763),b lvarchar(1))---success
每個表的最大列數 32767
每個索引的最大列數 16
鍵值的最大長度是 390 位元組。構成鍵的 VARCHAR 列的組合大小必須小於 390 減去每個 VARCHAR 列的額外位元組。
例如:資料庫伺服器構建用於以下語句的索引鍵長度等於 390 或 ((255+1) + (133+1))
2、oracle限制的每個表的列的總數不能超過1000(此處沒有測試),然後每個列的長度由其資料型別決定。
每個索引的最大列數 32
鍵值的最大長度 749
七、行遷移與行連結
當一行的資料過長而不能插入一個單個數據塊中時,可能發生兩種事情:行連結(row chaining)或行遷移(row migration)。
1、行連結:
當第一次插入行時,由於行太長而不能容納在一個數據塊中時,就會發生行連結。在這種情況下,oracle會使用與該塊連結
的一塊或多塊資料塊來容納該行的資料。行連線經常在插入比較大的行時才會發生,如包含long, long row, lob等型別的
資料。在這些情況下行連結是不可避免的。
2、行遷移
當修改不是行連結的行時,當修改後的行長度大於修改前的行長度,並且該資料塊中的空閒空間已經比較小而不能完全容納
該行的資料時,就會發生行遷移。在這種情況下,Oracle會將整行的資料遷移到一個新的資料塊上,而將該行原先的空間只
放一個指標,指向該行的新的位置,並且該行原先空間的剩餘空間不再被資料庫使用,這些剩餘的空間我們將其稱之為空洞,
這就是產生表碎片的主要原因,表碎片基本上也是不可避免的,但是我們可以將其降到一個我們可以接受的程度。
注意,即使發生了行遷移,發生了行遷移的行的rowid 還是不會變化,這也是行遷移會引起資料庫I/O效能降低的原因。其實行遷
移是行連結的一種特殊形式,但是它的起因與行為跟行連結有很大不同,所以一般把它從行連結中獨立出來,單獨進行處理。
八、ORACLE-在設計資料庫時如何選擇正確的資料型別
1、Char
定長格式字串,在資料庫中儲存時不足位數填補空格,不建議使用,會帶來不必要的麻煩
a、字串比較的時候,如果不注意(char不足位補空格)會帶來錯誤
b、字串比較的時候,如果用trim函式,這樣該欄位上的索引就失效(有時候會帶來嚴重效能問題)
c、浪費儲存空間
2、Varchar2/Varchar
不定長格式字串,對於4000位元組以內的字串,建議都用該型別
a、網上有說char比varchar2效能好,但是如果你有興趣做測試的話,會發現沒有區別(如果發生行遷移,可以通過pctfree來調整)
b、充分利用儲存空間
3、Long/long raw
Oracle已經廢棄,只是為了向下相容保留著,應該全部升級到lob
Long型別有很多限制
a、表中只能有一列long型別
b、Long型別不支援分散式事務
c、太多的查詢不能在long上使用了
informix字串函式:
1、lower,將字串中每個大寫字母轉換為小寫字母
SELECT manu_code, LOWER(manu_code)
FROM items
WHERE order_num = 1018
manu_code (expression)
PRC prc
KAR kar
PRC prc
SMT smt
HRO hro
2、upper,將字串中每個小寫字母轉換為大寫字母
select a,upper(a) from test;
a (expression)
aBcDe ABCDE
aBcDe ABCDE
3、initcap,將字串中每個詞的首寫字母轉換成大寫
select a,initcap(a) from test;
a (expression)
3bcde 3Bcde
3bcde dbv adf 45df 3Bcde Dbv Adf 45Df
4、replace,將字串中的某一組字元轉換成其他字元,例replace(col,”each”,”eve”)
select a,replace(a,'3b','4b') from test;
a (expression)
3bcde 4bcde
3bcde dbv adf 45df 4bcde dbv adf 45df
5 substr,substring
返回字串中的某一部分,指定開始位置和長度,例substr(col,1,2) substring(col,from 1to 4)
還有一種寫法是將欄位名後面加上方括號,裡面是起始到結束的位置,例:col[1,2]
select a,
substr(a,2,3) as substr ,
a[2,3] as a2 ,
substring(a from 2 for 3) as substring
from test;
a substr a2 substring
3bcde bcd bc bcd
3bcde dbv adf 45df bcd bc bcd
注意:substr,substring如果沒有長度,預設到最後一個字元:
欄位名後面加上方括號,如果沒有結束位置,就認為只取起始位置的字元
select a,
substr(a,2) as substr ,
a[2] as a2 ,
substring(a from 2) as substring
from test;
a substr a2 substring
3bcde bcde b bcde
3bcde dbv adf 45df bcde dbv adf 45df b bcde dbv adf 45df
注意:substr,substring的起始位置為負值,表示從字串末尾向後數,
substring的起始位置為負值,表示從字串開始位置向後幾位。
欄位名後面加上方括號,裡的起始、結束位置都不能用負值
select a,
substr(a,-2,5 ) as substr ,
substring(a from -2 for 5) as substring
from test;
a substr substring
3bcde de 3b
3bcde dbv adf 45df df 3b
6、lpad,使用lpad函式已用重複次數達到必要次數的字元序列在左邊填充或截斷的字串的副本,這取決於字串中填充
部分的指定長度。
select a,lpad(a,21,'_')
from test;
a lpad(a,21,'_')
3bcde ________________3bcde
3bcde dbv adf 45df ___3bcde dbv adf 45df
7、Rpad,使用rpad函式已用重複次數達到必要次數的字元序列在右邊填充或截斷的字串的副本,這取決於字串中填充部
分的指定長度。
select a,rpad(a,21,'_')
from test;
a rpad(a,21,'_')
3bcde 3bcde________________
3bcde dbv adf 45df 3bcde dbv adf 45df___
8、LENGTH
select a,length(a)
from test;
a length(a)
3bcde 5
3bcde dbv adf 45df 18
oracle字串函式:
1.ASCII
返回與指定的字元對應的十進位制數;
SQL> select ascii(’A’) A,ascii(’a’) a,ascii(’0’) zero,ascii(’ ’) space from dual;
A A ZERO SPACE
--------- --------- --------- ---------
65 97 48 32
2.CHR
給出整數,返回對應的字元;
SQL> select chr(54740) zhao,chr(65) chr65 from dual;
ZH C
-- -
趙 A
3.CONCAT
連線兩個字串;
SQL> select concat(’010-’,’88888888’)||’轉23’ 高乾競電話 from dual;
高乾競電話
----------------
010-88888888轉23
4.INITCAP
返回字串並將字串的第一個字母變為大寫;
SQL> select initcap(’smith’) upp from dual;
UPP
-----
Smith
5.INSTR(C1,C2,I,J)
在一個字串中搜索指定的字元,返回發現指定的字元的位置;
C1 被搜尋的字串
C2 希望搜尋的字串
I 搜尋的開始位置,預設為1
J 出現的次數,預設為1
SQL> select instr(’oracle traning’,’ra’,1,2) instring from dual;
INSTRING
---------
9
6.LENGTH
返回字串的長度;
SQL> select name,length(name),addr,length(addr),sal,length(to_char(sal)) from gao.nchar_tst;
NAME LENGTH(NAME) ADDR LENGTH(ADDR) SAL LENGTH(TO_CHAR(SAL))
------ ------------ ---------------- ------------ --------- --------------------
高乾競 3 北京市海錠區 6 9999.99 7
7.LOWER
返回字串,並將所有的字元小寫
SQL> select lower(’AaBbCcDd’)AaBbCcDd from dual;
AABBCCDD
--------
aabbccdd
8.UPPER
返回字串,並將所有的字元大寫
SQL> select upper(’AaBbCcDd’) upper from dual;
UPPER
--------
AABBCCDD
9.RPAD和LPAD(貼上字元)
RPAD 在列的右邊貼上字元
LPAD 在列的左邊貼上字元
SQL> select lpad(rpad(’gao’,10,’*’),17,’*’)from dual;
LPAD(RPAD(’GAO’,1
-----------------
*******gao*******
不夠字元則用*來填滿
10.LTRIM和RTRIM
LTRIM 刪除左邊出現的字串
RTRIM 刪除右邊出現的字串
SQL> select ltrim(rtrim(’ gao qian jing ’,’ ’),’ ’) from dual;
LTRIM(RTRIM(’
-------------
gao qian jing
11.SUBSTR(string,start,count)
取子字串,從start開始,取count個
SQL> select substr(’13088888888’,3,8) from dual;
SUBSTR(’
--------
08888888
12.REPLACE(’string’,’s1’,’s2’)
string 希望被替換的字元或變數
s1 被替換的字串
s2 要替換的字串
SQL> select replace(’he love you’,’he’,’i’) from dual;
REPLACE(’H
----------
i love you
13.SOUNDEX
返回一個與給定的字串讀音相同的字串
SQL> create table table1(xm varchar(8));
SQL> insert into table1 values(’weather’);
SQL> insert into table1 values(’wether’);
SQL> insert into table1 values(’gao’);
SQL> select xm from table1 where soundex(xm)=soundex(’weather’);
XM
--------
weather
wether
14.TRIM(’s’ from ’string’)
LEADING 剪掉前面的字元
TRAILING 剪掉後面的字元
如果不指定,預設為去掉空格符