今天分享一個小型電商系統的數據庫價格字段的數據類型設計。附上通用四舍五入轉換方法
我們知道,價格字段使用的類型,最佳的有兩個,分別為:decimal,money;而money小數部分只能精確到4位,雖然money在內存上是比decimal少那么一個字節,但是現在硬盤那么大,不用計較了。
個人喜歡,我全部直接用decimal(18,5),小數部分我直接用了5位;
但是對於一個商品來說,我最多只會用到兩位小數,百分比也只會用到4位,5位的只能是更小的佣金比例計算。
但我覺得這樣算起來的數,小數實在是太小了,既然針對小型電商來說,我覺得只要兩位就足夠了,
所以我引入了一些概念,
1、針對提現金額的手續費不采用標准的四舍五入,保留兩位小數。
2、針對佣金提成的手續費也不采用標准的四舍五入,保留兩位小數。
3、要用戶交錢的四舍五入,只要第三位小數有值,直接往第二位進1,目的就是要用戶多交錢。
3、要商家交錢的四舍五入,不管第三位小數是否有值,都不進1,目的是要商家少交錢。
好了,有了這些基礎后,我直接整個數據庫設計保存的價格值佣金值都采用保留兩位小數進行保存,雖然使用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)); } }
后話,如果我這里有什么是錯的,歡迎大家指正。
