seg. Тип данных для представления отрезков или интервалов чисел с плавающей точкой#

В исходном дистрибутиве установлено по умолчанию: нет.

Связанные компоненты: отсутствуют.

Схема размещения: ext.

Модуль реализует тип данных seg для представления отрезков или интервалов чисел с плавающей точкой. Представление данных в виде интервалов, а не в виде отдельных двух чисел, на практике часто оказывается эффективней, так как снижается риск потери информации на границах числовых типов.

Например, в базу данных вводится значение 6.50. Прочитав это значение из базы, будет получен следующий результат:

SELECT 6.50 :: float8 aAS "pH";
 pH  
-----
 6.5
(1 row)

Разница между 6.50 и 6.5 в некоторых случаях может быть критической. Запись 6.50 на самом деле представляет неточный интервал, содержащийся внутри большего и еще более неточного интервала 6.5.

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

Например:

select '6.25 .. 6.50'::seg as "pH";

Пример результата запроса:

      pH      
--------------
 6.25 .. 6.50
(1 row)

Внешнее представление интервала образуется:

  • одним или двумя числами с плавающей точкой, соединенными оператором диапазона – .. или ....;

  • как центральная точка плюс/минус отклонение;

  • дополнительными индикаторами достоверности, которые игнорируются встроенными операторами <;>;~.

Допустимые представления показаны в таблице. Cимволы x, y и delta обозначают числа с плавающей точкой. Перед значениями x и y может быть добавлен индикатор достоверности:

Представление

Описание

x

Одно значение (интервал нулевой длины)

x .. y

Интервал от x до y

x (+-) delta

Интервал от x - delta до x + delta

x ..

Открытый интервал с нижней границей x

.. x

Открытый интервал с верхней границей x

Допустимое значение

Описание

5.0

Создает сегмент нулевой длины (точка)

~5.0

Создает сегмент нулевой длины и записывает ~ в данные. Знак ~ игнорируется при операциях с seg, но сохраняется как комментарий

<5.0

Создает точку с координатой 5.0; знак < игнорируется, но сохраняется как комментарий

>5.0

Создает точку с координатой 5.0; знак > игнорируется, но сохраняется как комментарий

5(+-)0.3

Создает интервал 4.7 .. 5.3; запись (+-) не сохраняется

50 ..

Все, что больше или равно 50

.. 0

Все, что меньше или равно 0

1.5e-2 .. 2E-2

Создает интервал 0.015 .. 0.02

1 ... 2

То же, что и 1...2/1 .. 2/1..2; пробелы вокруг оператора диапазона игнорируются

Оператор ... часто используется в источниках данных, поэтому он принимается в качестве альтернативного написания оператора ... Это порождает неоднозначность при разборе, поскольку неясно, какая верхняя граница имеется в виду для записи 0...2323 или 0.23. Для разрешения этой неоднозначности во входных числах seg перед десятичной точкой всегда должна быть минимум одна цифра.

seg не принимает интервалы с нижней границей, превышающей верхнюю, например: 5 .. 2.

Значения seg хранятся внутри как пары 32-битных чисел с плавающей точкой. Это значит, что числа с более чем 7 значащими цифрами будут усекаться.

Числа, содержащие 7 и меньше значащих цифр, сохраняют изначальную точность. Если запрос возвращает 0.00, конечные нули отражают точность исходных данных. Количество ведущих нулей не влияет на точность: значение 0.0067 будет считаться имеющим только две значащих цифры.

Модуль seg включает класс операторов индекса GiST для значений seg:

Оператор

Тип

Описание

Пример

seg << seg

boolean

Первый seg полностью находится левее второго?

[a, b] << [c, d]true, если b < c

seg >> seg

boolean

Первый seg полностью находится правее второго?

[a, b] >> [c, d]true, если a > d

seg &< seg

boolean

Первый seg пересекает или левее второго?

[a, b] &< [c, d]true, если b <= d

seg &> seg

boolean

Первый seg пересекает или правее второго?

seg = seg

boolean

Два отрезка seg равны?

seg && seg

boolean

Два отрезка seg пересекаются?

seg @> seg

boolean

Первый seg содержит второй?

seg <@ seg

boolean

Первый seg содержится во втором?

Для типа seg поддерживаются стандартные операторы сравнения, которые сначала сравнивают (a) с ©, и если они равны, сравнивают (b) с (d). Результат сравнения позволяет упорядочить значения подходящим для большинства случаев образом, что полезно для применения ORDER BY с этим типом.

Доработка#

Доработка не проводилась.

Ограничения#

Ограничения отсутствуют.

Установка#

Модуль считается «доверенным», поэтому его могут устанавливать пользователи, имеющие право CREATE в текущей базе данных:

CREATE EXTENSION seg SCHEMA ext;

Настройка#

Настройка не требуется.

Использование модуля#

Примеры использования в регрессионном тесте: https://github.com/LuaDist/libpq/blob/master/contrib/seg/sql/seg.sql

Ссылки на документацию разработчика#

Исходная документация по модулю seg: https://www.postgresql.org/docs/15/seg.html