2012-04-11 2 views
3

Я знаю, что вы можете создать индекс в поле в столбце hstore. Я знаю, что вы также можете создать индекс GIN в столбце массива.Индексы на столбцах массива hstore PostgreSQL

Но каков синтаксис для создания индекса в массиве 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. –

+0

Как я уже упоминал в приведенном ниже комментарии, мы хотим перейти к модели DB без схемы, чтобы мы могли развертывать новые версии наших приложений без необходимости простоев, вызванных обновлениями БД и блокировками таблицы ALTER TABLE ADD COLUMN. –

ответ

5

Я думаю, вы неправильно поняли PostgreSQL Array s. Array на самом деле просто строка. Вы не можете индексировать объекты (в данном случае HSTORE s) в массиве, просто потому, что это не 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 S здесь?

Если вы должны создать INDEX на основе "purchase"HSTORE здесь, сделать что-то вроде этого:

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

Я не знаю, по какой-либо причине вы не можете создать индекс GIN или GIST непосредственно в столбце hstore; это описано здесь: http://www.postgresql.org/docs/9.1/interactive/hstore.html#AEN133006 Но я склонен думать, что это плохой выбор по сравнению с нормализацией данных с отдельными таблицами для покупок и line_items. Просто потому, что вы * можете * что-то сделать, это не очень хорошая идея. С другой стороны, если это учебное упражнение, чтобы увидеть, как использовать hstore, я думаю, что этот ответ может быть лучшим способом. – kgrittn

+2

Это не обфускация. Необходимость обновления нуля (например, мы не можем заблокировать таблицу с помощью ALTER TABLE ADD COLUMN) при развертывании новой версии приложения. Hstore показался хорошим вариантом в основном иметь хранилище объектов без схемы, которое может развиваться сверхурочно через логику приложения без необходимости обновления БД. –

+2

Добавление столбца в таблицу в postgresql не будет блокировать таблицу за какое-либо заметное время (предполагая, что столбец не имеет ограничений и может быть нулевым). –

Смежные вопросы