【问题标题】:Flags in database - Sensible way of keeping track数据库中的标志 - 跟踪的明智方法
【发布时间】:2022-03-06 01:09:03
【问题描述】:

我正在尝试设计我的第一个数据库,我发现我想在数据库中保留很多不同的“标志”:

Active      # Shows whether the item submission has been completed
Indexed     # Shows whether the item has been indexed
Reminded        # Shows whether the “expiring email” has been sent to the user
Error       # Shows whether there is an error with the submission
Confirmation    # Shows whether the confirmation email has been sent

除了为这些设置一个布尔字段之外,还有没有一种聪明的方法来存储这些详细信息?我想知道我是否在数据库中的状态组下有这些,每个内涵都有一个 ID (32),然后链接到那个。

【问题讨论】:

    标签: sql database linux postgresql debian


    【解决方案1】:

    除非有其他理由,否则我建议将这五个布尔(或位)列简单地添加到项目表中。

    【讨论】:

      【解决方案2】:

      这取决于内涵列表的不变性。

      如果只有您提到的五个,那么只需添加五个标志列。如果将来可能的内涵列表可能会发生变化,那么最好有一个单独的表,其中包含当前应用于主表中每一行的内涵列表,并且具有一对多的关系。

      【讨论】:

        【解决方案3】:

        考虑:

        Table: Vehicle
        ID
        Type
        Doors
        Color
        
        Table: Type_Categories
        ID
        Name
        
        Table: Types
        TypeID
        CategoryID
        Value
        DataType
        

        这种方式可以根据需要在其他地方重用类型。但是,如果所有标志都是真正的布尔值,则假定非布尔值“标志”...... Id 坚持 w/ 将它们放在表中。但我一直讨厌布尔值。我更喜欢时间戳,所以我知道标志是什么时候设置的,而不仅仅是它被设置了。如果时间戳为空,则没有设置。

        【讨论】:

          【解决方案4】:

          根据我的经验,状态栏经常演变为两个以上的状态。因此,为了方便和简单,我会为每个状态使用smallint

          但是,如果您的目标是节省空间,那么您可以将所有状态保存在单个 smallint 中,使用与 bit 之间的转换来单独或整体操作状态。

          create table t (status smallint);
          

          保存10010 然后将其转换为smallint:

          insert into t (status) values (b'10010'::int::smallint);
          

          列出所有状态:

          select status::int::bit(5) from t;
           status 
          --------
           10010
          

          要设置第三种状态,请使用bitwise or

          update t set status = (status::integer::bit(5) | b'00100')::integer::smallint;
          select status::int::bit(5) from t;
           status 
          --------
           10110
          

          要取消设置该状态,请使用bitwise and

          update t set status = (status::integer::bit(5) & b'11011')::integer::smallint;
          select status::int::bit(5) from t;
           status 
          --------
           10010
          

          要检索具有第 3 个状态集的行:

          select status
          from t
          where substring(status::integer::bit(5) from 3 for 1) = '1'
          

          您可以编写函数来简化转换。

          【讨论】:

            【解决方案5】:

            如果它们是“只是”标志,请将它们作为布尔类型的列存储在表中。

            我建议不要使用 Clodoaldo 的解决方案,除非空间真的很紧 - 请参阅 this 问题。

            您提到的列似乎具有“业务重要性” - 即存储“已编入索引”可能不够,而且还不足以存储该项目的索引日期。可能有必要限制状态组合,或对排序施加规则(在错误状态下无法完成)。在这种情况下,您可能需要实现一个“item_status”表来存储历史记录等。

            在这种情况下,您的架构将是这样的:

            ITEM
            ---------
            item_id
            ....
            
            STATUS
            ---------
            status_id
            description
            
            ITEM_STATUS
            --------------
            item_id
            status_id
            date
            

            每次项目更改状态时,您都会在 ITEM_STATUS 表中插入一个新行;当前状态是该项目的最新日期所在的行。

            【讨论】:

            • 你能解释一下吗,我有一个带有 ID 的 item_status 表,它链接到主要的“项目”,项目状态将有日期字段“索引”以显示它是什么时候完成了吗?
            • 我已经包含了一个示例架构
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-07-07
            • 2016-01-01
            • 1970-01-01
            相关资源
            最近更新 更多