PostgreSQL7.0手冊-程序員手冊 -39. 擴(kuò)展的 SQL: 類型
2019-09-08 23:33:47
供稿:網(wǎng)友
第三十九章. 擴(kuò)展的 SQL: 類型
正如前面所說,在 Postgres 里有兩種數(shù)據(jù)類型:基本類型(在編程語言里定義)和復(fù)合類型(記錄).本章的關(guān)于索引的接口的例子可以在 complex.sql 和 complex.c 里找到.復(fù)合例子在 funcs.sql 里.
用戶定義類型
用戶定義類型所需要的函數(shù)
一個用戶定義的類型總是有輸入和輸出函數(shù).這些函數(shù)決定該類型如何在字串里出現(xiàn)(讓用戶輸入和輸出給用戶)和類型如何在存儲器里組織.輸入函數(shù)以一個以空(null)為分隔符的字符串為輸入并且返回該類型的內(nèi)部(在存儲器里)的表現(xiàn)形式.輸出類型以該類型的內(nèi)部表現(xiàn)形式為輸入并且返回一個以空(null)為分隔符的字符串.假設(shè)我們要定義一個復(fù)數(shù)類型用來表示復(fù)數(shù).通常,我們選用下面的 C 結(jié)構(gòu)來在存儲器里表現(xiàn)復(fù)數(shù):
typedef struct Complex {
double x;
double y;
} Complex;
并且以 (x,y) 形式的字串做為外部的表現(xiàn)形式.這些函數(shù)通常比較容易寫,尤其是輸出函數(shù).不過,我們還是要注意幾點(diǎn):
當(dāng)定義你的外部(字符串)表現(xiàn)形式時,要注意你最后必須為該表現(xiàn)形式寫一個完整而且健壯的分析器作為你的輸入函數(shù)!
Complex *
complex_in(char *str)
{
double x, y;
Complex *result;
if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2) {
elog(WARN, "complex_in: error in parsing
return NULL;
}
result = (Complex *)palloc(sizeof(Complex));
result->x = x;
result->y = y;
return (result);
}
輸出函數(shù)可以簡單的就是:
char *
complex_out(Complex *complex)
{
char *result;
if (complex == NULL)
return(NULL);
result = (char *) palloc(60);
sprintf(result, "(%g,%g)", complex->x, complex->y);
return(result);
}
你應(yīng)該把你的輸入和輸出函數(shù)做的互為逆(函數(shù)).如果你不這樣做,你就可能在需要把數(shù)據(jù)輸出來在裝載回去時碰到很嚴(yán)重的問題(比如,輸入到別人在另外的計算機(jī)上的數(shù)據(jù)庫中去).當(dāng)涉及到浮點(diǎn)數(shù)時,這是非常普遍的問題.
要定義 complex 類型,我們要在創(chuàng)建該類型前先創(chuàng)建兩個用戶定義函數(shù) complex_in 和 complex_out:
CREATE FUNCTION complex_in(opaque)
RETURNS complex
AS 'PGROOT/tutorial/obj/complex.so'
LANGUAGE 'c';
CREATE FUNCTION complex_out(opaque)
RETURNS opaque
AS 'PGROOT/tutorial/obj/complex.so'
LANGUAGE 'c';
CREATE TYPE complex (
internallength = 16,
input = complex_in,
output = complex_out
);
正如我們前面討論的,Postgres 完全支持基本類型的數(shù)組.另外,Postgres 同樣還支持用戶定義類型的數(shù)組.當(dāng)你定義類型時,Postgres 自動提供對該類型的數(shù)組的支持.因?yàn)闅v史原因,數(shù)組類型的類型名是與類型同名字串前面加個下劃線 _ .不需要為復(fù)合類型定義任何函數(shù),因?yàn)橄到y(tǒng)已經(jīng)知道它們在里面看起來象什么.
大對象
到此為止我們討論的類型都是"小"對象?。簿褪钦f,它們都小于 8KB.
注意:1024 longwords(長字) == 8192 字節(jié).實(shí)際上,類型應(yīng)該是遠(yuǎn)比 8192 字節(jié)小,因?yàn)镻ostgres 記錄和頁面等附加部分內(nèi)容也必須放在這個 8KB 限制里面.這部分附加數(shù)據(jù)量的實(shí)際大小取決于機(jī)器體系結(jié)構(gòu).
如果你需要一個更大的類型用于象文檔檢索或存儲位圖等,你將需要使用 Postgres 大對象接口或者需要重新編譯 Postgres 后端以使內(nèi)部的存儲塊大于 8k 字節(jié).
--------------------------------------------------------------------------------