Как лучше всего представить рациональные числа в SQL Server?

Я работаю с данными, которыми исходно снабжают как рациональные числа. У меня есть гладкий универсальный класс C#, который красиво представляет эти данные в C# и позволяет преобразование во многие другие формы. К сожалению, когда я оборачиваюсь и хочу сохранить это в SQL, у меня есть пара решений в памяти, но ни один из них не очень удовлетворяет.

Вот пример. У меня есть необработанное значение 2/3 который мой new Rational(2, 3) легко дескрипторы в C#. Опции, о которых я думал для хранения этого в базе данных, следующие:

  1. Так же, как десятичное число/плавающая точка, т.е. значение = 0.66666667 из различной точности и точности. Профессионалы: это позволяет мне запрашивать данные, например, находить значения <1. Недостатки: это имеет потерю точности, и это ужасно, когда я иду для отображения этого простого значения назад в UI.

  2. Хранилище как два точных целочисленных поля, например, числитель = 2, знаменатель = 3 из различной точности и точности. Профессионалы: Это позволяет мне точно представить исходное значение и отобразить его в его самой простой форме позже. Недостатки: у Меня теперь есть два поля для представления этого значения, и запросы теперь сложный/меньшее количество эффективные, поскольку каждый запрос должен выполнить арифметику, например, найти числитель / знаменатель <1.

  3. Сериализируйте как строковые данные, т.е. "2/3". Я смог бы знать макс. длину строки и иметь varchar, который мог содержать это. Профессионалы: я вернулся к одному полю, но с точным представлением. Недостатки: запросы в значительной степени арестованы, и оплатите стоимость сериализации.

  4. Комбинация № 1 и № 2. Профессионалы: легко/эффективно запрос для диапазонов значений, и имеет точные значения в UI. Недостатки: три поля (!?!) для содержания одной части данных, должен сохранить несколько представлений в синхронизации, которая повреждает D.R.Y.

  5. Комбинация № 1 и № 3. Профессионалы: легко/эффективно запрос для диапазонов значений, и имеет точные значения в UI. Недостатки: отступите к двум полям для содержания данных части, должен сохранить несколько представлений в синхронизации, которая повреждает D.R.Y., и должен оплатить дополнительные издержки сериализации.

У кого-либо есть другое out-of-the-box решение, которое лучше, чем они? Есть ли другие вещи, которые я не рассматриваю? Существует ли относительно простой способ сделать это в SQL, о котором я просто не знаю?

5
задан CharlesB 21 April 2013 в 17:12
поделиться

5 ответов

Я бы, вероятно, выбрал вариант №4, но использовал вычисляемый столбец для третьего столбца, чтобы избежать проблем с синхронизацией / СУХОЙ (а также означает, что на самом деле вы храните только 2 столбца, избегая "трех" поля "проблема).

В SQL-сервере вычисляемый столбец определяется следующим образом:

CREATE TABLE dbo.Whatever(
   Numerator INT NOT NULL,
   Denominator INT NOT NULL,
   Value AS (Numerator / Denominator) PERSISTED
)

(обратите внимание, что вам может потребоваться преобразование типов и проверка того, что знаменатель не равен нулю и т. д.).

Кроме того, SQL 2005 добавлен вычисляемый столбец PERSISTED, который избавлялся от вычислений во время запроса.

6
ответ дан 18 December 2019 в 10:45
поделиться

Если вы используете SQL Server 2005 или 2008, у вас есть возможность определить свои собственные типы данных CLR :

Начиная с SQL Server 2005, вы может использовать определяемые пользователем типы (UDT) для расширить систему скалярных типов сервер, позволяющий хранить CLR объекты в базе данных SQL Server. UDT может содержать несколько элементов и может иметь поведение, различая его из традиционных типов данных псевдонимов которые состоят из одного SQL Server системный тип данных.

Поскольку доступ к UDT осуществляется систему в целом, их использование для сложные типы данных могут отрицательно влияние на производительность. Сложные данные обычно лучше всего моделируется с использованием традиционные строки и таблицы. UDT в SQL Server хорошо подходит для следующее:

  • Дата, время, валюта и расширенные числовые типы
  • Геопространственные приложения
  • Закодированные или зашифрованные данные

Если вы можете жить с ограничениями, я не могу представить лучшего способа данные карты, которые вы уже записываете в специальном классе.

8
ответ дан 18 December 2019 в 10:45
поделиться

Какая точность вам нужна?

Язык, C # или другой, округляет 2/3 в заданной позиции точности. Если для того, над чем вы работаете, допустимо использовать десятичные значения, скажем, в научном представлении 10, тогда установите точность в db.

Если точность действительно вызывает беспокойство, тогда разделите числитель и знаменатель. Это гарантирует, что у вас всегда будет доступ к любой точности, которую вы хотите, и вы можете использовать вычисляемый столбец для представления значения для быстрой фильтрации:

numerator INT,
denominator INT,
result AS CASE WHEN denominator > 0 THEN numerator / denominator ELSE NULL END
2
ответ дан 18 December 2019 в 10:45
поделиться

Я немного поэкспериментировал с использованием геометрического типа данных в SQL Server 2008 для хранения рациональных чисел и управления ими. По сути, я предполагаю, что числитель помещается в слот X, а знаменатель - в слот Y фиктивной геометрической точки.

Это было хорошо для моих нужд, но могло быть бесполезно для ваших. Это будет зависеть от ваших приоритетов (производительность, читаемость кода и т. Д.). Я лично обнаружил, что T-SQL для обработки геометрических данных трудно писать и читать.

0
ответ дан 18 December 2019 в 10:45
поделиться

Насколько точно вы смотрите? double / float обеспечивают приличную точность (на мой взгляд). Я почти уверен, что научным / астрономическим данным требуется гораздо больше точности. Я знаю, что библиотеки вроде Matlab и mathematica хороши в этом. Я обнаружил, что вы можете использовать математику со своей программой .net. Вот ссылка

Изменить: добавление дополнительных ссылок и цитат

«Когда система Mathematica работает с рациональными числами, она дает точный результат независимо от того, сколько цифр требуется» из здесь

Другой хорошее чтение , но я думаю, вам придется его реализовать

0
ответ дан 18 December 2019 в 10:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: