支援的版本:目前 (16) / 15 / 14 / 13 / 12
開發版本:devel
不支援的版本:11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3

F.18. hstore — hstore 鍵/值資料類型 #

此模組實作 hstore 資料類型,用於在單一 PostgreSQL 值中儲存成對的鍵/值組。這在各種情況下都很有用,例如具有許多很少檢查的屬性的列,或半結構化資料。鍵和值只是單純的文字字串。

此模組被視為 受信任,也就是說,它可以由具有當前資料庫 CREATE 權限的非超級使用者安裝。

F.18.1. hstore 外部表示 #

用於輸入和輸出的 hstore 文字表示包括零個或多個以逗號分隔的 key => value 成對。一些範例

k => v
foo => bar, baz => whatever
"1-a" => "anything at all"

成對的順序並不重要(而且可能不會在輸出時重現)。成對之間或 => 符號周圍的空白會被忽略。雙引號鍵和值包括空白、逗號、=>。若要包含雙引號或反斜線在鍵或值中,請使用反斜線進行跳脫。

hstore 中的每個鍵都是唯一的。如果您宣告一個具有重複鍵的 hstore,只會有一個儲存在 hstore 中,而且無法保證會保留哪一個

SELECT 'a=>1,a=>2'::hstore;
  hstore
----------
 "a"=>"1"

值(但不是鍵)可以是 SQL NULL。例如

key => NULL

關鍵字 NULL 不區分大小寫。雙引號 NULL 將其視為一般字串 NULL

注意

請記住,在用於輸入時,hstore 文字格式會在任何必要的引號或跳脫 之前 套用。如果您透過參數傳遞 hstore 文字,則不需要任何額外的處理。但是,如果您將其傳遞為引號文字常數,則任何單引號字元和(視 standard_conforming_strings 組態參數的設定而定)反斜線字元都需要正確跳脫。請參閱 第 4.1.2.1 節 以進一步瞭解字串常數的處理方式。

在輸出時,雙引號總是包含鍵和值,即使它並非絕對必要。

F.18.2. hstore 運算子與函數 #

hstore 模組提供的運算子顯示在 表 F.7 中,函數顯示在 表 F.8 中。

表 F.7. hstore 運算子

運算子

說明

範例

hstore -> texttext

傳回與給定鍵關聯的值,或在不存在時傳回 NULL

'a=>x, b=>y'::hstore -> 'a'x

hstore -> text[]text[]

傳回與給定鍵關聯的值,或在不存在時傳回 NULL

'a=>x, b=>y, c=>z'::hstore -> ARRAY['c','a']{"z","x"}

hstore || hstorehstore

串接兩個 hstore

'a=>b, c=>d'::hstore || 'c=>x, d=>q'::hstore"a"=>"b", "c"=>"x", "d"=>"q"

hstore ? textboolean

hstore 是否包含鍵?

'a=>1'::hstore ? 'a't

hstore ?& text[]boolean

hstore 是否包含所有指定的鍵?

'a=>1,b=>2'::hstore ?& ARRAY['a','b']t

hstore ?| text[]boolean

hstore 是否包含任何指定的鍵?

'a=>1,b=>2'::hstore ?| ARRAY['b','c']t

hstore @> hstoreboolean

左運算元是否包含右運算元?

'a=>b, b=>1, c=>NULL'::hstore @> 'b=>1't

hstore <@ hstore布林值

左運算元是否包含在右運算元中?

'a=>c'::hstore <@ 'a=>b, b=>1, c=>NULL'f

hstore - 文字hstore

從左運算元中刪除金鑰。

'a=>1, b=>2, c=>3'::hstore - 'b'::text"a"=>"1", "c"=>"3"

hstore - 文字陣列hstore

從左運算元中刪除金鑰。

'a=>1, b=>2, c=>3'::hstore - ARRAY['a','b']"c"=>"3"

hstore - hstorehstore

從左運算元中刪除與右運算元中配對配對的配對。

'a=>1, b=>2, c=>3'::hstore - 'a=>4, b=>2'::hstore"a"=>"1", "c"=>"3"

anyelement #= hstoreanyelement

使用來自 hstore 的相符值取代左運算元(必須是複合類型)中的欄位。

ROW(1,3) #= 'f1=>11'::hstore(11,3)

%% hstore文字陣列

hstore 轉換為交替金鑰和值的陣列。

%% 'a=>foo, b=>bar'::hstore{a,foo,b,bar}

%# hstore文字陣列

hstore 轉換為二維金鑰/值陣列。

%# 'a=>foo, b=>bar'::hstore{{a,foo},{b,bar}}


表格 F.8. hstore 函數

函數

說明

範例

hstore ( 記錄 ) → hstore

從記錄或列建立 hstore

hstore(ROW(1,2))"f1"=>"1", "f2"=>"2"

hstore ( 文字陣列 ) → hstore

從陣列建立 hstore,該陣列可以是金鑰/值陣列,也可以是二維陣列。

hstore(ARRAY['a','1','b','2'])"a"=>"1", "b"=>"2"

hstore(ARRAY[['c','3'],['d','4']])"c"=>"3", "d"=>"4"

hstore ( 文字陣列, 文字陣列 ) → hstore

從個別金鑰和值陣列建立 hstore

hstore(ARRAY['a','b'], ARRAY['1','2'])"a"=>"1", "b"=>"2"

hstore ( 文字, 文字 ) → hstore

建立單一項目 hstore

hstore('a', 'b')"a"=>"b"

akeys ( hstore ) → text[]

萃取 hstore 的金鑰為陣列。

akeys('a=>1,b=>2'){a,b}

skeys ( hstore ) → setof text

萃取 hstore 的金鑰為集合。

skeys('a=>1,b=>2')

a
b

avals ( hstore ) → text[]

萃取 hstore 的值為陣列。

avals('a=>1,b=>2'){1,2}

svals ( hstore ) → setof text

萃取 hstore 的值為集合。

svals('a=>1,b=>2')

1
2

hstore_to_array ( hstore ) → text[]

萃取 hstore 的金鑰和值為陣列,交替排列金鑰和值。

hstore_to_array('a=>1,b=>2'){a,1,b,2}

hstore_to_matrix ( hstore ) → text[]

萃取 hstore 的金鑰和值為二維陣列。

hstore_to_matrix('a=>1,b=>2'){{a,1},{b,2}}

hstore_to_json ( hstore ) → json

轉換 hstorejson 值,將所有非空值轉換為 JSON 字串。

hstore 值轉換為 json 時,會隱含使用此函數。

hstore_to_json('"a key"=>1, b=>t, c=>null, d=>12345, e=>012345, f=>1.234, g=>2.345e+4'){"a key": "1", "b": "t", "c": null, "d": "12345", "e": "012345", "f": "1.234", "g": "2.345e+4"}

hstore_to_jsonb ( hstore ) → jsonb

轉換 hstorejsonb 值,將所有非空值轉換為 JSON 字串。

hstore 值轉換為 jsonb 時,會隱含使用此函數。

hstore_to_jsonb('"a key"=>1, b=>t, c=>null, d=>12345, e=>012345, f=>1.234, g=>2.345e+4'){"a key": "1", "b": "t", "c": null, "d": "12345", "e": "012345", "f": "1.234", "g": "2.345e+4"}

hstore_to_json_loose ( hstore ) → json

hstore 轉換為 json 值,但會嘗試區分數字和布林值,以便在 JSON 中不加引號。

hstore_to_json_loose('"a key"=>1, b=>t, c=>null, d=>12345, e=>012345, f=>1.234, g=>2.345e+4'){"a key": 1, "b": true, "c": null, "d": 12345, "e": "012345", "f": 1.234, "g": 2.345e+4}

hstore_to_jsonb_loose ( hstore ) → jsonb

hstore 轉換為 jsonb 值,但會嘗試區分數字和布林值,以便在 JSON 中不加引號。

hstore_to_jsonb_loose('"a key"=>1, b=>t, c=>null, d=>12345, e=>012345, f=>1.234, g=>2.345e+4'){"a key": 1, "b": true, "c": null, "d": 12345, "e": "012345", "f": 1.234, "g": 2.345e+4}

slice ( hstore, text[] ) → hstore

僅包含指定金鑰的 hstore 子集。

slice('a=>1,b=>2,c=>3'::hstore, ARRAY['b','c','x'])"b"=>"2", "c"=>"3"

each ( hstore ) → setof record ( key text, value text )

hstore 的金鑰和值萃取為一組記錄。

select * from each('a=>1,b=>2')

 key | value
-----+-------
 a   | 1
 b   | 2

exist ( hstore, text ) → boolean

hstore 是否包含鍵?

exist('a=>1', 'a')t

defined ( hstore, text ) → boolean

是否 hstore 包含金鑰的非 NULL 值?

defined('a=>NULL', 'a')f

delete ( hstore, text ) → hstore

刪除具有相符金鑰的配對。

delete('a=>1,b=>2', 'b')"a"=>"1"

delete ( hstore, text[] ) → hstore

刪除具有匹配金鑰的配對。

delete('a=>1,b=>2,c=>3', ARRAY['a','b'])"c"=>"3"

delete ( hstore, hstore ) → hstore

刪除與第二個參數中匹配的配對。

delete('a=>1,b=>2', 'a=>4,b=>2'::hstore)"a"=>"1"

populate_record ( anyelement, hstore ) → anyelement

使用來自 hstore 的相符值取代左運算元(必須是複合類型)中的欄位。

populate_record(ROW(1,2), 'f1=>42'::hstore)(42,2)


除了這些運算子與函式之外,hstore 類型的值可以作為下標,讓它們可以像關聯式陣列一樣運作。只能指定單一 text 類型的下標;它會被解釋為金鑰,並擷取或儲存對應的值。例如,

CREATE TABLE mytable (h hstore);
INSERT INTO mytable VALUES ('a=>b, c=>d');
SELECT h['a'] FROM mytable;
 h
---
 b
(1 row)

UPDATE mytable SET h['c'] = 'new';
SELECT h FROM mytable;
          h
----------------------
 "a"=>"b", "c"=>"new"
(1 row)

如果下標為 NULLhstore 中不存在該金鑰,下標擷取會傳回 NULL。(因此,下標擷取與 -> 運算子沒有太大的不同。)如果下標為 NULL,下標更新會失敗;否則,它會取代該金鑰的值,如果金鑰不存在,則會新增一個項目至 hstore

F.18.3. 索引 #

hstore 具有對 @>??&?| 運算子支援的 GiST 和 GIN 索引。例如

CREATE INDEX hidx ON testhstore USING GIST (h);

CREATE INDEX hidx ON testhstore USING GIN (h);

gist_hstore_ops GiST opclass 將一組金鑰/值配對近似為位元圖簽章。其選用的整數參數 siglen 決定簽章長度(以位元組為單位)。預設長度為 16 個位元組。有效的簽章長度值介於 1 到 2024 個位元組之間。較長的簽章會導致更精確的搜尋(掃描較小的索引部分和較少的堆積頁面),但索引會較大。

建立具有 32 個位元組簽章長度的索引的範例

CREATE INDEX hidx ON testhstore USING GIST (h gist_hstore_ops(siglen=32));

hstore 也支援 btreehash 索引,用於 = 算子。這允許 hstore 欄位宣告為 UNIQUE,或用於 GROUP BYORDER BYDISTINCT 表達式。對 hstore 值進行排序並非特別有用,但這些索引可能對等效查詢很有用。建立索引以進行 = 比較,如下所示

CREATE INDEX hidx ON testhstore USING BTREE (h);

CREATE INDEX hidx ON testhstore USING HASH (h);

F.18.4. 範例 #

新增一個金鑰,或使用新值更新現有金鑰

UPDATE tab SET h['c'] = '3';

執行相同操作的另一種方法是

UPDATE tab SET h = h || hstore('c', '3');

如果要一次新增或變更多個金鑰,連接方法比下標更有效率

UPDATE tab SET h = h || hstore(array['q', 'w'], array['11', '12']);

刪除金鑰

UPDATE tab SET h = delete(h, 'k1');

record 轉換為 hstore

CREATE TABLE test (col1 integer, col2 text, col3 text);
INSERT INTO test VALUES (123, 'foo', 'bar');

SELECT hstore(t) FROM test AS t;
                   hstore
---------------------------------------------
 "col1"=>"123", "col2"=>"foo", "col3"=>"bar"
(1 row)

hstore 轉換為預先定義的 record 類型

CREATE TABLE test (col1 integer, col2 text, col3 text);

SELECT * FROM populate_record(null::test,
                              '"col1"=>"456", "col2"=>"zzz"');
 col1 | col2 | col3
------+------+------
  456 | zzz  |
(1 row)

使用 hstore 的值修改現有記錄

CREATE TABLE test (col1 integer, col2 text, col3 text);
INSERT INTO test VALUES (123, 'foo', 'bar');

SELECT (r).* FROM (SELECT t #= '"col3"=>"baz"' AS r FROM test t) s;
 col1 | col2 | col3
------+------+------
  123 | foo  | baz
(1 row)

F.18.5. 統計資料 #

由於 hstore 類型的內在自由度,它可能包含許多不同的金鑰。檢查有效金鑰是應用程式的任務。下列範例示範了檢查金鑰和取得統計資料的幾種技術。

簡單範例

SELECT * FROM each('aaa=>bq, b=>NULL, ""=>1');

使用表格

CREATE TABLE stat AS SELECT (each(h)).key, (each(h)).value FROM testhstore;

線上統計資料

SELECT key, count(*) FROM
  (SELECT (each(h)).key FROM testhstore) AS stat
  GROUP BY key
  ORDER BY count DESC, key;
    key    | count
-----------+-------
 line      |   883
 query     |   207
 pos       |   203
 node      |   202
 space     |   197
 status    |   195
 public    |   194
 title     |   190
 org       |   189
...................

F.18.6. 相容性 #

從 PostgreSQL 9.0 開始,hstore 使用與先前版本不同的內部表示法。由於文字表示法(用於傾印)未變更,這不會對傾印/還原升級造成阻礙。

在二進位升級的情況下,透過讓新程式碼辨識舊格式資料,來維持向上相容性。在處理尚未由新程式碼修改的資料時,這將造成輕微的效能損失。可以透過執行下列 UPDATE 陳述式,強制升級表格欄位中的所有值

UPDATE tablename SET hstorecol = hstorecol || '';

另一種執行方法是

ALTER TABLE tablename ALTER hstorecol TYPE hstore USING hstorecol || '';

ALTER TABLE 方法需要對表格進行 ACCESS EXCLUSIVE 鎖定,但不會導致表格因舊列版本而膨脹。

F.18.7. 轉換 #

有其他可用的擴充套件,可為 PL/Perl 和 PL/Python 語言實作 hstore 類型的轉換。PL/Perl 的擴充套件稱為 hstore_plperlhstore_plperlu,分別用於受信任和不受信任的 PL/Perl。如果您安裝這些轉換,並在建立函數時指定它們,hstore 值會對應到 Perl hash。PL/Python 的擴充套件稱為 hstore_plpython3u。如果您使用它,hstore 值會對應到 Python 字典。

注意

強烈建議將轉換擴充套件安裝在與 hstore 相同的架構中。否則,如果轉換擴充套件的架構包含敵對使用者定義的物件,則在安裝時會有安全風險。

F.18.8. 作者 #

Oleg Bartunov ,俄羅斯莫斯科莫斯科大學

Teodor Sigaev ,俄羅斯莫斯科 Delta-Soft Ltd.

Andrew Gierth ,英國,提供額外增強功能

提交修正

如果您在文件中看到任何不正確、與您使用特定功能的經驗不符或需要進一步說明的內容,請使用 此表單 回報文件問題。