今天分享一個小型電商系統的數據庫價格字段的數據類型設計。附上通用四捨五入轉換方法數據庫
咱們知道,價格字段使用的類型,最佳的有兩個,分別爲:decimal,money;而money小數部分只能精確到4位,雖然money在內存上是比decimal少那麼一個字節,可是如今硬盤那麼大,不用計較了。數據庫設計
我的喜歡,我所有直接用decimal(18,5),小數部分我直接用了5位;spa
可是對於一個商品來講,我最多隻會用到兩位小數,百分比也只會用到4位,5位的只能是更小的佣金比例計算。設計
但我以爲這樣算起來的數,小數實在是過小了,既然針對小型電商來講,我以爲只要兩位就足夠了,code
因此我引入了一些概念,orm
一、針對提現金額的手續費不採用標準的四捨五入,保留兩位小數。blog
二、針對佣金提成的手續費也不採用標準的四捨五入,保留兩位小數。內存
三、要用戶交錢的四捨五入,只要第三位小數有值,直接往第二位進1,目的就是要用戶多交錢。ci
三、要商家交錢的四捨五入,無論第三位小數是否有值,都不進1,目的是要商家少交錢。string
好了,有了這些基礎後,我直接整個數據庫設計保存的價格值佣金值都採用保留兩位小數進行保存,雖然使用decimal(18,5)會有3個多餘的0,這裏我直接用一個方法進行切割,反正是沒值的。
而對於百分比的,直接不變,都是採用五位小數。
下面我提供我換算的方法:
/// <summary> /// 四捨五入計算類 /// </summary> public class Round { /// <summary> /// 標準切割,結果保留兩位小數 /// 不計算四捨五入 /// </summary> public static decimal Standard(string money) { return decimal.Parse((Math.Truncate(decimal.Parse(money) * 100) / 100.00M).ToString("0.00")); } /// <summary> /// 標準四捨五入,結果保留兩位小數 /// </summary> public static decimal RoundForStandard(string money) { return Standard(Math.Round(decimal.Parse(money), 2, MidpointRounding.AwayFromZero).ToString()); } /// <summary> /// 針對用戶的四捨五入,結果保留兩位小數 /// 要用戶交錢的四捨五入,目的就是要用戶多交錢 /// </summary> public static decimal RoundForUser(string money) { if ((decimal.Parse(money) * 100) > (Math.Truncate(decimal.Parse(money) * 100))) //看下小數點第三位是否有數 { //有的時候,直接進1 return Standard((decimal.Parse(money) + 0.01M).ToString()); } else { return Standard(money); } } /// <summary> /// 針對商家的四捨五入,結果保留兩位小數 /// 要商家交錢的四捨五入,目的是要商家少交錢 /// </summary> public static decimal RoundForMerchant(string money) { return Standard(money); } /// <summary> /// 固定點的轉換,可將小數後面多餘的零去掉 /// 這個不固定保留多少位小數 /// </summary> public static decimal Fixed(string money) { return decimal.Parse(string.Format("{0:G}", money)); } }
後話,若是我這裏有什麼是錯的,歡迎你們指正。