Ключ / значение hstore в postgresql по сравнению с традиционной производительностью SQL - PullRequest
8 голосов
/ 28 февраля 2012

Мне нужно разработать бэкэнд ключ / значение, что-то вроде этого:

Table T1 id-PK, Key - string, Value - string
INSERT into T1('String1', 'Value1')
INSERT INTO T1('String1', 'Value2')

Table T2 id-PK2, id2->external key to id
some other data in T2, which references data in T1 (like users which have those K/V etc)

Я слышал о PostgreSQL hstore с GIN / GIST.Что лучше (с точки зрения производительности)?Делать это традиционным способом с SQL-соединениями и иметь отдельные столбцы (ключ / значение)?Работает ли PostgreSQL hstore лучше в этом случае?

Формат данных должен быть любым ключом => любым значением.Я также хочу сделать сопоставление текста, например, частичный поиск (LIKE% в SQL или использование эквивалента hstore).Я планирую иметь около 1M-2M записей в нем и, вероятно, в какой-то момент масштабировать.

Что вы рекомендуете?Идем ли мы традиционным способом SQL / PostgreSQL hstore или любым другим распределенным хранилищем ключей / значений с постоянством?

Если это поможет, мой сервер - это VPS с 1-2 ГБ ОЗУ, так что это не очень хорошее оборудование.Я также думал о том, чтобы поверх этого был слой кеша, но я думаю, что это несколько усложняет проблему.Я просто хочу хорошую производительность для 2M записей.Обновления будут выполняться часто, но поиск будет выполняться еще чаще.

Спасибо.

Ответы [ 2 ]

8 голосов
/ 04 июля 2012

Ваш вопрос неясен, потому что вы не понимаете своей цели.

Ключ здесь - это индекс (каламбур) - если вы имеете дело с большим количеством ключей, вы хотите иметь возможность получить их с помощьюнаименьшее количество поисков и без извлечения несвязанных данных.

Краткий ответ: вы, вероятно, не хотите использовать hstore, но давайте рассмотрим более подробно ...

  • У каждого id есть много пар ключ / значение (сотни +)?Не используйте hstore.
  • Будут ли какие-либо из ваших значений содержать большие блоки текста (4 КБ +)?Не используйте hstore.
  • Хотите ли вы выполнять поиск по ключам в подстановочных выражениях?Не используйте hstore.
  • Вы хотите делать сложные объединения / агрегирование / отчеты?Не используйте hstore.
  • Будете ли вы обновлять значение для одного ключа?Не использовать hstore.
  • Несколько клавиш с одинаковым именем под id?Не могу использовать hstore.

Так в чем же смысл hstore?Хорошо, один хороший сценарий был бы, если бы вы хотели сохранить пары ключ / значение для внешнего приложения, где вы знаете, что вы всегда хотите получить все ключ / значения и всегда сохраните данные обратно как блок (т.е.никогда не редактируется на месте).В то же время вам нужна некоторая гибкость для возможности поиска этих данных - очень просто - вместо того, чтобы хранить их, например, в блоке XML или JSON.В этом случае, поскольку количество пар ключ / значение невелико, вы экономите место, потому что сжимаете несколько кортежей в один hstore.

. Рассматривайте это как таблицу:

CREATE TABLE kv (
  id /* SOME TYPE */ PRIMARY KEY,
  key_name TEXT NOT NULL,
  key_value TEXT,
  UNIQUE(id, key_name)
);
1 голос
/ 10 июля 2013

Мне кажется, дизайн плохо нормализован. Попробуйте что-то вроде этого:

CREATE TABLE t1
(
  t1_id serial PRIMARY KEY,
  <other data which depends on t1_id and nothing else>,
  -- possibly an hstore, but maybe better as a separate table
  t1_props hstore
);

-- if properties are done as a separate table:
CREATE TABLE t1_properties
(
  t1_id int NOT NULL REFERENCES t1,
  key_name text NOT NULL,
  key_value text,
  PRIMARY KEY (t1_id, key_name)
);

Если свойства небольшие, и вам не нужно интенсивно использовать их в соединениях или с причудливыми критериями выбора, и hstore может быть достаточно. Эллиот изложил некоторые разумные вещи для рассмотрения в этом отношении.

Ваша ссылка на пользователей предполагает, что это неполно, но вы на самом деле не дали достаточно информации, чтобы предположить, где они принадлежат. Вы могли бы обойтись с массивом в t1, или вы могли бы быть лучше с отдельной таблицей.

...