今天分享一个小型电商系统的数据库价格字段的数据类型设计。附上通用四舍五入转换方法
我们知道,价格字段使用的类型,最佳的有两个,分别为:decimal,money;而money小数部分只能精确到4位,虽然money在内存上是比decimal少那么一个字节,但是现在硬盘那么大,不用计较了。
个人喜欢,我全部直接用decimal(18,5),小数部分我直接用了5位;
但是对于一个商品来说,我最多只会用到两位小数,百分比也只会用到4位,5位的只能是更小的佣金比例计算。
但我觉得这样算起来的数,小数实在是太小了,既然针对小型电商来说,我觉得只要两位就足够了,
所以我引入了一些概念,
1、针对提现金额的手续费不采用标准的四舍五入,保留两位小数。
2、针对佣金提成的手续费也不采用标准的四舍五入,保留两位小数。
3、要用户交钱的四舍五入,只要第三位小数有值,直接往第二位进1,目的就是要用户多交钱。
3、要商家交钱的四舍五入,不管第三位小数是否有值,都不进1,目的是要商家少交钱。
好了,有了这些基础后,我直接整个数据库设计保存的价格值佣金值都采用保留两位小数进行保存,虽然使用decimal(18,5)会有3个多余的0,这里我直接用一个方法进行切割,反正是没值的。
而对于百分比的,直接不变,都是采用五位小数。
下面我提供我换算的方法:
////// 四舍五入计算类 /// public class Round { ////// 标准切割,结果保留两位小数 /// 不计算四舍五入 /// public static decimal Standard(string money) { return decimal.Parse((Math.Truncate(decimal.Parse(money) * 100) / 100.00M).ToString("0.00")); } ////// 标准四舍五入,结果保留两位小数 /// public static decimal RoundForStandard(string money) { return Standard(Math.Round(decimal.Parse(money), 2, MidpointRounding.AwayFromZero).ToString()); } ////// 针对用户的四舍五入,结果保留两位小数 /// 要用户交钱的四舍五入,目的就是要用户多交钱 /// 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); } } ////// 针对商家的四舍五入,结果保留两位小数 /// 要商家交钱的四舍五入,目的是要商家少交钱 /// public static decimal RoundForMerchant(string money) { return Standard(money); } ////// 固定点的转换,可将小数后面多余的零去掉 /// 这个不固定保留多少位小数 /// public static decimal Fixed(string money) { return decimal.Parse(string.Format("{0:G}", money)); } }
后话,如果我这里有什么是错的,欢迎大家指正。