【问题标题】:How do you deal with char(1) in place of a boolean and tri-state fields?你如何处理 char(1) 来代替布尔和三态字段?
【发布时间】:2010-10-06 22:31:26
【问题描述】:

与我关于整数而不是小数的问题有点相关;我的供应商以 char(1) 格式(即 Y/N)提供了很多“布尔”字段。其中一些字段合法地不能是布尔值,因为它们可以有多个值,但大多数可以被视为布尔值。在我之前的问题中,建议是做“正确”的事情,而不是供应商提供的事情;我应该仍然应用此逻辑并使用这些列的位字段创建我的数据库架构,还是将其保留为 char(1) 并在我的代码中进行转换?

同样关于这个主题,就代码而言,我应该如何处理三态字段?从逻辑上讲,该字段是一个布尔值(从某种意义上说,我只对 Y/N 值感兴趣,而第三个值实际上是是或否),但这些值可以不仅仅是真/假(例如,有一个UpsShippable 字段可以是YNG);该字段有多个状态,那么我将如何最好地封装它?像枚举(或静态常量,因为枚举不能与 char 数据类型一起使用)之类的东西?在多值情况下,数据更像是一个类型指示符而不是一个标志。

总结一下(我有点啰嗦):1)在处理数据中的char(1) 值时,您会将它们保留为字符还是转换为位(或任何您的数据库的布尔类型)以及为什么,和 2) 假设您在数据模式中将其保留为 char(1),您将如何处理代码中的三态 char 字段?

编辑:为了澄清,这些字段都没有用于“真实”逻辑,它基本上只是一个指标。例如,如果该物品不能通过 UPS 运送(即价值为 N/G),那么在面向客户的页面上,它会说该物品不能通过 UPS 运送,并且在后端逻辑不会调用 UPS 的网络服务来计算运费。其他 Y/N 字段只是作为有关项目的额外详细信息存在并且没有逻辑,尽管它们需要是可更改的(例如,有一个复选框来指示它是否在后端的数据输入表单上被回收);我可能会显示图像或按它们过滤项目(例如,您可以搜索所有回收产品,我会检查以确保它们的回收指示符是真实的)但没有别的,至少目前不是。

【问题讨论】:

    标签: sql sql-server database-design types


    【解决方案1】:

    您可以创建一个视图,将三态布尔字段转换为可空位字段。

    例如:

    CASE UpsShippable WHEN 'Y' THEN 1 WHEN 'N' THEN 0 ELSE NULL END
    

    如果将此视图创建为索引视图,则从数据中进行 SELECT 时不会产生任何开销。

    【讨论】:

      【解决方案2】:

      不久前我遇到了类似的情况。我正在针对我无法控制的数据库构建一个应用程序,该数据库使用 char(1) Y/N 字段作为布尔值。我还使用 SubSonic ORM 框架来构建我的数据访问层。我所做的是在类上创建另一个属性,以便表格与 char(1) 字段相互转换。

          public string SomeYNField { ... } // property generated by ORM tool
      
          // property added manually (in a partial class, so 
          // it doesnt get blown away by the ORM tool)
          public bool SomeYNFieldBool
          {
      
              get 
              { 
                  // Anything other than a "Y" is false.
                  return SomeYNField.Equals("Y", StringComparison.InvariantCultureIgnoreCase); 
              }
              set 
              {
                  SomeYNField = value ? "Y" : "N"; 
              }
          }
      

      现在您可以使用该布尔字段绑定到复选框和其他需要布尔值的控件。

      【讨论】:

        【解决方案3】:

        我决定继续将简单的 Y/N 字段实现为真正的位字段,但我仍然不确定应该如何处理多状态字符字段。

        我需要将它们用作标志来指示是否应该采取其他行动;例如,除非ShippingStatusCodeY,否则该项目将被视为可通过 UPS 运送,并且应用与可运送不同的一组逻辑。逻辑范围可以从不显示某些选项到用完全不同的项目实际替换已输入表单的项目,或者如果查找表明没有等效项目则将其完全删除。

        解决了一个问题.. 一个问题。关于处理多态领域的想法?我必须将它们保留为 char 字段,尽管我认为我会谨慎行事并使用 char(3) 而不是 char(1) 以防万一需求在某些时候发生变化。

        【讨论】:

          【解决方案4】:

          1:) 取决于 char(1) 是否只是 Y/NT/F 类型字段,那么是的,我会将其转换为位,因为它是布尔值,我将转换为供应商特定格式系统的边缘(想象一下,您有多个供应商,例如 fedEx 和 UPS,您可能能够概括您的后端系统来处理两个托运人,然后插入特定组件来与您的模型和他们的模型进行通信)。

          2:) 如果有多个状态,那么这不再是布尔值,我会将其存储为有意义的格式,一些选项是将其存储为 char 字段,或者您可以创建一个查找表以便UpsShippable 您可能有 Yes、No 或 Ground。好吧,查找表允许您存储有关 G 含义的更具描述性的信息。如果我会在代码中使用 Enum,很大程度上取决于该字段的目的和您的项目是什么。如果您要针对该字段运行逻辑,那么我可能会考虑使用与查找表完美搭配的枚举,如果您只是存储和传递数据,那么也许我不会。

          【讨论】:

            【解决方案5】:

            我最常处理的 Oracle 并没有真正的位类型,所以它从来都不是问题。

            话虽这么说,一个字符的代码字段很常见而且很好。不管你做什么,不要给他们一个误导性的名字,暗示它是一个布尔类型,如果它有 3 个状态。这只会让人们感到困惑。

            错误名称:SHIP_FLAG(“flag”含糊不清,但许多人会将其解释为 Y/N 或 T/F)
            坏名:HAS_BOOKED(再次暗示布尔值)
            错误名称:IS_SENT(同上)
            好名字:SHIP_CODE(这可以表示任何你想要的意思)

            此外,一个字符字段允许您稍后扩展含义。位域没有(真的)。

            【讨论】:

            • 此外,char(1) 字段意味着数据与可能没有位/布尔字段的不同数据库交叉兼容(这可能是它以 char(1) 开头的原因);正如你提到的甲骨文。
            • +1 表示“允许您稍后扩展含义”。用户需求具有以意想不到的方式改变的诀窍。
            • 好的,看起来可以将其保留为 char(1) 并在代码中进行转换?这使我能够在数据导入过程中进行较少的转换,并在以后需要时对其进行扩展。
            【解决方案6】:

            我建议在双态字段中,您始终进行布尔转换。

            三态字段有所不同...有很多解决方案,但没有一个绝对“正确”。您可以为选项集创建表,并按索引链接...但是除了“正确”之外,您会失去人类的可读性,几乎没有收获。

            【讨论】:

              猜你喜欢
              • 2010-10-05
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-02-19
              • 2020-10-12
              • 2022-07-29
              相关资源
              最近更新 更多