F.51. seg — тип данных для отрезков или интервалов с плавающей запятой#
F.51. seg — тип данных для отрезков или интервалов с плавающей запятой #
Этот модуль реализует тип данных seg
для представления отрезков прямых или интервалов с плавающей запятой. seg
может представлять неопределенность в конечных точках интервала, что особенно полезно для представления лабораторных измерений.
Этот модуль считается "доверенным", то есть его можно установить
недоступным пользователям, у которых есть привилегия CREATE
в текущей базе данных.
F.51.1. Обоснование #
Геометрия измерений обычно более сложна, чем геометрия точки на числовом континууме. Измерение обычно представляет собой сегмент этого континуума с нечеткими границами. Измерения представляются в виде интервалов из-за неопределенности и случайности, а также потому, что значение, которое измеряется, может естественным образом быть интервалом, указывающим на какое-то состояние, например, диапазон температурной стабильности белка.
Используя только здравый смысл, кажется более удобным хранить такие данные в виде интервалов, а не пар чисел. На практике это даже оказывается более эффективным в большинстве приложений.
Далее, в рамках здравого смысла, нечеткость границы подразумевает, что использование традиционных числовых типов данных приводит к потере определенной информации. Представьте себе следующую ситуацию: ваш инструмент показывает значение 6.50, и вы вводите это значение в базу данных. Что вы получите при его извлечении? Посмотрим:
test=> select 6.50 :: float8 as "pH"; pH --- 6.5 (1 row)
В мире измерений, 6.50 не равно 6.5. Иногда это может быть критически важным. Экспериментаторы обычно записывают (и публикуют) цифры, которым они доверяют. 6.50 на самом деле является нечетким интервалом, содержащимся в более крупном и еще более нечетком интервале, 6.5, с их центральными точками, вероятно, единственным общим признаком, который они имеют. Мы определенно не хотим, чтобы такие разные элементы данных выглядели одинаково.
Вывод? Приятно иметь специальный тип данных, который может записывать пределы интервала с произвольной переменной точностью. Переменная в смысле, что каждый элемент данных записывает свою собственную точность.
Проверьте это:
test=> select '6.25 .. 6.50'::seg as "pH"; pH ------------ 6.25 .. 6.50 (1 row)
F.51.2. Синтаксис #
Внешнее представление интервала формируется с использованием одного или двух чисел с плавающей точкой, соединенных оператором диапазона (..
или ...
). Кроме того, его можно указать как центральную точку плюс или минус отклонение. Дополнительные индикаторы уверенности (<
, >
или ~
) также могут быть сохранены. (Однако все встроенные операторы игнорируют индикаторы уверенности). Таблица F.29 дает обзор допустимых представлений; Таблица F.30 показывает некоторые примеры.
В Таблица F.29, x
, y
и
delta
обозначают
числа с плавающей точкой. x
и y
, но
не delta
, могут предшествовать индикатору уверенности.
Таблица F.29. seg
Внешние представления
| Одиночное значение (интервал нулевой длины) |
| Интервал от x до y
|
| Интервал от x - delta до
x + delta
|
| Открытый интервал с нижней границей x
|
.. | Открытый интервал с верхней границей x
|
Таблица F.30. Примеры допустимого ввода для seg
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...23
равной 23
или 0.23
.
Это разрешается требованием наличия хотя бы одной цифры перед десятичной
точкой во всех числах ввода типа seg
.
В качестве проверки на здравый смысл, seg
отклоняет интервалы, у которых нижняя граница больше верхней, например 5 .. 2
.
F.51.3. Точность #
seg
значения хранятся внутренне в виде пар 32-битных чисел с плавающей точкой. Это означает, что числа с более чем 7 значащими цифрами будут усечены.
Все числа с 7 или менее значащими цифрами сохраняют свою исходную точность. То есть, если ваш запрос возвращает 0.00, вы можете быть уверены, что конечные нули не являются результатом форматирования: они отражают точность исходных данных. Количество ведущих нулей не влияет на точность: значение 0.0067 считается имеющим всего 2 значащие цифры.
F.51.4. Использование #
Модуль seg
включает класс операторов индекса GiST для значений seg
.
Поддерживаемые операторы класса операторов GiST показаны в Таблица F.31.
Таблица F.31. Операторы Seg GiST
Оператор Описание |
---|
Является ли первый |
Является ли первый |
Не простирается ли первый |
Не распространяется ли первый |
Являются ли два |
Совпадают ли два |
Содержит ли первый |
Содержится ли первый |
В дополнение к вышеуказанным операторам, для типа seg
доступны обычные операторы сравнения, показанные в Таблица 9.1. Эти операторы сначала сравнивают (a) с (c), и если они равны, сравнивают (b) с (d). Это обеспечивает достаточно хорошую сортировку в большинстве случаев, что полезно при использовании ORDER BY с этим типом.
F.51.5. Примечания #
Для примеров использования смотрите тест на регрессию sql/seg.sql
.
Механизм, который преобразует (+-)
в обычные диапазоны, не является полностью точным при определении количества значащих цифр для границ. Например, он добавляет дополнительную цифру к нижней границе, если полученный интервал включает степень десяти.
postgres=> select '10(+-)1'::seg as seg; seg --------- 9.0 .. 11 -- should be: 9 .. 11
Производительность индекса R-дерева в значительной степени зависит от начального порядка входных значений. Очень полезно отсортировать входную таблицу по столбцу seg
; см. скрипт sort-segments.pl
для примера.
F.51.6. Заслуги #
Оригинальный автор: Ген Селков, мл. <selkovjr@mcs.anl.gov>
,
Отделение математики и компьютерных наук, Национальная лаборатория Аргонн.
Мои благодарности в первую очередь идут профессору Джо Хеллерштейну (https://dsf.berkeley.edu/jmh/) за ясное изложение сути GiST (http://gist.cs.berkeley.edu/). Я также благодарен всем разработчикам Postgres, настоящим и прошлым, за то, что позволили мне создать свой собственный мир и жить в нем непрерывно. И я хотел бы выразить свою благодарность Лаборатории Аргонн и Министерству энергетики США за годы верной поддержки моих исследований в области баз данных.