簡體   English   中英

我應該如何向用戶顯示一個費用字段,並將其存儲在數據庫中?

[英]How should I present a cost field to the user, and store it in the database?

現在,我有兩個成本領域。 一美元,一美分。 這行得通,但是有點難看。 它還不允許用戶根據需要輸入術語“免費”或“免費”。 但是,如果我只有一個字段,則可能必須使解析器更加智能。 你怎么看?

在服務器端,我將美元和美分結合起來以小數形式存儲在數據庫中。 主要是為了使我可以快速收集統計信息(平均費用等)。

您認為將成本存儲為字符串更好嗎? 然后,無論何時我將成本實際用於統計或其他目的,都將在那一刻將其轉換為小數。 還是我步入正軌?

數據庫設計中有一條規則規定“原子數據”不應拆分。 根據此規則,價格或成本就是原子數據的示例,因此,永遠不要將其拆分為多列,就像您不應將電話號碼拆分為多列一樣(除非您確實有很好的理由-極少)

使用DECIMAL數據類型。 像DECIMAL(8,3)這樣的東西應該可以工作,並且所有符合ANSI SQL的數據庫產品都支持它!

您可以查閱Joe Celko的“思維定型書中有關此主題的討論。 請參閱第1.6.2節,第21-22頁

編輯 -從您的問題看來,您還擔心如何以類似於價格(xxxx.xx)的形式接受用戶輸入-因此有兩個輸入框,代表整個美元和便士。

我建議使用單個輸入框,然后使用正則表達式進行輸入驗證以匹配您的格式(例如[0-9] +(。[0-9] {1,3}))可能會起作用,但可以改進)。 然后,您可以使用您的語言將經過驗證的字符串解析為Decimal類型,或者僅將其作為字符串傳遞給數據庫-SQL將知道如何將其轉換為DECIMAL類型。

將總成本保持為小數。 如果是免費的,則將成本保持為0。在演示中,如果成本為零,請寫成“免費”而不是0。

我通常將成本存儲為最低單位(便士),然后將其轉換為整美元。

因此,將4.50美元的成本存儲為450。免費商品將為-1便士。 您也可以將免費商品存儲為0便士,這使您可以靈活地使用0和-1來表示兩個稍有不同的商品(免費還是不出售?)。

如果您選擇沿途使用美分,也可以更輕松地支持不使用美分的國家。


至於顯示數據輸入字段,我個人不喜歡它,因為我不得不為微小的事情保持切換狀態(例如當他們將電話號碼分為3個字段,或者將IP地址分為4個字段時)。 我將顯示一個字段,然后讓用戶自己輸入小數點。 這樣,您的用戶就不必跳至下一個字段(如果不熟悉此選項卡,也可以單擊)。

使用美分,使用450的價格為$ 4.50,這將為您節省因浮點操作不安全而經常引起的問題。 只需在irb中嘗試以下表達式:0.4-0.3 == 0.1將返回false。 都是因為浮點表示不准確。

在我的模型中,我一直使用:

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中的表示沒有太多經驗(可以是浮點數,如我一開始所顯示的那樣是有問題的)。

不允許垃圾進入您的數據庫。 如果您期望某個字段上有美元,那么在進入該字段之前,請確保它是有效的。 這將使您可以更好地報告數據,並可以簡化輸出格式。

我建議將此字段設為對更新或插入進行驗證的單個字段。

if field != SpecialFreeTag then

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

使用try解析或正則表達式可以幫助進行驗證。

我將成本存儲為小數位數,其比例應不小於2,甚至是3-5。 如果大量購買某物,則單位成本很容易包含零點幾分。 免費商品的成本為0。如果成本未知,則還允許使用空值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM