hstore Внешнее представлениеhstore Операторы и функции
Данный модуль реализует hstore тип данных для хранения наборов
пар «ключ/значение» в одном Digital Q.DataBase поле. Это может быть полезно в различных сценариях, например, для строк с множеством редко используемых атрибутов или для слабоструктурированных данных. Ключи и значения являются обычными текстовыми строками.
Этот модуль считается «trusted»(доверенным), то есть он может быть установлен обычными пользователями, имеющими CREATE право
в текущей базе данных.
hstore Внешнее представление #
Текстовое представление типа hstore, используемое для ввода и вывода,
может содержать ноль или более ключ =>
value пары, разделенные запятыми. Примеры:
k => v foo => bar, baz => whatever "1-a" => "anything at all"
Порядок следования пар не является значимым (и может не сохраняться при выводе данных). Пробелы между парами или вокруг символа => знак игнорируется. Ключи и значения, содержащие пробелы, запятые,
=или >, необходимо заключать в двойные кавычки. Чтобы включить символ двойной кавычки или обратной косой черты в ключ или значение, его необходимо экранировать обратной косой чертой.
Каждый ключ в типе данных hstore уникален. Если тип данных hstore
объявляется с дублирующимися ключами, то в hstore будет сохранено только одно из них, hstore и нет гарантии того, какое именно из них будет сохранено:
SELECT 'a=>1,a=>2'::hstore; hstore ---------- "a"=>"1"
Значение (но не ключ) может принимать значение SQL NULL. Например:
key => NULL
Ключевое слово NULL нечувствительно к регистру. Заключите
NULL в двойные кавычки, чтобы оно воспринималось как обычная строка «NULL».
Учтите, что hstore текстовый формат при использовании для ввода
применяется перед любым необходимым квотированием или экранированием. Если вы
передаете hstore литерал через параметр, дополнительная обработка не требуется. Но если вы передаете его как литеральную константу в кавычках, то любые символы одиночной кавычки и (в зависимости от настройки standard_conforming_strings параметра конфигурации)
символы обратной косой черты должны быть правильно экранированы. См.
Раздел 2.1.1.2.1 для получения дополнительной информации об обработке строковых констант.
При выводе ключи и значения всегда заключаются в двойные кавычки, даже когда это не является строго необходимым.
hstore Операторы и функции #
Операторы, предоставляемые модулем тип данных hstore модуля приведены в Таблица 8.6.6, функции в Таблица 8.6.7.
Таблица 8.6.6. hstore Операторы
Оператор Описание Пример(ы) |
|---|
Возвращает значение, связанное с указанным ключом, или
|
Возвращает значения, связанные с указанными ключами, или
|
Выполняет конкатенацию двух
|
Содержит ли
|
Содержит ли
|
Содержит ли
|
Содержит ли левый операнд правый?
|
Содержится ли левый операнд в правом?
|
Удаляет ключ из левого операнда.
|
Удаляет ключи из левого операнда.
|
Удаляет из левого операнда пары, соответствующие парам в правом операнде.
|
Заменяет поля в левом операнде (который должен иметь составной тип данных)
соответствующими значениями из
|
Преобразует тип данных
|
Преобразует тип данных
|
Таблица 8.6.7. hstore Функции
Помимо этих операторов и функций, значения
типа данных hstore 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 строка)
Операция выборки по индексу возвращает NULL если индекс
имеет значение NULL или если этот ключ отсутствует в
поле hstore. (Таким образом, выборка по индексу существенно не отличается от работы оператора -> .)
Обновление по индексу завершается ошибкой, если индекс равен NULL;
в противном случае операция заменяет значение для этого ключа, добавляя запись в
поле hstore если ключ еще не существует.
hstore имеет поддержку индексов GiST и GIN для @>,
?, ?& и ?| операторов. Например:
CREATE INDEX hidx ON testhstore USING GIST (h); CREATE INDEX hidx ON testhstore USING GIN (h);
gist_hstore_ops Класс операторов GiST аппроксимирует набор пар «ключ/значение» в виде битовой сигнатуры. Его необязательный целочисленный параметр
siglen определяет длину сигнатуры в байтах. Длина по умолчанию составляет 16 байт.
Допустимые значения длины сигнатуры — от 1 до 2024 байт. Более длинные сигнатуры обеспечивают более точный поиск (сканируется меньшая часть индекса и меньше страниц данных) ценой увеличения размера индекса.
Пример создания такого индекса с длиной сигнатуры 32 байта:
CREATE INDEX hidx ON testhstore USING GIST (h gist_hstore_ops(siglen=32));
hstore также поддерживает btree или hash индексы для = оператора. Это позволяет hstore объявляемых столбцов UNIQUE, либо использовать их в GROUP BY,
ORDER BY или DISTINCT выражениях. Порядок сортировки
для hstore значений не имеет особого смысла, однако такие индексы могут быть полезны для поиска по равенству. Создайте индексы для =
сравнения следующим образом:
CREATE INDEX hidx ON testhstore USING BTREE (h); CREATE INDEX hidx ON testhstore USING HASH (h);
Добавление ключа или обновление значения существующего ключа:
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');
Преобразование запись в тип данных 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 строка)
Преобразование значения hstore в предопределенный запись тип:
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 строка)
Изменение существующей записи с использованием значений из типа данных 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 строка)
Тип данных hstore 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
.................. .
Начиная с версии PostgreSQL 9.0, hstore использует иное внутреннее представление, чем в предыдущих версиях. Это не создает препятствий для обновления путем выгрузки/восстановления (dump/restore), так как текстовое представление (используемое в дампе) осталось неизменным.
В случае бинарного обновления совместимость снизу вверх обеспечивается тем, что новый код распознает данные в старом формате. Это повлечет за собой небольшое снижение производительности при обработке данных, которые еще не были изменены новым кодом. Можно принудительно обновить все значения в столбце таблицы, выполнив инструкцию UPDATE следующим образом:
UPDATE tablename SET hstorecol = hstorecol || '';
Другой способ сделать это:
ALTER TABLE tablename ALTER hstorecol TYPE hstore USING hstorecol || '';
Команда ALTER TABLE требует наличия блокировки таблицы
ACCESS EXCLUSIVE, но не приводит к раздуванию таблицы старыми версиями строк.
Доступны дополнительные расширения, реализующие трансформации hstore для языков PL/Perl и PL/Python. Расширения для PL/Perl называются hstore_plperl
и hstore_plperlu, для доверенной и недоверенной версий PL/Perl.
Если вы установите эти расширения трансформации и укажете их при создании
функции, hstore значения преобразуются в хеш-таблицы Perl. Расширение для PL/Python называется hstore_plpython3u.
Если вы используете его, hstore значения преобразуются в словари Python.
Настоятельно рекомендуется устанавливать расширения трансформации в ту же схему, что и тип данных hstore. В противном случае существуют риски безопасности на этапе установки, если схема расширения трансформации содержит объекты, созданные злоумышленником.
Олег Бартунов <oleg@sai.msu.su>, Москва, МГУ, Россия
Федор Сигаев <teodor@sigaev.ru>, Москва, Delta-Soft Ltd., Россия
Дополнительные улучшения: Эндрю Герт (Andrew Gierth) <andrew@tao11.riddles.org.uk>,
Великобритания