F.21. hstore — hstore ключ/значение тип данных#
F.21. hstore — hstore ключ/значение тип данных #
Этот модуль реализует тип данных hstore для хранения наборов пар ключ/значение внутри одного значения Tantor SE. Это может быть полезно в различных сценариях, таких как строки с большим количеством атрибутов, которые редко проверяются, или полуструктурированные данные. Ключи и значения представляют собой простые текстовые строки.
Этот модуль считается "доверенным", то есть его можно установить
недоступным пользователям, у которых есть привилегия CREATE
в текущей базе данных.
F.21.1. hstore Внешнее представление #
Текстовое представление типа hstore, используемое для ввода и вывода,
включает ноль или более пар key =>
value, разделенных запятыми. Некоторые примеры:
k => v foo => bar, baz => whatever "1-a" => "anything at all"
Порядок пар не имеет значения (и может не быть воспроизведен при выводе). Пробелы между парами или вокруг знака => игнорируются. Ключи и значения, содержащие пробелы, запятые, = или >, должны быть заключены в двойные кавычки. Чтобы включить двойную кавычку или обратную косую черту в ключ или значение, нужно экранировать их обратной косой чертой.
Каждый ключ в hstore является уникальным. Если вы объявляете hstore с повторяющимися ключами, только один будет сохранен в hstore, и нет гарантии, какой будет сохранен:
SELECT 'a=>1,a=>2'::hstore; hstore ---------- "a"=>"1"
Значение (но не ключ) может быть SQL-NULL. Например:
key => NULL
Ключевое слово NULL нечувствительно к регистру. Для обработки его как обычной строки “NULL” используйте двойные кавычки.
Примечание
Учтите, что формат текста hstore, используемый для ввода, применяется до любого необходимого цитирования или экранирования. Если вы передаете литерал hstore через параметр, то дополнительная обработка не требуется. Но если вы передаете его как литерал в кавычках, то символы апострофа и (в зависимости от значения параметра конфигурации standard_conforming_strings) символы обратной косой черты должны быть корректно экранированы. См. Раздел 4.1.2.1 для получения дополнительной информации о работе со строковыми константами.
На выходе двойные кавычки всегда окружают ключи и значения, даже когда это не строго необходимо.
F.21.2. hstore Операторы и функции #
Операторы, предоставляемые модулем hstore, показаны в таблице Таблица F.7, функции - в таблице Таблица F.8.
Таблица F.7. hstore Операторы
Оператор Описание Пример(ы) |
|---|
Возвращает значение, связанное с заданным ключом, или
|
Возвращает значения, связанные с заданными ключами, или
|
Соединяет два
|
Содержит ли
|
Содержит ли
|
Содержит ли
|
Содержит ли левый операнд правый?
|
Содержится ли левый операнд в правом?
|
Удаляет ключ из левого операнда.
|
Удаляет ключи из левого операнда.
|
Удаляет пары из левого операнда, которые соответствуют парам в правом операнде.
|
Заменяет поля в левом операнде (который должен быть составным типом)
соответствующими значениями из
|
Преобразует
|
Преобразует
|
Таблица F.8. 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 row)
Подстрочный запрос возвращает NULL, если подстрока равна NULL или ключ не существует в hstore. (Таким образом, подстрочный запрос не сильно отличается от оператора ->). Подстрочное обновление завершается неудачей, если подстрока равна NULL; в противном случае оно заменяет значение для этого ключа, добавляя запись в hstore, если ключ еще не существует.
F.21.3. Индексы #
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);
F.21.4. Примеры #
Добавить ключ или обновить существующий ключ новым значением:
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 row)
Преобразование типа hstore в предопределенный тип record:
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 row)
Изменить существующую запись, используя значения из 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 row)
F.21.5. Статистика #
Тип 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
...................
F.21.6. Совместимость #
Согласно 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 блокировку на таблице, но не приводит к раздутию таблицы старыми версиями строк.
F.21.7. Преобразования #
Дополнительные расширения доступны, которые реализуют преобразования для типа hstore для языков PL/Perl и PL/Python. Расширения для PL/Perl называются hstore_plperl и hstore_plperlu для доверенного и недоверенного PL/Perl соответственно. Если вы установите эти преобразования и укажете их при создании функции, значения hstore будут отображаться на хеши Perl. Расширение для PL/Python называется hstore_plpython3u. Если вы его используете, значения hstore будут отображаться на словари Python.
Предостережение
Сильно рекомендуется установить расширения преобразования в ту же схему, что и hstore. В противном случае, при установке могут возникнуть проблемы с безопасностью, если схема расширения преобразования содержит объекты, определенные враждебным пользователем.
F.21.8. Авторы #
Олег Бартунов <oleg@sai.msu.su>, Москва, Московский университет, Россия
Teodor Sigaev <teodor@sigaev.ru>, Moscow, Delta-Soft Ltd.,Russia
Дополнительные улучшения от Andrew Gierth <andrew@tao11.riddles.org.uk>,
Великобритания