【问题标题】:How do you handle "special-case" data when modeling a database?在对数据库建模时如何处理“特殊情况”数据?
【发布时间】:2010-09-25 14:13:35
【问题描述】:

我们的组织为我们的客户提供各种服务(例如,网络托管、技术支持、定制编程等...)。我们网站上有一个页面列出了所有可用的服务及其相应的价格。这是静态数据,但我的老板希望全部从数据库中提取。

列出了大约 100 项服务。然而,其中只有两个具有非数值的“价格”(特别是字符串“ISA”和“成本 + 8%”——我真的不知道它们应该是什么意思,所以不要问我)。

我不想仅仅因为这两个列表而将“价格”列设为 varchar。我目前的方法是创建一个特殊的“price_display”字段,该字段要么为空白,要么包含要显示的文本来代替价格。这个解决方案感觉太像一个肮脏的黑客(它会使查询不必要地复杂化),那么有更好的解决方案吗?

【问题讨论】:

    标签: database data-modeling


    【解决方案1】:

    也许在主表中使用“类型”指示符,一个子表允许数字价格,另一个子表允许字符值。这些可以合并到一张表中,但我通常避免这样做。如果您想根据购买的数量确定价格,您也可以使用带有数量的中间链接表。

    【讨论】:

    • 查看 RickH 的回答,我实际上喜欢他的解决方案 5 作为您一般情况的灵活实现。它与中间表相结合是我用于税收计算的东西,这是一个类似的情况。
    【解决方案2】:

    很多选择:

    1. 所有价格都存储为 varchars
    2. 以数字形式存储的价格和额外的 price_display 字段,如果已填充,则会覆盖该数字
    3. 以数字形式存储的价格和用于显示目的的额外 price_display 字段手动填充或在数字价格更新时触发(数据重复并且可能不同步 - yuk)
    4. 存储映射到特殊情况的特殊情况负价格(简直太棒了!!)
    5. varchar 价格,可用前缀表的前缀键字段('cost +',...),可用后缀表的后缀键字段,价格类型列表的类型列表字段键( '$'、'%'、'描述')。如果您将来需要针对价格编写复杂的查询,这很有用。

    我可能会选择 2 作为一个务实的解决方案,如果我需要一些非常通用的通用定价系统,我可能会选择 5 的扩展。

    【讨论】:

      【解决方案3】:

      认为此列是向客户显示的价格,可以包含任何内容。

      如果你试图把它变成一个数字列,你会招来悲伤。你已经在两个不符合的价值观上苦苦挣扎,明天你的老板可能想要更多……

      • 申请价格!
      • 请致电我们获取今日特惠!!

      你明白了。

      如果您确实需要一个数字列,则将其命名为 internalPrice 或其他名称,并将您的数字约束放在该列上。

      【讨论】:

      • 你是对的。我们的老板可能很想将类似的东西放入其他服务的“价格”中。此外,据我所知,不会对这些数据执行任何业务逻辑。使它成为 varchar 可能是最好的方法。谢谢。
      • 该死的。我一完成,我的老板就说“现在我们进入第 2 阶段 - 建立一个‘价格估算器’,它将计算所选服务的总成本”。我想我会回到使用“display_price”列。
      • :-) 老板们通常都想要它。
      【解决方案4】:

      问问自己...

      我会添加这些值吗?我会按价格排序吗?我需要转换成其他货币价值吗?

      我只是在网页上显示这个值吗?

      如果这只是一个洗衣清单而不用于计算,最简单的解决方案是将价格存储为字符串 (varchar)。

      【讨论】:

        【解决方案5】:

        如果这是您的数据模型的范围,那么 varchar 字段就可以了。无论如何,您的正常价格(可能是小数)可能对计算毫无用处。您如何比较“数据传输”10 美元/GB 和“域托管”25 美元/月?

        此特定项目的数据模型不是关于定价,而是关于显示定价。考虑到这一点进行设计。

        当然 - 如果您要存储特定客户为特定项目支付的价格,或者试图计算向特定客户收取的费用 - 那么您将拥有一个不同的(更复杂的)域。你需要一个不同的模型来支持它。

        【讨论】:

          【解决方案6】:

          至少有一个备用价格包含一个数字,那么价格列,价格类型呢?正常条目可以是美元值和类型“dollar”的数字,另一个可以是 8 和“PercentOverCost”以及 null 和“ISA”(用于 Price 和 PriceType 列)。

          如果你走这条路,你可能应该有一个 PriceType 表来验证和 PriceTypeID。

          这将允许在未来添加其他类型的定价(单位定价、外币),为您提供一个数字,并让您更容易了解您正在处理的定价类型..

          【讨论】:

            【解决方案7】:

            当我过去不得不做这种事情时,我使用过:

            Price   Unit   Display
            10.00   item   null
            100.00  box    null
            null    null   "Call for Pricing"
            

            价格将是十进制数据类型(任何精确的数字,不是浮点数或实数),单位和显示将是某种字符串数据类型。

            然后使用 case 语句以单价或显示来显示价格。还要在显示列上放置一个约束或触发器,使其必须为空,除非价格为空。如果 price 不为 null,则约束或触发器也应该需要单位值。

            通过这种方式,您可以尽可能计算订单的价格,并在未指定价格但同时显示两者时将其排除在外。我还制定了一项业务规则,以确保在定价要求得到解决之前无法总计总计(您还必须有一种方法将特殊定价插入到订单详细信息中,而不仅仅是从价格表)。

            【讨论】:

            • 这个项目是 7 个月前,在一个我不再工作的地方。不过,谢谢,它将来会很有用。
            【解决方案8】:
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-04-09
            • 1970-01-01
            • 1970-01-01
            • 2016-05-16
            • 2021-12-09
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多