Я унаследовал большую (SQLServer) базу данных с сотнями столбцов, которые представляют суммы той или иной вещи. Единицы для этих значений (например, «галлоны», «дюймы» и т. Д.) Хранятся в поле MS_Description расширенных свойств. Мне интересно, есть ли лучший способ хранить эту информацию. Я предполагаю, что это хорошо для целей документирования, но было бы трудно сделать надежные вычисления преобразования единиц на основе этих данных. На данный момент я не готов внести инвазивные изменения, но если у меня появится возможность сделать это, какова рекомендуемая наилучшая практика в этом отношении? Варианты, в верхней части моей головы, могут включать в себя:
- Измените имя столбца на включенные единицы (например, «TotalVolumeInGallons». Это сделает информацию немного более доступной, но она все еще кажется мне слабой.)
- Добавьте отдельный столбец «Units», чтобы соответствовать каждому столбцу «Amount» (этот столбец может быть nvarchar ИЛИ это может быть внешний ключ к отдельной таблице Units, что может упростить вычисление конверсий единиц. С другой стороны, добавление так многие столбцы могут удвоить размер моей базы данных - с ужасно избыточными данными.)
- Создайте новое поле в Extended Properties, предназначенное специально для юнитов. (К сожалению, я не думаю, что это может быть внешним ключом таблицы Units.)
- Есть другая идея, которую я пропускаю?
ОБНОВЛЕНИЕ: после прочтения ответа @Todd Everett мне пришло в голову возможное решение, так что я собираюсь продолжить и ответить на мой собственный вопрос. (Увидеть ниже)
Ответы:
Поскольку вы упоминаете сотни столбцов, я бы рассмотрел дизайн EAV . Хотя Джо Селко предупреждает об этом , я думаю, что это может быть применимо в вашем случае использования. Похоже, что все ваши «суммы» являются числами, так что вы избежите проблем с приведением, которые описывает Джо, и необходимости превращать каждое «значение» в строку. Это будет работать даже лучше, если все суммы являются целыми числами, но может также работать, если некоторые являются десятичными. Учитывая единицы измерения, вы можете пойти еще дальше и реализовать модель стиля «универсальная модель данных», основанную на этой статье Дэвида Хэя, а также изложенную в его книге « Шаблоны моделей данных: условные обозначения»., Эта модель обладает дополнительным преимуществом настройки того, какие «суммы» применяются к каким «вещам», если вам это нужно. Один дополнительный шаг, показанный в книге на стр. 162, - это таблица преобразования единиц измерения, которую можно использовать для преобразования между различными единицами измерения. Вот пример:
Это говорит о том, что для преобразования из килограмма в фунт сначала нужно умножить килограмм на 2,2. Существует также константа, если преобразование должно также включать постоянное значение и возможность создавать несколько шагов. Таким образом, при преобразовании, скажем, в градусы Цельсия в градусы Фаренгейта вы умножаете градусы Цельсия на 1,8, а затем добавляете 32. Ключом будет значение от UOM, до UOM и шаг вычисления.
Это мои 2 цента. Я надеюсь, что эти ссылки дадут вам хорошую пищу для размышлений, если у вас когда-нибудь появится возможность перезагрузить текущий дизайн.
источник
Все работают.
Обратите внимание, что во втором случае вы не можете добавлять яблоки и апельсины, и поэтому данные исключительно легко могут быть неправильно истолкованы.
Также обратите внимание, что преобразования не могут быть очень безопасными и подвержены ошибкам округления, переполнениям и т. Д.
Кроме того, существуют физические проблемы, такие как удельный вес и температура. Преобразование 20 галлонов воды в фунты потребует, чтобы вы знали плотность воды. Но плотность воды меняется в зависимости от температуры, поэтому вам может понадобиться либо узнать плотность одновременно с измерением, либо температуру аналогичным образом и использовать поправочный коэффициент объема.
В случае расширенных свойств это хорошо только для документации - хорошее имя столбца лучше для документации. Проблема с колонкой, подразумеваемой как находящаяся в фиксированной единице по имени, состоит в том, что вы в конечном итоге ставите себя в угол, когда меняете единицы измерения - новый клиент хочет масло в бочках, а не в галлонах - и это было бы хорошо, поскольку его данные находятся в его собственная база данных, но имя столбца в настоящее время вводит в заблуждение.
Другой вариант - хранить канонические версии в фиксированных единицах (то есть всегда в килограммах и метрах) в дополнение к различным исходным измерениям. Агрегатные операции с фиксированными единицами должны быть в порядке (за исключением того, что вы не добавите температуры, например), но вы не потеряете исходное измерение.
источник
Простое решение, которое хорошо работало для меня в прошлом, - хранить все ваши данные в «базовых» единицах. Например, ваша базовая единица измерения длины может составлять миллиметры, а базовая единица измерения веса - килограммы. Это решение может привести к необходимости преобразования некоторых существующих данных в базовый блок, если это еще не сделано.
Когда у вас есть все данные в стандартных базовых единицах, нет необходимости хранить единицу в самой базе данных, поскольку теперь это общесистемное предположение. Отображаемые единицы измерения, требуемые для каждого типа единиц (например, отображать ли длину в мм, дюймах, см, м), становятся проблемой приложения / клиентского домена, которую можно сохранить в локальном хранилище.
Таблицы преобразования единиц для преобразования между различными поддерживаемыми единицами могут быть жестко заданы в вашем приложении, поскольку новые единицы измерения изменяются крайне редко.
Обратите внимание, что решение, связанное с другой проблемой, заключается в том, что при хранении меток времени в базе данных их всегда нужно хранить в базовом блоке - UTC .
Еще один вопрос и ответ по теме ...
/programming/12977021/best-practice-for-storing-weights-in-a-sql-database
Здесь содержится некоторая полезная информация о том, почему использование типа столбца с плавающей запятой является наилучшим способом хранения реальных измерений.
источник
Поскольку любая единица может быть преобразована в другую единицу того же типа с помощью формулы:
Я хотел бы создать таблицу, которая содержит типы единиц плюс эти 4 значения.
После добавления всех измерений, которые вы, вероятно, хотите конвертировать, по обе стороны от списка, запустите запрос, в который вы вставляете обратную операцию, просто отменяя смещения и меняя множитель и знаменатель, а также на единицу измерения и единицу измерения.
Чтобы добавить преобразование между всеми типами, перекрестное соединение с некоторыми фильтрами может вставить остальные преобразования.
источник
После прочтения ответа @Todd Everett мне пришло решение, так что я собираюсь ответить и на свой вопрос. То , что я думаю , что я собираюсь сделать , это создать отдельную
ColumnUnits
таблицу с четырьмя столбцами:Schema
,Table
,Column
,UnitsID
(где UnitsID является FK в отдельнуюUnitsOfMeasure
таблицу), таким образом , отображение любого заданного столбца в связанной с ним единицы измерения. Очевидно, что самым большим недостатком этой идеи является то, что разработчики должны помнить, чтобы редактировать эту таблицу всякий раз, когда они переименовывают столбец или таблицу [ возможно, использовать триггер DDL ? ], иначе система сломается, Но если предположить, что такие переименования редки, а уровень разработки небольшой (в моем случае всего один человек), эта архитектура должна быть работоспособной. Преимущество состоит в том, что в текущую БД не нужно вносить инвазивные изменения, и мне нужно хранить значение только один раз для каждого столбца, а не один раз для строки, как того требует мой второй вариант в моем исходном сообщении.источник