【问题标题】:How to better organise database to account for changing status in users如何更好地组织数据库以考虑用户状态的变化
【发布时间】:2012-08-19 05:28:04
【问题描述】:

我关注的用户可以是“未确认”或“已确认”。后者意味着他们可以获得完全访问权限,而前者意味着他们正在等待主持人的批准。我不确定如何设计数据库来解释这种结构。

我的一个想法是有 2 个不同的表:confirmedUser 和 unconfirmedUser,它们非常相似,只是 unconfirmedUser 有额外的字段(例如“emailConfirmed”或“confirmationCode”)。这有点不切实际,因为当用户确实被接受时,我必须复制所有信息(尽管我认为它不会那么糟糕 - 预计流量不会很大)。

我想象的第二种方法是将所有用户实际放在同一个表中,并在需要时拥有一个指向带有额外“未确认”数据的表的密钥(也许还在用户中添加一个“已确认”标志表)。

每种方法的优缺点是什么?是否有更好的方法来设计数据库?

【问题讨论】:

    标签: database database-design


    【解决方案1】:

    第一种方法意味着您需要为两个表编写每个查询 - 为所有常见的。坏(tm)。第二种选择肯定更好。这样您就可以根据特定访问权限的需要添加一个简单的where confirmed = True(或 False)。

    您实际上可以考虑的是确认的数据(不是用户,只是数据)是否存储在同一个表中。也许将所有确认数据放在一个单独的表中会更干净+规范化,这样您left join confirmation on confirmation.userid = users.id where users.id is not null (或类似的,或内部连接,或在服务器端脚本中获取所有+过滤器等)只获取确认的用户。确认电子邮件、日期等附加数据可以存储在这里。

    【讨论】:

    • 如果您将确认状态和数据保存在单独的表中,请记住在confirmation 表中将confirmation.userid 设为唯一(+ 外来)键或主(+ 外来)键。
    【解决方案2】:

    我个人会选择您的第二个选项:1 个用户表,其中包含布尔类型的已确认/待定列。将数据从一个表复制到另一个相同的表是不切实际的。

    然后,您可以创建组并将特定访问权限附加到每个组,并在需要时将每个用户分配到特定组。

    【讨论】:

      【解决方案3】:

      从逻辑上讲,这是继承(又名类别、子类、子类型、泛化层次结构等)。

      从物理上讲,继承可以通过 3 种方式实现,如 hereherehere 以及可能在 SO 上的许多其他地方所提到的。

      在这种特殊情况下,所有类型都在同一个表中的策略似乎最合适1,因为层次结构很简单,不太可能获得新的子类,子类只有几个字段不同,而你需要维护父级密钥(即未确认和确认的用户不应有重叠的密钥)。


      1 即您的问题中提到的“第二种方式”。是否也将确认数据放在同一个表中取决于所需的基数 - 即那里是否存在 1:N 关系?

      【讨论】:

        【解决方案4】:

        最好的方法是为用户创建一个表,其中状态 ID 作为外键,状态表将包含所有不同类型的确认以及您可能拥有的所有不同组合。在我看来,这是构建规范化数据库和满足您的编程需求的最佳方式。

        所以你的状态表看起来像这样

        StatusID | Description
        =============================================
        1        | confirmed
        2        | unconfirmed
        3        | CC confirmed
        4        | CC unconfirmed
        5        | acct confirmed CC unconfirmed
        6        | all confirmed
        

        用户表

        userID | StatusID
        =================
        456    |    1
        457    |    2
        458    |    2
        459    |    1
        

        如果您需要确认码,可以将其存储在用户表中。并对其进行编程以在使用后进行更改,以便在他们需要重置密码或其他任何情况时可以使用相同的字段。

        也许我假设太多了?

        【讨论】:

        • @aneroid 你在说我的方法吗?
        • @aneroid 如果您在用户表中有电子邮件和确认日期,则可以将其保留为 Null,您可以在 IS NOT NULLIS NULL 的列上进行查询
        • 是的,但只是它的“标准化”方面。您不需要单独的confirmed/unconfirmed 状态,因为在我的解决方案中,确认表中存在用户 ID 表示用户已确认。您描述的Status 表没有任何好处,因为“确认”可以在同一个表中存储为布尔值 True/False 或整数 0/1。不需要英文“确认/未确认”映射。
        • 也正确。但是,当您想将可规范化的数据移出时,您在哪里划清界限?如果稍后有其他相关信息,您可以继续将其添加到 NULL 和非 NULL 列值检查中,并最终得到一个糟糕的设计。 OTOH,也可以说像“确认状态”这样重要的东西应该存储在同一张表中。所以我说,“你真正可以思考的是……”
        • 我明白你在说什么,并同意。我在想他会想要一个确认的电子邮件状态、确认的信用卡等,这取决于他使用它的目的。使用状态 id 表,您可以有不同的组合,但仍然只需要查询一个表
        猜你喜欢
        • 2015-10-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-03
        • 1970-01-01
        • 2016-07-24
        • 2010-09-22
        • 2020-03-10
        相关资源
        最近更新 更多