2012-04-11 44 views
3

我知道您可以在hstore列中的字段上創建索引。 我知道你也可以在數組列上創建一個GIN索引。PostgreSQL hstore數組列上的索引

但是,在hstore數組上創建索引的語法是什麼?

例如

CREATE TABLE customer (
    pk serial PRIMARY KEY, 
    customer hstore, 
    customer_purchases hstore[] 
); 

比方說,客戶購買hstore可能像

productId -> 1 
price -> 9.99 

哈希和我有那些在customer_purchases數組hstore []

我想創建客戶索引.customer_purchases [] - > productId

這可能嗎?我已經嘗試了CREATE INDEX語法的不同組合,並且它們都不支持hstore數組中的索引字段。

+0

如果忽略hstore並簡單地使用兩個額外的表,這似乎是一個解決的問題。爲什麼這樣做?如果您出於某種原因必須定義一個IMMUTABLE函數,該函數會生成一個可排序的值並在您的CREATE INDEX語法中調用該函數。 – 2012-04-12 03:46:57

+0

正如我在下面的評論中所提到的,我們希望向無模式數據庫模型發展,這樣我們就可以推出新版本的應用程序,而不需要由數據庫升級和ALTER TABLE ADD COLUMN表鎖造成的停機時間。 – 2012-04-12 14:02:23

回答

5

我想你已經誤解了PostgreSQL Array s。 Array實際上只是一個字符串。您不能將數組中的對象(在這種情況下爲HSTORE)索引,因爲它不是TABLE

相反,創建一個額外的表:

CREATE TABLE customer (
    pk bigserial PRIMARY KEY, 
    customer hstore 
); 

CREATE TABLE purchases (
    pk bigserial PRIMARY KEY, 
    customer_pk bigint not null, 
    purchase hstore not null, 
    constraint "must be a valid customer!" 
     foreign key (customer_pk) references customer(pk) 
); 

而且,你爲什麼要使用HSTORE在這兒?

如果必須創建基於"purchase"HSTORE這裏的INDEX,做這樣的事情:

CREATE OR REPLACE FUNCTION purchase_amount(purchase hstore) returns float as $$ 
    select ($1 -> 'price')::float; 
$$ language 'SQL' IMMUTABLE; 

CREATE INDEX "purchases by price" ON purchases (purchase_amount(purchase)); 

這只是一個練習來了解HSTORE類型?還是你有一些真正的用例會讓你的真實數據變得混亂?

+1

我不知道你有什麼理由不能直接在hstore列創建GIN或GIST索引;它記錄在這裏:http://www.postgresql.org/docs/9.1/interactive/hstore.html#AEN133006但我確實傾向於認爲這是一個不好的選擇,與使用單獨的表格進行購物和line_items規範化數據相比。僅僅因爲你*可以做某件事情並不是一個好主意。另一方面,如果這是一個培訓練習來了解如何使用hstore,我認爲這個答案可能是最好的選擇。 – kgrittn 2012-04-12 05:06:47

+2

這不是一個混淆。當部署新版本的應用程序時,需要進行零宕機升級(即我們無法使用ALTER TABLE ADD COLUMN鎖定表)。 Hstore似乎是一個很好的選擇,基本上有一個無模式實體存儲,可以通過應用程序邏輯演變超時而不需要數據庫升級 – 2012-04-12 13:47:04

+2

向postgresql中的表添加列不會將表鎖定任何明顯的時間量假設列沒有約束並且可以爲空)。 – 2013-07-03 22:41:12