2012-04-11 45 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