《卸甲筆記》-PostgreSQL和Oracle的資料型別的對比系列四:大資料型別
PostgreSQL是世界上功能最強大的開源資料庫,在國內得到了越來越多機構和開發者的青睞和應用。隨著PostgreSQL的應用越來越廣泛,Oracle向PostgreSQL資料庫的資料遷移需求也越來越多。資料庫之間資料遷移的時候,首先遇到的,並且也是最重要的,就是資料型別之間的轉換。下面根據自己的理解和測試,寫了一些資料型別之間的差異以及遷移時的注意事項的文章,不足之處,尚請多多指教。
大資料型別
Oracle的大資料型別主要包括三類。分別是儲存在資料庫內部的型別,包括BLOB, CLOB, NCLOB。儲存在外部的型別, 就是BFILE。還有Oracle不推薦使用, 僅用於特殊環境的型別。包括為了相容老版本而使用的Long和為了資料在不同系統間移動而利用的Long raw型別。
PostgreSQL的大資料型別只有兩種,就是儲存二進位制資料的bytea和儲存字元型別的text。下面介紹一下它們之間的對應和遷移時的一些注意事項。
注意: PostgreSQL對應的大資料型別還有一個物件識別符號型別(oid)。它是一個識別符號,指向在pg_largeobject 系統表中的一個bytea型別的物件。由於它是用一個四位元組的無符號整數實現,不能夠提供大資料庫範圍內的唯一性保證。因此,postgreSQL不推薦使用oid型別。加上它的內部實現,也是使用bytea型別,所以就不單獨介紹了。
1、儲存在資料庫內部的型別
1.1、BLOB型別
Oracle的Blob型別主要內容是二進位制的大物件。最大長度是(4G-1)*database block size。在PostgreSQL中,與之對應的是bytea。最大長度是1G。雖然最大長度小於Blob,但是在實際應用中已經足夠了。
Oracle BLOB
SQL> create table o_test(value blob);
表已建立。
SQL> insert into o_test values(`867814324901abedf4314312`);
已建立 1 行。
SQL> insert into o_test values(`867814324901abedf4314312t`);
insert into o_test values(`867814324901abedf4314312t`)
*
第 1 行出現錯誤:
ORA-01465: 無效的十六進位制數字
SQL> select * from o_test;
VALUE
--------------------------------------------------------------------------------
867814324901ABEDF4314312
PostgreSQL bytea
postgres=# create table p_test(value bytea);
CREATE TABLE
postgres=# insert into p_test values(`867814324901abedf4314312`);
INSERT 0 1
postgres=# insert into p_test values(`867814324901abedf4314312t`);
INSERT 0 1
postgres=# select * from p_test;
value
------------------------------------------------------
x383637383134333234393031616265646634333134333132
x38363738313433323439303161626564663433313433313274
(2 行記錄)
1.2、CLOB型別
Oracle的Clob型別,主要儲存基於資料庫字符集的單位元組或多位元組文字資訊,最大長度是(4G-1)*database block size。PostgreSQL中,可以使用text來對應。text的最大長度是1G,比Oracle的小。但是,實際應用中,1G已經足夠。
Oracle CLOB
SQL> create table o_test( value clob);
表已建立。
SQL> insert into o_test values(`122334543543666345435313421`);
已建立 1 行。
VALUE
--------------------------------------------------------------------------------
122334543543666345435313421
PostgreSQL text
postgres=# create table p_test(value text);
CREATE TABLE
postgres=# insert into p_test values(`1234567890123`);
INSERT 0 1
postgres=# select * from p_test;
value
---------------
1234567890123
(1 行記錄)
1.3、NCLOB型別
Oracle的NClob型別,主要儲存固定長度的UNICODE字串,最大長度是(4G-1)*database block size。PostgreSQL中,可以使用text來對應。text的最大長度是1G,比Oracle的小。但是,實際應用中,1G已經足夠。
Oracle CLOB
SQL> create table o_test1(value NCLOB);
表已建立。
SQL> insert into o_test1 values(`1223344452525341`);
已建立 1 行。
SQL> select DBMS_LOB.GETLENGTH(value) from o_test1;
DBMS_LOB.GETLENGTH(VALUE)
-------------------------
16
SQL> select * from o_test1;
VALUE
--------------------------------------------------------------------------------
1223344452525341
PostgreSQL text
postgres=# create table p_test(value text);
CREATE TABLE
postgres=# insert into p_test values(`1234567890123`);
INSERT 0 1
postgres=# select * from p_test;
value
---------------
1234567890123
(1 行記錄)
2、儲存在資料庫外部的型別
2.1、BFILE型別
儲存在資料庫外部的型別,就是指BFILE型別。BFILE是一種特殊的資料型別。資料並不儲存在資料庫內。資料庫內僅僅是一個檔案的指標。指明瞭檔案的路徑和檔名。實際的檔案儲存在硬碟上。只能對檔案進行讀取,而且不能Commit和Rollback。Oracle需要對檔案所在的路徑有讀許可權。檔案的大小理論上可以達到2^64-1位元組。
PostgreSQL中,沒有儲存在外部的資料型別。可以使用bytea來對應BFILE型別。資料型別的最大長度,沒有BFILE的大。但是實際應用中,bytea的大小已經足夠了。
Oracle BFILE
SQL> create table o_test(value bfile);
表已建立。
SQL> begin
2 insert into o_test values(bfilename(`BFILE1`, `00.txt`));
3 end;
4 /
PL/SQL 過程已成功完成。
SQL> declare txt1 BFILE;
2 piece raw(100);
3 amount binary_integer :=100;
4 begin
5 select value into txt1 from o_test;
6 DBMS_LOB.OPEN(txt1);
7 DBMS_LOB.READ(txt1, amount, 1, piece);
8 DBMS_LOB.CLOSE(txt1);
9 DBMS_OUTPUT.PUT_LINE(RAWTOHEX(piece));
10 end;
11 /
313233343535363635343333
PL/SQL 過程已成功完成。
PostgreSQL bytea
postgres=# create table p_test(value bytea);
CREATE TABLE
postgres=# insert into p_test values(`123455665433`);
INSERT 0 1
postgres=# select * from p_test;
value
----------------------------
x313233343535363635343333
(1 行記錄)
3、Oracle不推薦使用的大資料型別
3.1、LONG RAW型別
Oracle的long raw主要用於不同的系統之間轉移資料的時候所用,是Oracle不推薦使用的資料型別。Oracle推薦使用Blob來代替Long raw,並且Long raw的資料可以直接轉換成Blob型別。Long raw的最大範圍是2G。
PostgreSQL中,與之對應的就是bytea型別。
3.2、LONG型別
Oracle的Long型別是Oracle不推薦使用的一個資料型別。使用它有很多的限制。比如一個表中只能有1個欄位,不能用在where條件中使用等等。Oracle保留它的目的只是為了相容以前的版本。Long型別的最大範圍是2^31 -1(即2G-1)個位元組。
在PostgreSQL中,Long型別的對應欄位是text。雖然最大字元數少於Long型別,但是,text的最大長度1G在實際應用中已經足夠了。
Oracle LONG
SQL> create table o_test(value long);
表已建立。
SQL> insert into o_test values(`12sdfadsfewr34qdfsdsvvatearaewra`);
已建立 1 行。
SQL> select * from o_test;
VALUE
--------------------------------------------------------------------------------
12sdfadsfewr34qdfsdsvvatearaewra
SQL> select * from o_test where value =`12sdfadsfewr34qdfsdsvvatearaewra`;
select * from o_test where value =`12sdfadsfewr34qdfsdsvvatearaewra`
*
第 1 行出現錯誤:
ORA-00997: 非法使用 LONG 資料型別
PostgreSQL text
postgres=# create table p_test(value text);
CREATE TABLE
postgres=# insert into p_test values(`12sdfadsfewr34qdfsdsvvatearaewra`);
INSERT 0 1
postgres=# select * from p_test;
value
----------------------------------
12sdfadsfewr34qdfsdsvvatearaewra
(1 行記錄)
Oracle的大資料型別雖然多一些,但是PostgreSQL中基本上就是text和bytea兩個,分別對應文字資訊和二進位制資訊。遷移的時候,文字資訊轉成text,二進位制資訊轉成bytea。特殊型別BFILE形式的,可以額外寫一些程式碼把資料從檔案中讀出轉換成bytea。這樣就可以完成大資料型別的遷移。
參考文件:
PostgreSQL 9.4.4 中文手冊:字元型別,二進位制型別,物件識別符號型別
http://www.postgres.cn/docs/9.4/datatype-character.html (字元型別)
http://www.postgres.cn/docs/9.4/datatype-binary.html (二進位制型別)
http://www.postgres.cn/docs/9.4/datatype-oid.html (物件識別符號型別)
Database SQL Language Reference:Data Types
http://docs.oracle.com/cd/E11882_01/server.112/e41084/sql_elements001.htm#i45441
相關文章
- 《卸甲筆記》-PostgreSQL和Oracle的資料型別的對比系列五:其它型別筆記SQLOracle資料型別
- Java 支援的資料型別與 MySQL 支援的資料型別對比Java資料型別MySql
- Oracle資料型別對應Java型別Oracle資料型別Java
- Oracle和sqlserver資料型別對應OracleSQLServer資料型別
- MySql和SQL Server資料型別 對比MySqlServer資料型別
- MySQL資料型別筆記MySql資料型別筆記
- js資料型別之基本資料型別和引用資料型別JS資料型別
- 強資料型別和弱資料型別資料型別
- 區別值型別資料和引用型別資料型別
- Java 資料型別和 MySql 資料型別對應一覽表JavaMySQL 資料型別
- PostgreSQL批次改資料型別SQL資料型別
- Redis 筆記(核心資料型別)Redis筆記資料型別
- Go 筆記之資料型別Go筆記資料型別
- python筆記--資料型別Python筆記資料型別
- Oracle資料型別Oracle資料型別
- Oracle 資料型別Oracle資料型別
- Oracle的number資料型別Oracle資料型別
- Oracle的raw資料型別Oracle資料型別
- ORACLE的資料型別(轉)Oracle資料型別
- Oracle - LOB(大物件資料型別)Oracle物件資料型別
- Oracle三種集合資料型別的比較Oracle資料型別
- JAVA中基本資料型別和引用資料型別Java資料型別
- SQL Server 2005 資料型別和.Net資料型別的對應關係SQLServer資料型別
- JavaScript筆記5:計時器、物件、基本資料型別、引用資料型別JavaScript筆記物件資料型別
- [轉]ABAP資料型別與Java資料型別的對應關係資料型別Java
- SQL資料型別和C#資料型別間的轉換SQL資料型別C#
- 簡單資料型別和引用資料型別對應棧和堆示意圖資料型別
- 資料型別: 資料型別有哪些?資料型別
- ORACLE DATE和TIMESTAMP資料型別的比較(一) (轉)Oracle資料型別
- ORACLE DATE和TIMESTAMP資料型別的比較(二) (轉)Oracle資料型別
- oracle中date資料型別與timestamp資料型別的轉換Oracle資料型別
- MySQL學習筆記--資料型別MySql筆記資料型別
- JavaScript學習筆記---資料型別JavaScript筆記資料型別
- Oracle中常用的資料型別Oracle資料型別
- Oracle的 資料型別比較及注意事項Oracle資料型別
- 【轉】ORACLE資料型別Oracle資料型別
- Oracle anydata資料型別Oracle資料型別
- ORACLE NUMBER資料型別Oracle資料型別