Как мне представить поле стоимости пользователю и сохранить его в базе данных? - PullRequest
1 голос
/ 29 апреля 2009

Прямо сейчас у меня есть два поля для стоимости. Один за доллары и один за центы. Это работает, но это немного некрасиво. Это также не позволяет пользователю вводить термин «бесплатно» или «бесплатно», если он хочет. Но если у меня есть только одно поле, мне, возможно, придется сделать свой парсер немного умнее. Что ты думаешь?

На стороне сервера я объединяю доллары и центы, чтобы хранить их как десятичные числа в моей базе данных. Главным образом, чтобы я мог быстро собрать статистику (средние затраты и т. Д.).

Как вы думаете, лучше хранить стоимость в виде строки? Тогда всякий раз, когда я фактически использую стоимость для статистики или других целей, я конвертирую ее в десятичную точку в этой точке. Или я на правильном пути?

Ответы [ 6 ]

8 голосов
/ 29 апреля 2009

В проекте базы данных есть правило, согласно которому «атомарные данные» не следует разбивать. По этому правилу цена или стоимость являются таким примером элементарных данных, и поэтому их никогда не следует разбивать на несколько столбцов, точно так же, как вам не следует разбивать телефонный номер на несколько столбцов (если только у вас нет для этого веской причины - очень редко)

Используйте тип данных DECIMAL. Должно работать что-то вроде DECIMAL (8,3), и оно поддерживается всеми продуктами баз данных, совместимыми с ANSI SQL!

Вы можете обратиться к книге "Мышление в наборах" Джо Селко для обсуждения этой темы. См. раздел 1.6.2, стр. 21-22 .

РЕДАКТИРОВАТЬ - Из вашего вопроса видно, что вы также обеспокоены тем, как принять ввод пользователя в форме, похожей на цену (xxxx.xx) - отсюда два поля ввода, для целых долларов и пенни.

Я рекомендую использовать одно поле ввода, а затем выполнить проверку ввода с использованием регулярных выражений для соответствия вашему формату (например, что-то вроде [0-9] + (. [0-9] {1,3} )? , вероятно, будет работать, но может быть улучшено). Затем вы можете проанализировать проверенную строку в десятичном типе на вашем языке или просто передать ее в виде строки в базу данных - SQL будет знать, как преобразовать ее в тип DECIMAL.

4 голосов
/ 29 апреля 2009

Сохраняйте всю стоимость как десятичную. Если это бесплатно, тогда оставьте стоимость равной 0. В представлении, если стоимость равна нулю, напишите «бесплатно» вместо 0.

2 голосов
/ 30 апреля 2009

Используйте центы, используйте 450 за $ 4,50, это избавит вас от проблем, которые возникают очень часто от того, что операции с плавающей запятой небезопасны. Просто попробуйте следующее выражение в irb: 0,4 - 0,3 == 0,1 вернет false. Все из-за представления с плавающей точкой innacuracies.

В моих моделях я всегда использую:

attr_accessor :price_with_cents
def price_with_cents
  self.price/100.00
end

def price\_with\_cents==(num)
  self.price = (num.to_f * 100.00).to_i
end

И имя столбца просто цена и целое число тип.

У меня нет большого опыта работы с десятичными столбцами и их представлением в ruby ​​(что может быть плавающим, что проблематично, как я показал в начале).

2 голосов
/ 29 апреля 2009

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

Таким образом, стоимость $ 4,50 сохраняется как 450. Бесплатные вещи будут -1 копейка. Вы также можете хранить бесплатные вещи как 0 копеек, что дает вам возможность использовать 0 и -1 для обозначения двух немного разных вещей (бесплатно против продажи?).

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


Что касается представления поля ввода данных, мне лично не нравится, когда мне приходится переключать поля для крошечных вещей (например, когда они разбивают телефонные номера на 3 поля или IP-адреса на 4). Я бы представил одно поле и позволил бы пользователям вводить десятичную точку в себя. Таким образом, ваши пользователи не должны вкладывать (или щелкать, если они не знакомы с вкладкой) следующее поле.

0 голосов
/ 29 апреля 2009

Я бы сохранил стоимость как десятичную с масштабом не менее 2 и, возможно, даже 3-5. Если что-то купить оптом, стоимость единицы может легко включать доли цента. Стоимость бесплатных предметов равна 0. Если стоимость неизвестна, допустимы также нулевые значения.

0 голосов
/ 29 апреля 2009

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

Я предлагаю сделать это единственное поле с проверкой при обновлении или вставке.

if field != SpecialFreeTag then

  try to convert to decimal
    if fail then report to user
    otherwise accept value

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...