?
? ????? PHP ??? ???? ??? ?? ??
bytea數(shù)據(jù)類型允許存儲(chǔ)二進(jìn)制字符串。參閱Table 8-6。
Table 8-6. 二進(jìn)制數(shù)據(jù)類型
名字 | 存儲(chǔ)空間 | 描述 |
---|---|---|
bytea | 1或4字節(jié)加上實(shí)際的二進(jìn)制字符串 | 變長(zhǎng)的二進(jìn)制字符串 |
二進(jìn)制字符串是一個(gè)字節(jié)序列。二進(jìn)制字符串和普通字符字符串的區(qū)別有兩個(gè): 首先,二進(jìn)制字符串完全可以存儲(chǔ)字節(jié)零值以及其它"non-printable"字節(jié) (定義在32到126范圍之外的字節(jié))。字符串不允許字節(jié)零值, 并且也不允許那些不附合選定的字符集編碼的非法字節(jié)值或者字節(jié)序列。 第二,對(duì)二進(jìn)制字符串的處理實(shí)際上就是處理字節(jié),而對(duì)字符串的處理則取決于區(qū)域設(shè)置 。簡(jiǎn)單說(shuō),二進(jìn)制字符串適用于存儲(chǔ)那些程序員認(rèn)為是"raw bytes"的數(shù)據(jù), 而字符串適合存儲(chǔ)文本。
bytea類型支持兩種輸入輸出的外部格式: "hex"格式和PostgreSQL的歷史"escape"格式。 這兩種格式通常在輸入中使用,輸出格式由bytea_output配置參數(shù)決定,默認(rèn)是hex。 (需要注意的是hex格式是在PostgreSQL9.0中引入的, 早期版本和一些工具中不識(shí)別)
SQL 標(biāo)準(zhǔn)定義了一個(gè)不同的二進(jìn)制字符串格式, 稱為BLOB或BINARY LARGE OBJECT。 輸入格式與bytea不同,但提供的函數(shù)和操作符基本一致。
"hex"格式將二進(jìn)制數(shù)據(jù)編碼為每字節(jié)2位十六進(jìn)制數(shù)字, 最重要的四位(半字節(jié))放在開(kāi)始。 整條字符串以\x開(kāi)始(與逃逸格式相區(qū)別)。 在某些情況下,最初的反斜杠需要再寫(xiě)一次,以逃逸, 有時(shí),在逃逸格式中,反斜杠需要寫(xiě)兩個(gè),下面會(huì)詳細(xì)介紹。 十六進(jìn)制數(shù)字可以大寫(xiě)也可以小寫(xiě),并且數(shù)字對(duì)之間允許有空格(但不能是在一個(gè)數(shù)對(duì), 也不能是在\x起始序列)。 十六進(jìn)制格式能夠與許多的外部應(yīng)用程序和協(xié)議兼容,并且轉(zhuǎn)換往往比逃逸快,因此更傾向于這種用法。
Example:
SELECT E'\\xDEADBEEF';
對(duì)于bytea格式來(lái)說(shuō), "escape"格式是一種傳統(tǒng)的PostgreSQL格式。 它采用以ASCII字符序列來(lái)表示二進(jìn)制串的方法, 同時(shí)將那些無(wú)法表示成ASCII字符的二進(jìn)制串轉(zhuǎn)換成特殊的逃逸序列。 從應(yīng)用的角度看,如果代表字節(jié)的字符有意義,那么這種表示方法會(huì)很方便。 但實(shí)際上,這樣做會(huì)模糊二進(jìn)制字符串和字符字符串之間的關(guān)系,從而造成困擾,同時(shí)篩選出的逃逸機(jī)制 會(huì)顯得很臃腫。因此對(duì)一些新應(yīng)用應(yīng)該恰當(dāng)?shù)谋苊膺@種格式。
當(dāng)以逃逸格式錄入bytea值時(shí),某些值的八位字節(jié)必須被逃逸, 同時(shí)所有的八位字節(jié)值可以被逃逸。一般情況下,逃逸一個(gè)八位字節(jié)時(shí),將它轉(zhuǎn)換成 反斜杠+三位八進(jìn)制值的形式(或兩個(gè)反斜杠,如果用逃逸字符穿語(yǔ)法將值寫(xiě)成文本形式)。 另外,反斜杠本身(字節(jié)值92)可以用雙反斜杠表示。 Table 8-7給出了必須逃逸的字符串,和替代的逃逸序列(如適用)。
Table 8-7. bytea八進(jìn)制文本逃逸
十進(jìn)制數(shù)值 | 描述 | 輸入逃逸形式 | 例子 | 輸出形式 |
---|---|---|---|---|
0 | 八進(jìn)制的零 | E'\\000' | SELECT E'\\000'::bytea; | \000 |
39 | 單引號(hào) | ''''或E'\\047' | SELECT E'\''::bytea; | ' |
92 | 反斜杠 | E'\\\\' or E'\\134' | SELECT E'\\\\'::bytea; | \\ |
0 to 31 and 127 to 255 | "不可打印"字節(jié) | E'\\xxx' (八進(jìn)制值) | SELECT E'\\001'::bytea; | \001 |
逃逸不可打印字節(jié)的要求因區(qū)域設(shè)置而異。 在某些場(chǎng)合下,你可以不逃逸它們。 請(qǐng)注意Table 8-7里的每個(gè)例子都是剛好一個(gè)字節(jié)長(zhǎng), 雖然字節(jié)零和反斜杠輸出形式比一個(gè)字符要長(zhǎng)。
你必須寫(xiě)這么多反斜杠的原因,如Table 8-7所示, 是因?yàn)橐粋€(gè)寫(xiě)成字符串文本的輸入字符串必須通過(guò)PostgreSQL服務(wù)器里的兩個(gè)分析階段。 每一對(duì)反斜杠中的第一個(gè)會(huì)被字符串文本分析器 理解成一個(gè)逃逸字符而消耗掉,于是剩下的第二個(gè)反斜杠被bytea輸入函數(shù)當(dāng)作 一個(gè)三位八進(jìn)制值或者是逃逸另外一個(gè)反斜杠的開(kāi)始。 比如,一個(gè)傳遞給服務(wù)器的字符串文本E'\\001'在通過(guò) 字符串分析器之后會(huì)當(dāng)作\001發(fā)送給 bytea輸入函數(shù),在這里它被轉(zhuǎn)換成一個(gè)十進(jìn)制值為 1 的單個(gè)字節(jié)。請(qǐng)注意,單引號(hào)字符(')不會(huì)被bytea特殊對(duì)待, 它遵循字符串文本的普通規(guī)則。又見(jiàn)Section 4.1.2.1。
Bytea字節(jié)也在輸出中逃逸。 通常,每個(gè)"不可打印"的字節(jié)值都 轉(zhuǎn)化成對(duì)應(yīng)的前導(dǎo)反斜杠的三位八進(jìn)制數(shù)值。 大多數(shù)"可打印"字節(jié)值是以客戶端字符集的標(biāo)準(zhǔn)表現(xiàn)形式出現(xiàn)的。 十進(jìn)制值為 92(反斜杠)的字節(jié)在輸出形式增加一倍。 細(xì)節(jié)在Table 8-8里描述。
Table 8-8. bytea輸出逃逸序列
字節(jié)的十進(jìn)制 | 描述 | 逃逸的輸出形式 | 例子 | 輸出結(jié)果 |
---|---|---|---|---|
92 | 反斜杠 | \\ | SELECT E'\\134'::bytea; | \\ |
0 to 31 and 127 to 255 | "不可打印"八進(jìn)制字符 | \xxx (八進(jìn)制值) | SELECT E'\\001'::bytea; | \001 |
32 to 126 | "可打印"八進(jìn)制字符 | 客戶端字符集表現(xiàn)形式 | SELECT E'\\176'::bytea; | ~ |
根據(jù)你使用的前端不同,在是否逃逸bytea字符串的問(wèn)題上你可能有一些額外的工作要做。 比如,如果你的接口自動(dòng)轉(zhuǎn)換換行和回車,那你可能還要逃逸它們。