F.20. hstore — hstore ключ/значение тип данных#
F.20. hstore — hstore ключ/значение тип данных #
Этот модуль реализует тип данных hstore
для хранения наборов пар ключ/значение внутри одного значения Tantor SE. Это может быть полезно в различных сценариях, таких как строки с большим количеством атрибутов, которые редко проверяются, или полуструктурированные данные. Ключи и значения представляют собой простые текстовые строки.
Этот модуль считается "доверенным", то есть его можно установить
недоступным пользователям, у которых есть привилегия CREATE
в текущей базе данных.
F.20.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.20.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.20.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.20.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.20.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.20.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.20.7. Преобразования #
Дополнительные расширения доступны, которые реализуют преобразования для типа hstore
для языков PL/Perl и PL/Python. Расширения для PL/Perl называются hstore_plperl
и hstore_plperlu
для доверенного и недоверенного PL/Perl соответственно. Если вы установите эти преобразования и укажете их при создании функции, значения hstore
будут отображаться на хеши Perl. Расширение для PL/Python называется hstore_plpython3u
. Если вы его используете, значения hstore
будут отображаться на словари Python.
Предостережение
Сильно рекомендуется установить расширения преобразования в ту же схему, что и hstore
. В противном случае, при установке могут возникнуть проблемы с безопасностью, если схема расширения преобразования содержит объекты, определенные враждебным пользователем.
F.20.8. Авторы #
Олег Бартунов <oleg@sai.msu.su>
, Москва, Московский университет, Россия
Teodor Sigaev <teodor@sigaev.ru>
, Moscow, Delta-Soft Ltd.,Russia
Дополнительные улучшения от Andrew Gierth <andrew@tao11.riddles.org.uk>
,
Великобритания