1. 程式人生 > >Oracle學習筆記 字符集概述

Oracle學習筆記 字符集概述

Oracle 學習筆記 字符集概述

這節課開始講oracle裡面的字符集
偏重於原理和簡單的一些判斷以及實現

字符集它涉及到很多的東西
比如建庫和作業系統環境

這節課把字符集的原理性的東西以及常見的操作講一下
大家以後不要在字符集方面犯一些錯誤
以後字符集的問題基本都可以解決了

一)字符集的發展

通過查詢各方面資料
這裡把字符集的發展自己先簡單梳理了一下

字符集是編號和字元的對應表
是為了讓計算機使用和顯示出來人們使用的語言和符號
這個編號就是編碼表中的編碼
而字元的表現都是字模的形式
一個編碼對應著一個圖形型別的字模
人們向計算機輸入字元,計算機通過編碼表把它轉變為編碼
這些編碼在計算機內部處理或運算
而需要檢視處理過程和結果的時候
因為有了這種編碼就可以從這些編碼表中找到對應的字模
並有系統繪製或顯示出來

計算機控制運算和傳輸只能使用二進位制的1和0
要輸入和顯示出的文字和符號都要有一個轉變為0、1和由0、1轉變來的過程
這樣就需要用二進位制來標定它們
計算機需要使用編碼表來完成這個工作

在地球上
計算機使用最早的字符集是
BCD(binary coded decimal)編碼表
只有十個資料
用二進位制表示從0到9十個數字
只要四位二進位制就夠了

這些對計算機是不夠的
因為計算機還要使用字母和控制符

而恰好計算機最早出現在使用英語的美國

所以IBM公司(國際商用機器公司)制定了EBCDIC編碼
EBCDIC碼(Extended Binary Coded Decimal Interchange Code)
廣義二進位制編碼的十進位制交換碼
對BCD碼擴充套件
使用八位二進位制表示256個包括數字、英文字元、控制符和其它一些常用字元

這時美國國家標準局(ANSI)也制定了ASCII碼
即美國標準資訊交換碼(American Standard Code for Information Interchange)
被國際標準化組織( International Organization for Standardization, ISO )批准為國際標準
稱為ISO 646標準

基本的 ASCII 字符集,使用了七位二進位制,共有 128 個字元,
其中有 96 個可列印字元,包括常用的字母、數字、標點符號等,另外還有 32 個控制字元

EBCDIC和ASCII中都主要是英文字母,但在字元的位置和排列順序上不一樣

在計算機技術發展的早期,如ASCII和EBCDIC這樣的字符集逐漸成為標準

數字0到9使用BCD編碼4位的二進位制就可以實現
英文字元、控制符和一些常用的符號用7位二進位制的標準ASCII可以完成

但是世界上的符號包括文字非常的多
各個國家都要使用計算機
就需要更多的二進位制數來和他們對應

首先字母文字國家把這種編碼表擴充到了8位

ISO 陸續制定了一批適用於不同地區的擴充 ASCII 字符集
最低的128個程式碼總是相同的,較高的128個程式碼取決於定義內碼錶的語言

這多餘的128個碼位的不同擴充套件,就形成了一系列ISO-8859-*的標準

代表性的是實現了西歐語言編碼的ISO-8859-1(即Latin-1)
它向下相容ASCII,是一種西歐字符集

像東亞的國家
每個文字都是一個獨立的符號
用8位只256個空間無法表示
所以位數被進一步擴充套件
使用了16位二進位制為自己的國家制定了編碼表
用於顯示本國的語言
不同的國家和地區制定了不同的標準,
由此產生了 GB2312, BIG5, JIS 等各自的編碼標準
它們使用2個位元組來代表一個字元

每個字元使用一個位元組編碼,這樣的字符集就是單位元組字符集SBCS(Single-byte Character Sets)
每個字元最多使用兩個位元組編碼,這樣的字符集就是雙位元組字符集DBCS(Double-byte Character Sets)
某些字元的編碼超過了一個位元組,這樣的字符集就是多位元組字符集MBCS(Multi-byte Character Sets)

在中國,中國國家標準委員會開始了設計工作
保留ASCII的127號以前的編碼並把編碼擴充套件到兩個位元組
方案中可以組合出大約7000多箇中文字元,這就是國標(國家標準GB)2312
是中國國家標準簡體中文字符集,全稱《資訊交換用漢字編碼字符集·基本集》,又稱GB0

GB2312 是對 ASCII 的中文擴充套件
由於GB2312只收錄6763個漢字,於是微軟利用GB 2312未使用的編碼空間,制定了GBK編碼
GBK即漢字內碼擴充套件規範
K為漢語拼音 Kuo Zhan(擴充套件)中“擴”字的聲母
英文全稱Chinese Internal Code Specification
也使用了雙位元組編碼方案。

在香港出現了Big5,又稱大五碼
是繁體中文(正體中文)最常用字符集標準,共收錄13060個漢字

這些出現的由ASCII擴充套件而來,用於單種語言的編碼表又被微軟使用為ANSI編碼
在簡體中文系統下,ANSI 編碼代表 GB2312 編碼,
在日文作業系統下,ANSI 編碼代表 JIS 編碼
它們既相容ASCII又互相不相容

這時世界已形成出了多種的字元編碼體系
包括分別以ASCII和EBCDIC為基礎並且由它們擴充套件而來的編碼體系
還有SAP(systems applications and products in data processing)體系等
SAP在德國,是全球企業管理軟體與解決方案的技術領袖,同時也是市場領導者
SAP既是公司名稱,又是其產品企業管理解決方案的軟體名稱

每種編碼體系都有各種文字的很多的編碼表
但是各自的編碼不同,適用於不同的環境
EBCDIC編碼體系主要由IBM生產的機器使用,
如IBM的大型機S/390、zSeries及其上的作業系統IBMOS/390、z/OS
和IBM的中小型機AS/400、IBM i系列及其上的作業系統OS/400、i5/OS
IBM的個人計算機和工作站作業系統使用的是文字的工業標準編碼ASCII碼
如:AIX(Advanced Interactive eXecutive)IBM開發的一套UNIX作業系統
它的平臺的字元編碼是基於 ASCII 的

一般地說,開放的作業系統(LINUX 、WINDOWS等)採用ASCII 編碼,
而大型主機系統(MVS 、OS/390)等採用EBCDIC 編碼。
絕大多數所熟悉的系統都是使用ASCII

在每個體系中還存在一個問題
各個語言的編碼表自己獨立使用是可以的
如果放在一起使用會發生同一編碼對應不同文字的衝突問題

為了解決這個問題
一個軟體製造商的協會unicode組織和國際標準化組織(ISO)
都進行了把世界上所有的字元放在一起進行統一編碼的工作
ISO開發了ISO 10646專案,Unicode協會開發了Unicode專案

Unicode是國際組織制定的可以容納世界上所有文字和符號的字元編碼方案
而Unicode只與ASCII相容(更準確地說,是與ISO-8859-1相容)

“ Universal Multiple-Octet Coded Character Set”,簡稱UCS
是由ISO制定的ISO 10646(或稱ISO/IEC 10646)標準所定義的標準字符集

當雙方認識到世界不需要兩個不相容的字符集
它們開始合併雙方的工作成果,併為創立一個單一編碼表而協同工作

從Unicode 2.0開始,Unicode採用了與ISO 10646-1相同的字型檔和字碼
ISO也承諾使兩方保持一致
目前兩個專案仍都存在,並獨立地公佈各自的標準。

UCS編碼有自己的格式:UCS-2和UCS-4等等
在編碼層面上
UCS-2就是用兩個位元組編碼
UCS-4就是用4個位元組(實際上只用了31位,最高位必須為0)編碼。

unicode在編碼上和UCS保持一致,在實現上有自己的規則,而UCS只定義了編碼標準。

unicode的實現形式上有UTF-8,UTF-16,UTF-32,還有UTF-7等。
UTF是“UCS Transformation Format”的縮寫
都是將數字轉換到程式資料的編碼方案。

UTF-16是UCS-2的擴充套件,UTF-32是UCS-4的子集。

一般對於UNICODE來說,UCS-2是內碼,而UTF-8等則是它的實現方式

中國為了和ISO 10646編碼接軌制定了國家標準GB13000
等同於國際標準的《通用多八位編碼字符集 (UCS)》 ISO10646.1
就是等同於Unicode的標準,內碼表等等的都使用UTF的一套標準
一共使用四個位元組
目前所有字元程式碼的前兩個位元組都是0
因此預設情況下按照兩位元組處理

而GBK並非國家正式標準
僅是GB 2312到GB 13000.1-93之間的過渡方案

但GB13000標準目前發展緩慢

GB 18030全稱:國家標準GB 18030-2005《資訊科技中文編碼字符集》
是中華人民共和國現時最新的內碼字集
GB 18030與GB 2312-1980完全相容,與GBK基本相容,支援GB 13000及Unicode的全部統一漢字,
共收錄漢字70244個
與 UTF-8 相同,採用多位元組編碼,每個字可以由1個、2個或4個位元組組成

GB18030是我國繼GB2312-1980和GB13000-1993之後最重要的漢字編碼標準,
是未來我國計算機系統必須遵循的基礎性標準之一

在windows中這些編碼表被稱為內碼表,也稱為“內碼錶”

早期,內碼表是IBM稱呼計算機的BIOS所支援的字符集編碼
作業系統直接使用BIOS提供的字元繪製功能來顯示字元(或者是一組嵌入在顯示卡字元生成器中的字形)
作業系統的編碼支援也就依靠BIOS的編碼
這時的內碼表被整合在硬體中,由製造商選擇整合哪種內碼表,稱作OEM(原始裝置製造商)內碼表
最具代表性的是”IBM PC或MS-DOS 內碼表437”。

隨著圖形使用者介面作業系統的廣泛使用,作業系統本身具有了字元繪製的功能
Windows內碼表最初是根據ANSI草案實現的
微軟在Windows作業系統沒有轉向UTF-16作為內碼實現之前(也就是在Windows 2000之前),
針對不同的使用地區與國家,定義了一系列的支援不同語言字符集的內碼表,
被稱作”Windows(或ANSI)內碼表”。
這是Windows內碼表被稱作ANSI的緣由。
ANSI由ASCII標準編碼擴充套件而來,它們既相容ASCII又互相不相容

ANSI code pages實際上是一系列的編碼集合,
是微軟自己定義的內碼表
根據作業系統區域設定而啟用其中一種作為ANSI編碼由系統預設使用。
在儲存檔案時編碼選擇ANSI就是選擇這個預設的編碼。
公司電腦(英文系統)上的ANSI code page可能是1252,而家裡的中文系統則可能是936
在簡體中文作業系統中ANSI編碼預設指的是GB系列編碼(GB2312、GBK);
在繁體中文作業系統中ANSI編碼預設指的是BIG5;
在日文作業系統中ANSI編碼預設指的是Shift JIS

ANSI編碼是在Windows中特別是在windows安裝過程中可以指定為預設內碼表
為了使windows系統本地化而選擇的一種本地語言編碼表
由於世界上有很多的語種,
每種語言的ANSI編碼指的都是這種語言對應的編碼表,國家不同內碼表也不同
在windows中同時只能選擇一種內碼表作為ANSI編碼使用

ANSI內碼表的特點:
編碼0至127符合ANSI制定的ASCII編碼標準
是由微軟制定並實現的
編碼最多兩個位元組

ANSI使用最明顯的例子:
widows中儲存文字檔案一般
裡面有四個選項:ANSI,Unicode,Unicode big endian 和 UTF-8

(1)ANSI是預設的編碼方式。
對於英文檔案是ASCII編碼,對於簡體中文檔案是GB2312編碼
(只針對Windows簡體中文版,如果是繁體中文版會採用Big5碼)。
(2)Unicode編碼指的是UCS-2編碼方式,即直接用兩個位元組存入字元的Unicode碼。
這個選項用的little endian格式。
(3)Unicode big endian編碼與上一個選項相對應。
(4)UTF-8編碼
它們就是windows系統正在使用的字符集
第一個選項就是使用的系統預設的ANSI內碼表

在windows中的內碼表是微軟系統使用的當然要由微軟指定
對於ANSI編碼微軟往往都是先得到相應國家自己制定的標準
然後微軟對其進行修改或擴充得到自己的內碼表

如繁體中文的BIG5編碼,日本的Shift JIS編碼,西歐iso-8859-1
微軟以原編碼為基礎
對其修改擴充後分別得到的內碼表編號為950,932,1252

簡體中文GBK碼
是微軟在GB2312-80標準基礎上的內碼擴充套件規範,使用了雙位元組編碼方案
完全相容GB2312-80標準,支援國際標準ISO/IEC10646-1和國家標準GB13000-1中的全部中日韓漢字,
幷包含了BIG5編碼中的所有漢字
GBK對應內碼表936

Windows平臺上的GUI程式使用ANSI內碼表,
而控制檯程式Windows 中的字元模式的應用程式(使用命令提示符視窗的應用程式)
使用過去在 DOS 中使用的內碼表。
由於歷史原因,這些內碼表稱為 OEM(原始裝置製造商)內碼表
這兩種內碼表在前128個字元的編碼是一樣的,
但後128個字元的編碼可能不一致。
而現在圖形系統中提供的OEM內碼表只是為了和早期使用OEM內碼表的程式相容

字元要在系統中繪製
還需要字元編碼表對應的字模庫,也稱字形庫
計算機最早使用的是點陣字型字模,
到現在有了很多的向量字型字模,又稱輪廓字型、描邊字型,
TrueType字型與PostScript字型、OpenType字型是主要的三種

點陣字型也叫點陣圖字型,其中每個字形都以一組二維畫素資訊表示
向量字型檔儲存的是對每一個字的描述資訊
比較而言點陣字型優點是顯示速度快,最大的缺點是不能放大
現在點陣字型仍在被廣泛的使用

Windows使用的字型檔也為以上兩類,
在FONTS目錄下,如果字型副檔名為FON,表示該檔案為點陣字型檔,副檔名為TTF則表示向量字型檔

下面簡單的列一下windows中幾個內碼表和字符集的對應關係

分三列,分別表示
內碼表編號、對應編碼名稱、說明
37 IBM037 IBM EBCDIC (US-Canada) 就是最早的EBCDIC編碼表
437 IBM437 OEM United States 美國擴充套件ASCII表,最初的IBM PC內碼表,實現了擴充套件ASCII字符集
20127 us-ascii US-ASCII 就是基礎的7位ASCII編碼

65000 utf-7 Unicode (UTF-7)
65001 utf-8 Unicode (UTF-8)
65005 utf-32LE Unicode (UTF-32)
65006 utf-32BE Unicode (UTF-32 Big-Endian)

1200 UTF-16LE Unicode(UCS-2LE Unicode) (little-endian小端序)
1201 UTF-16BE Unicode(UCS-2BE Unicode) (big-endian大端序)

20936 GB2312 簡體中文(GB2312)
936 GBK 簡體中文(GBK)
54936 GB18030 簡體中文(GB18030)
950 BIG5 繁體中文(大五碼)
932 Shift_JIS 日文(Shift_JIS)
949 EUC-KR 韓文(EUC-KR)

28591 iso-8859-1 西歐字元 (ISO)Latin-1 西尤拉丁字母
28605 iso-8859-15 Latin 9 (ISO) 西歐語言
1252 Windows-1252 西歐字元(Windows)

有個別情況要說明:

Windows 1252和ISO 8859-1基本等同但並不完全一致,
ISO-8859-1在0x80-0x9F範圍的控制字元,在Windows-1252中被可列印字元取代。
由於在web網頁中,ASCII控制字元不起作用,
所以網頁一般用Windows-1252內碼表標記替代ISO-8859-1標記。

iso-8859-15 Latin 9 字符集是iso-8859-1 Latin 1字符集的更新版本,
去掉一些不常用的字元,增加修正了部分字元,增加了歐元字元

每種編碼集在不同的編碼體系中有不同的別名

如iso-8859-1編碼:
ISO-8859-1編碼也是單位元組編碼,最多能夠表示256個字元。
Latin1是ISO-8859-1的別名,有些環境下寫作Latin-1
在OEM(IBM PC)內碼表編號是 850 —“多語言(Latin-1)” (西歐語言)
IBM中叫它Code page 819 or CP819
Oracle中則是WE8ISO8859P1編碼或WE8MSWIN1252編碼
SAP中是SAP Code page 1100
在windows中被使用為28591和1252內碼表

又如UTF-8:
UTF-8在IBM稱作內碼表1208,在微軟稱作內碼表65001,在SAP稱作內碼表4110

在oracle中對編碼的命名有一定的規則
如:

AL32UTF8

【AL】支援所有語言(All Language)。

【32】每字元最多佔用32位(4位元組)。

【UTF8】編碼為UTF-8。

WE8MSWIN1252

【WE】支援西歐語言(Western Europe)。

【8】每字元需要佔用8位(單位元組)。

【MSWIN1252】編碼為CP1252。

US7ASCII

【US】表示美國(United States)。

【7】每字元需要佔用7位。

【ASCII】編碼為ASCII。

其它如ZHS16GBK,ZHT16BIG5,US8PC437(編碼為OEM cp437),都可以類推

二)字符集概念

繼續講課課程

首先看一下
oracle的字符集,什麼叫字符集

字符集說白了是一個集合
是一張表,這個表有兩列

左面這列是字元是所有要儲存的字元

字元有很多字元
比如我們講中文字元
左面這列就是中國人常用的所有的中文字元
有漢字、英文字母有數字還有一些特殊的符號
在左面都出現是我們中文要使用的所有的字元
右邊是一個編碼,從1號2、3、4、5、6
將來提到1的時候就對應著一個字元

所以說字符集就是字元和編碼的這麼一個對應表

我們知道在計算機裡面只能儲存數字
我們不能儲存一個字元,儲存不了字元

但是我們還想在計算機裡面儲存字元
我們就做了一件事情
將字元對應成編碼儲存起來

比如我要存中文
中文裡面的“中國”這兩個字元
我們就找這個字符集
“中”和“國”分別對應著兩個編碼
把兩個編碼儲存到資料庫裡面去
這是儲存的時候

顯示的時候
根據兩個編碼再來查
顯示的是”中”和”國”
把兩個字元顯示出來
這就是我們計算機裡面的字符集的概念

在計算機裡面很多地方都有字符集的概念
我們的oracle資料庫也有字符集的概念

因為oracle要存字元
有字元就需要字符集的概念

三)有字符集的地方

簡單講一下哪些地方有字符集

1)作業系統

第一個作業系統有字符集
比如我們的windows有字符集
linux也有字符集,unix也有字符集
作業系統os本身有字符集

比如我們的linux字符集我們可以看一下
使用locale命令

[oracle@redhat4 ~]$ locale
LANG=zh_CN.UTF-8
LC_CTYPE="zh_CN.UTF-8"
LC_NUMERIC="zh_CN.UTF-8"
LC_TIME="zh_CN.UTF-8"
LC_COLLATE="zh_CN.UTF-8"
LC_MONETARY="zh_CN.UTF-8"
LC_MESSAGES="zh_CN.UTF-8"
LC_PAPER="zh_CN.UTF-8"
LC_NAME="zh_CN.UTF-8"
LC_ADDRESS="zh_CN.UTF-8"
LC_TELEPHONE="zh_CN.UTF-8"
LC_MEASUREMENT="zh_CN.UTF-8"
LC_IDENTIFICATION="zh_CN.UTF-8"
LC_ALL=

這個命令結果中
當前的字符集是UTF-8

還有locale 加上 -a 引數

[[email protected] ~]$ locale -a
aa_DJ
aa_DJ.iso88591
aa_DJ.utf8
aa_ER
aa_ER@saaho
aa_ER.utf8
aa_ER[email protected]
aa_ET
aa_ET.utf8
.
.
.
zh_CN
zh_CN.gb18030
zh_CN.gb2312
zh_CN.gbk
zh_CN.utf8
zh_HK
zh_HK.big5hkscs
zh_HK.utf8
zh_SG
zh_SG.gb2312
zh_SG.gbk
zh_SG.utf8
zh_TW
zh_TW.big5
zh_TW.euctw
zh_TW.utf8
zu_ZA
zu_ZA.iso88591
zu_ZA.utf8

結果內容較多隻列出一部分
可以展示出linux支援的所有的字符集

還支援zh_HK.big5hkscs
大5碼,香港人用的

還支援zh_SG.gbk
我們的國標

還支援zh_TW.utf8
UNICODE類字符集

這裡有它支援的所有字符集

在windows裡面支援的當前的字符集

先開啟 windows 的 命令提示符
有一個chcp命令

C:\WINDOWS>chcp
活動的內碼表: 936

活動內碼表是936
936是中文字符集

這是我們作業系統有字符集

2)oracle資料庫

oracle資料庫本身有字符集
資料庫軟體裡面帶著字符集

它也帶著很多張表
一個表是一種字符集

字符集可以認為是一張表
是一張字元和編碼的對應表

oracle有字符集說明oracle有這張表

oracle支援很多種字符集說明oracle裡面有很多種這張表

作業系統有字符集也有這張表

3)軟體

還有一些軟體跟oracle一樣
本身也帶字符集

有些軟體本身是不帶字符集的
有些軟體有字符集

oracle或者一些別的軟體有字符集
他就自己使用自己的
有些軟體不帶字符集的字符集
他就使用作業系統字符集

要注意這個地方
看看軟體本身有沒有字符集

後面還會通過例子去強調

字符集就是字元和編碼的這麼一張對應表
作業系統和oracle都有字符集的概念

四)什麼時候用字符集

我們訪問一個表
訪問t2這張表

先把t2中的資料都刪了

SQL> delete from t2;

1 row deleted.

SQL> commit;

Commit complete.

先查一下

SQL> select * from t2;

no rows selected

沒有資料

SQL> desc t2;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                                 NUMBER
 NAME                                               VARCHAR2(20)

t2這張表有兩個列
一個是ID列 型別是NUMBER 數字列
NAME列 是VARCHAR2列 VARCHAR是字元

所以說對這個表來講
表t2有兩列
有id列型別是number
name列型別是varchar

對id列來講,因為它是數字列,沒有字元的概念
對這個列來講不用字符集

往這個列中插入資料和刪除資料、顯示資料的時候
它不涉及到字元的概念字符集的概念

但是name列 型別是varchar 或varchar2
因為這個列儲存的是字元

往這個列中插入刪除還有顯示資料的時候
這個列要用到字符集的概念
如果一個數據庫裡面沒有varchar
只有類似於number這樣的這種列
這個資料庫可以沒有字符集的概念

但大家想想沒有可能,不可能
所有的資料庫裡面的表總有varchar
而且還以varchar為主

什麼時候使用字符集呢

(1)當我們用來儲存CHAR, VARCHAR2, CLOB, LONG等型別資料的時候

這四種類型都是放字元的
char是固定長度放字元的
varchar是可變長度放字元的
clob是大物件,比如我們把一片文章存進去
long也是大物件,但它現在像是慢慢被clob取代了

當我們的列是這四種列的時候
往這四種列存資料的時候用到字符集

當然了還有資料字典裡面
(2)用來標示諸如表名、列名以及PL/SQL變數等
(3)用來儲存SQL和PL/SQL程式單元等

資料字典裡面的一些char和varchar,clob和long也要用到資料庫字符集

五)國家字符集

還有一種用到的字符集

我們在oracle安裝的時候
有兩個字符集
一個是資料庫字符集
一個是國家字符集

看一下我們oracle安裝過程的時候
在其中安裝的一步的時候
在調sga、pga裡面
我們還可以看到有字符集的選擇
我們有兩種字符集
第一是資料庫字符集,我們選擇了
第二是國家字符集,我們也選擇了

這兩個字符集含義
是分別應用在不同場合

當我們建立一個表
這個表如果它的列的型別是char varchar clob long
這個時候oracle就使用資料庫字符集

如果我們建了一個表
它的資料型別是 nchar nvarchar2 或nclob
這個時候針對這個表我們就使用國家字符集

現在表t2它的有個列是varchar
我往t2插入資料和顯示資料的時候
它會用到資料庫字符集

再建立一個表t3

SQL> create table t3(id number,name nvarchar2(20));

Table created.

這是建了一個表

SQL> desc t3;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                                 NUMBER
 NAME                                               NVARCHAR2(20)

這個時候針對表t3它的列是nvarchar

對錶t3來講
我要能往裡面儲存資料和顯示資料的時候
用到國家字符集

向t3表中插入資料

SQL> insert into t3 values(1,'中國');

1 row created.

檢視使用的字符集

SQL> select id,name,dump(name,1016) from t3;

        ID NAME   DUMP(NAME,1016)
---------- ------ --------------------------------------------------
         1 中國   Typ=1 Len=4 CharacterSet=AL16UTF16: 4e,2d,56,fd

可以看出CharacterSet=AL16UTF16
這裡說明是使用的國家字符集

一個表中同時存在varchar和nvarchar時
就是即使用資料庫字符集又使用國家字符集時
國家字符集的設定只對nvarchar的列起作用

新建一個表t4,包含varchar列和nvarchar列

SQL> create table t4(id number,name varchar(20),namen nvarchar2(20));

Table created.

SQL> desc t4;
 Name    Null?    Type
 ------- -------- --------------------------------------------------------
 ID                NUMBER
 NAME              VARCHAR2(20)
 NAMEN             NVARCHAR2(20)

向t4中插入資料

SQL> insert into t4 values(1,'中國','中國');

1 row created.

檢視資料的編碼

SQL> select id,name,dump(name,1016),namen,dump(namen,1016) from t4;

        ID NAME   DUMP(NAME,1016)                                    NAMEN  DUMP(NAMEN,1016)
---------- ------ -------------------------------------------------- ------ --------------------------------------------------
         1 中國   Typ=1 Len=4 CharacterSet=ZHS16GBK: d6,d0,b9,fa     中國   Typ=1 Len=4 CharacterSet=AL16UTF16: 4e,2d,56,fd

可以看出varchar列使用的資料庫字符集ZHS16GBK
而nvarchar列使用的是國家字符集AL16UTF16

所以國家字符集不是作用於整個表
而是作用於使用它的列

六)資料庫字符集狀況

我們可以查一下資料庫用到字符集的狀況

SQL> select * from nls_database_parameters;

PARAMETER                      VALUE
------------------------------ ----------------------------------------
NLS_LANGUAGE                   AMERICAN
NLS_TERRITORY                  AMERICA
NLS_CURRENCY                   $
NLS_ISO_CURRENCY               AMERICA
NLS_NUMERIC_CHARACTERS         .,
NLS_CHARACTERSET               ZHS16GBK
NLS_CALENDAR                   GREGORIAN
NLS_DATE_FORMAT                DD-MON-RR
NLS_DATE_LANGUAGE              AMERICAN
NLS_SORT                       BINARY
NLS_TIME_FORMAT                HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT           DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT             HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT        DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY              $
NLS_COMP                       BINARY
NLS_LENGTH_SEMANTICS           BYTE
NLS_NCHAR_CONV_EXCP            FALSE
NLS_NCHAR_CHARACTERSET         AL16UTF16
NLS_RDBMS_VERSION              10.2.0.1.0

20 rows selected.

資料庫的字符集
NLS_CHARACTERSET ZHS16GBK
是中文字符集
目前資料庫的字符集是中文字符集

國家字符集是
NLS_NCHAR_CHARACTERSET AL16UTF16

資料庫裡面是兩個字符集
第一叫資料庫字符集
第二叫國家字符集

當前資料庫系統使用環境
資料庫字符集是中文字符集
國家字符集是AL16UTF16

通過
select * from nls_database_parameters;
這個sql語句可以查出來

一般來講國家字符集用的比較少
一般都是使用資料庫字符集
國家字符集往往作為資料庫字符集的一個補充
它們應用場合不同

七)常用字符集

講到這個地方我們看一下字符集的命名

比如對oracle資料庫來講
有幾個經典的字符集

經常關注
US7ASCII
ZHS16CGB231280
AL32UTF8
AF16UTF16
ZHS16GBK
utf8
這幾個字符集

我們關注字符集的時候其實就關注一個地方
這個字符集能儲存哪些字元

比如這個US7ASCII碼
這是美國人使用的字符集
它只能儲存美國人的使用的字元
美國人儲存使用的字元不超過128個

我們學計算機的時候
學ascii碼都知道
我們的ascii碼一共使用一個位元組8個位來表示
對美國人來講它只使用右邊的7位,最高位是0
所以說它只使用7位

只能儲存常見的26個英文字母數字
以及加減乘除等字元
不超過128個
這是美國人用的字符集US7ASCII

zhs16cgb231280是中國人用的字符集
裡面可以存中文
這是我們的中文的國標
這個字符集比較老
裡面並沒有儲存所有的中文字符集,相對少一些

最新的中文字符集是ZHS16GBK
我們都用這個最新的中文字符集

zhs16cgb231280這個字符集所容納的所有的字元
ZHS16GBK都有
也就是說ZHS16GBK是zhs16cgb231280的超集

超集不意味著嚴格超集

所謂的超集就是
zhs16cgb231280裡面有的字元
ZHS16GBK裡面都有是超集

嚴格超集是
zhs16cgb231280裡面有的字元
ZHS16GBK裡面都有
而且zhs16cgb231280裡面字元對應的編碼
和ZHS16GBK裡面對應的編碼是一樣的
這就是嚴格超集

比如說zhs16cgb231280和ZHS16GBK是超集的關係
但不是嚴格超集的關係

比如“中國”兩個字
在zhs16cgb231280有,在ZHS16GBK裡面也有
但是在zhs16cgb231280裡面的編碼
和在ZHS16GBK裡面的編碼是不一樣的
所以只能說是超集不能說是嚴格超集

這是中文

還有一個utf8字符集
叫unicode字符集

zhs16cgb231280和ZHS16GBK這兩個裡面存的是中國人常用的字元
US7ASCII存的是美國人常用的字元

比如說“中石油”,這是個跨國企業
有一張表專門儲存員工的姓名的
對中石油來講
它既有中國人也有韓國人也有日本人也有辛巴威非洲人
有很多員工
這些員工的名字是有各個國家的名字
它們有自己的語言

所以說這個表裡面現在有一個需求

資料庫裡面
有張表,有列
有一個列是varchar將來可以存字元
存字元要用到資料庫字符集

這裡面將來要儲存的
第一儲存中文,第二英文,第三日文,第四韓語
要儲存很多字符集字元

要用中文字符集不行
英文字符集不行
日文韓文都不行
針對日文韓文都有相關的字符集都不行

這個時候針對這個問題
有一些比較大的公司它們統一起來做了一張字符集
叫unicode字符集
當時它設計的初衷是
將全世界所有的字元以及對應的編碼編成一個字符集

unicode字符集也是字符集
左面是字元右面是編碼

只不過它左邊的字元不僅僅侷限於中文英文
它的初衷是把全世界所有的字元全部編到這個編碼裡面去
然後給它統一性編碼
也就是說如果說資料庫是unicode字符集的話
也就意味著它可以儲存全世界所有的字元

所以一開始推出了一個utf8,u開頭的字符集

因為當時基於技術以及各個方面的限制
這個utf8它的初衷是儲存全部的字元
但是並沒有做到
只是儲存了部分字符集
但是裡面有中英文日文都有
只不過沒有那麼全而已

utf8是一個比較老的unicode字符集

最後隨著技術的改進
又推出了AL32UTF8這個最新的字符集
這個字符集比utf8字元就多的多了
它含的字符集範圍就非常廣了

所以說要用unicode字符集的話那就用AL32UTF8

對國家字符集來講我們統一的選AF16UTF16
這個字符集也是unicode字符集

unicode字符集有三個
AL32UTF8
AF16UTF16
utf8

對資料庫字符集來講,我們通常選擇AL32UTF8
對國家字符集來講,我們選擇AF16UTF16

因為AL32UTF8是unicode最新字符集
AF16UTF16是資料庫國家字符集

八)儲存中文的選擇

如果一個數據庫裡面我們將來要存中文
有幾種選擇

對國家字符集來講
我們只選擇AF16UTF16沒有別的選擇

對資料庫字符集來講
如果我將來要存中文有兩種辦法

第一種辦法
我們將資料庫字符集設成AL32UTF8
將來存中文肯定沒問題

第二個辦法
做成ZHS16GBK

如果確認資料庫裡面將來只存中文當然裡面也包括英文
只存中英文
也就是說只是中國人使用
最好把它設成ZHS16GBK

AL32UTF8它裡面是可以存中文
但是每一箇中文所對應的字元編碼會消耗更多的空間
也就是說AL32UTF8它全,但是在效能上會差一些
考慮到效能我們最好用ZHS16GBK

如果存中文,如果只存中文那就是ZHS16GBK

如果你是國際化、國際型的企業那就是UTF8

選擇AL32UTF8的話在很多地方會涉及到字元編碼的轉換
以及佔用過多的空間
佔用過多的空間就意味著
將來io啊網路啊等等會有更大的負載

這就是資料庫字符集該如何選擇

US7ASCII中的US表示語言存的是英語
7是也就是將來編碼是用7位
ASCII是編碼

對我們中國人來講
將來用ZHS16GBK用16位,GBK表示國標,
是使用我們中國人,我們的中文國標來進行編碼

九)有多少字符集可以選擇

我們到底有多少字符集可以選擇
可以使用
select * from V$NLS_VALID_VALUES;
看一下

SQL> select * from V$NLS_VALID_VALUES;

PARAMETER       VALUE                     ISDEP
--------------- ------------------------- -----
LANGUAGE        AMERICAN                  FALSE
LANGUAGE        GERMAN                    FALSE
LANGUAGE        FRENCH                    FALSE
LANGUAGE        CANADIAN FRENCH           FALSE
.
.
.                 
LANGUAGE        THAI                      FALSE
LANGUAGE        JAPANESE                  FALSE
LANGUAGE        KOREAN                    FALSE
LANGUAGE        SIMPLIFIED CHINESE        FALSE
LANGUAGE        TRADITIONAL CHINESE       FALSE
LANGUAGE        ENGLISH                   FALSE
.
.
.
TERRITORY       AMERICA                   FALSE
TERRITORY       UNITED KINGDOM            FALSE
.
.
.                 
TERRITORY       UNITED ARAB EMIRATES      FALSE
TERRITORY       THAILAND                  FALSE
TERRITORY       CHINA                     FALSE
TERRITORY       HONG KONG                 FALSE
TERRITORY       JAPAN                     FALSE
TERRITORY       KOREA                     FALSE
TERRITORY       TAIWAN                    FALSE
.
.
.            FALSE
CHARACTERSET    US7ASCII                  FALSE
CHARACTERSET    WE8DEC                    FALSE
.
.
.            
CHARACTERSET    WE8PC858                  FALSE
CHARACTERSET    WE8ISO8859P1              FALSE
CHARACTERSET    EE8ISO8859P2              FALSE
CHARACTERSET    SE8ISO8859P3              FALSE
CHARACTERSET    NEE8ISO8859P4             FALSE
CHARACTERSET    CL8ISO8859P5              FALSE
CHARACTERSET    AR8ISO8859P6              FALSE
CHARACTERSET    EL8ISO8859P7              FALSE
CHARACTERSET    IW8ISO8859P8              FALSE
CHARACTERSET    WE8ISO8859P9              FALSE
CHARACTERSET    NE8ISO8859P10             FALSE
.
.
.            
CHARACTERSET    IW8MSWIN1255              FALSE
CHARACTERSET    LT8MSWIN921               FALSE
CHARACTERSET    TR8MSWIN1254              FALSE
CHARACTERSET    WE8MSWIN1252              FALSE
.
.
. 
CHARACTERSET    JA16VMS                   FALSE
CHARACTERSET    JA16EUC                   FALSE
CHARACTERSET    JA16EUCYEN                FALSE
CHARACTERSET    JA16SJIS                  FALSE
CHARACTERSET    JA16DBCS                  FALSE
CHARACTERSET    JA16SJISYEN               FALSE
CHARACTERSET    JA16EBCDIC930             FALSE
CHARACTERSET    JA16MACSJIS               FALSE
CHARACTERSET    JA16EUCTILDE              FALSE
CHARACTERSET    JA16SJISTILDE             FALSE
CHARACTERSET    KO16KSC5601               FALSE
CHARACTERSET    KO16DBCS                  FALSE
CHARACTERSET    KO16KSCCS                 FALSE
CHARACTERSET    KO16MSWIN949              FALSE            
CHARACTERSET    ZHS16CGB231280            FALSE
CHARACTERSET    ZHS16MACCGB231280         FALSE
CHARACTERSET    ZHS16GBK                  FALSE
CHARACTERSET    ZHS16DBCS                 FALSE
CHARACTERSET    ZHS32GB18030              FALSE
CHARACTERSET    ZHT32EUC                  FALSE
CHARACTERSET    ZHT32SOPS                 FALSE
CHARACTERSET    ZHT16DBT                  FALSE
CHARACTERSET    ZHT32TRIS                 FALSE
CHARACTERSET    ZHT16DBCS                 FALSE
CHARACTERSET    ZHT16BIG5                 FALSE
CHARACTERSET    ZHT16CCDC                 FALSE
CHARACTERSET    ZHT16MSWIN950             FALSE
CHARACTERSET    ZHT16HKSCS                FALSE
CHARACTERSET    AL24UTFFSS                TRUE
CHARACTERSET    UTF8                      FALSE
CHARACTERSET    UTFE                      FALSE
CHARACTERSET    AL32UTF8                  FALSE
CHARACTERSET    ZHT16HKSCS31              FALSE
CHARACTERSET    JA16EUCFIXED              TRUE
CHARACTERSET    JA16SJISFIXED             TRUE
CHARACTERSET    JA16DBCSFIXED             TRUE
CHARACTERSET    KO16KSC5601FIXED          TRUE
CHARACTERSET    KO16DBCSFIXED             TRUE
CHARACTERSET    ZHS16CGB231280FIXED       TRUE
CHARACTERSET    ZHS16GBKFIXED             TRUE
CHARACTERSET    ZHS16DBCSFIXED            TRUE
CHARACTERSET    ZHT32EUCFIXED             TRUE
CHARACTERSET    ZHT32TRISFIXED            TRUE
CHARACTERSET    ZHT16DBCSFIXED            TRUE
CHARACTERSET    ZHT16BIG5FIXED            TRUE
CHARACTERSET    AL16UTF16                 FALSE
.
.
.
SORT            TCHINESE_RADICAL_M        FALSE
SORT            BIG5                      FALSE
SORT            HKSCS                     FALSE
SORT            TCHINESE_STROKE_M         FALSE
SORT            SCHINESE_PINYIN_M         FALSE
SORT            SCHINESE_STROKE_M         FALSE
SORT            GBK                       FALSE
SORT            SCHINESE_RADICAL_M        FALSE
SORT            JAPANESE_M                FALSE
SORT            KOREAN_M                  FALSE

494 rows selected.

返回內容較多隻截取了部分顯示

第一列是LANGUAGE的部分
如:
LANGUAGE AMERICAN FALSE
這是字符集關於語言的設定

第一列是CHARACTERSET
如:
CHARACTERSET US7ASCII FALSE
是關於字符集的設計

結果中有非常多的字符集可以設定
全部都可以設

有oracle支援的所有的字符集

有CHARACTERSET AL16UTF16 FALSE
字符集
是最後面的一個字符集

還有
CHARACTERSET AL32UTF8 FALSE
這個字符集unicode字符集

中文字符集可以去找一下

CHARACTERSET ZHS16GBK FALSE
是中文字符集

還有一些日文字符集
如:
CHARACTERSET JA16SJISTILDE FALSE

除了我們中英文以外
還有一些字符集
以後做資料庫的時候經常會碰到
就是我們的繁體

繁體字符集裡面又分臺灣的和香港的
香港的都用大5碼

因為現在的我們的臺灣企業和香港企業很多
所以說你將來畢業以後如果去香港企業的話
你會發現它的字符集很多用大5碼
大5碼是繁體中文
存簡體中文的時候可能有問題

在返回結果中的第三列是ISDEPRECATED
中文翻譯是:是否被啟用
就是因為版本升級的原因,有些引數可能在新版本中已不再被使用
如果當前還被使用這個值是FALSE
如果當前版本已經不使用這個引數了,這個值就是true

記住這裡有一個檢視可以去查

這裡講了資料庫字符集的一些常見的一些知識
以及常見字符集一些基礎的知識
並講了相關的檢視
同時講了哪些字符集可以設定

字符集的概論先簡單講到這個地方
下節課講一下
在一個複雜的環境裡面我們該如何去設定字符集
以及出了字符集以後如何去判斷

十)作業系統

字符集是作業系統處理資訊的一個很重要的方面
作業系統到底是什麼這裡也簡單的說一下

人們在執行各種軟體時
基本都不是在硬體上直接執行
而是在作業系統上執行

它給了一個操作計算機的環境
使硬體合理正確的工作
給軟體提供執行的環境

一個好的作業系統
可以全面的控制硬體
並使硬體完成各種各樣的功能
不用每個軟體再去編碼完成同樣的事情

它本身和軟體和硬體都有緊密的結合

以硬體和整合在硬體上的更基礎的軟體為基礎如各種bios
給程式提供各種執行的需求

bios為基本輸入輸出系統,為計算機中最基礎的系統
它整合在硬體中並最直接的和硬體接觸

計算機啟動需要先啟動硬體
從主機加電開始
然後檢查各個硬體