【问题标题】:Database design, two types of users for website数据库设计,网站的两类用户
【发布时间】:2010-01-26 04:32:35
【问题描述】:

我正在制作一个评论类型的网站,我希望有两种类型的用户。一个是大多数人,评论者,而另一个是评论所针对的人。在数据库设计方面,我将如何区分两者。我应该为评论者和评论者设置单独的表格,还是只是为两者分配不同的 ID 范围?

【问题讨论】:

  • 感谢您的快速回复。两种类型的用户的信息都是相同的。一些上下文,不是一回事,而是认为 ratemyprofessor.com,教授能够回应特定的 cmets 和评论。

标签: php mysql database database-design


【解决方案1】:

这是典型的超类型/子类型情况。用户和审阅者都是人,关系偏执者会说你应该有一个包含所有普通人字段的“人”表。然后,您可以与审阅者表建立明确的一对一外键关系,该表包含审阅者特定字段和其他审阅者特定表的相关键。您可以通过加入 Reviewers 表来检查某人是否是审阅者。

您当然可以将具有不同数据的其他类型的人添加到此方法中。对于像我这样喜欢避免空值字段和引用多个表之一的未声明外键的关系偏执狂来说,这是一种建模事物的好方法。 MySQL jockeys 只会将它们全部塞进一张大表中,其中包含大量空值、幻数和 varchar 字段中的逗号分隔列表。

如果您知道需求在未来不会改变(哈!),并且用户和审阅者之间的架构没有区别,只需使用单个 person_type 字段并保持简单。

切勿出于任何原因使用“键范围”。这只是骇客,只会在几年内对您或其他人造成巨大痛苦的重新编码工作。主键应该没有语义和不变性。

【讨论】:

  • 所以你建议像renter(user_ID, user_Fname, user_Lname, user_email) 和另一张桌子地主(user_ID,lander_ID)?
  • 是的,减去landlord_id(如果有一对一就不需要了)。此外,只有在房东表中需要其他特定于房东的数据而不是一般人员表中时,答案才会是肯定的。最后,我真的希望人们不要再将他们的“人”表命名为“用户”...... USER、USERID 等在大多数 SQL 方言中通常是保留的关键字或函数名,所以你最终只会给自己带来痛苦。没有什么比为应用程序编写的每一个查询都输入一堆额外的括号或引号更有趣的了。
  • SQL 书籍中的标准超类型示例是“客户”。客户可以是个人或组织。因此,您有一个包含常见客户字段的客户表,该表与订单和其他客户类型数据相关。然后,您有一个 CustomerPerson 和一个 CustomerOrg 表,它们都与 Customer 是一对一的,并且使用 Customer_ID 作为它们的键。在大多数情况下,CustomerPerson 和 CustomerOrg 包含非常不同的模式。有点做作(人员和组织在大多数实际应用程序中都是他们自己的表,通过一对一的中间表进行子类型化)。
  • 了解并欣赏有关用户命名方案的提示,在我使用的简短示例中,我还没有遇到过这个问题。
【解决方案2】:

我建议您为用户创建一个表,为用户类型创建另一个表,并为用户创建一个外键,以防您以后需要两种类型的用户。

【讨论】:

    【解决方案3】:

    鉴于您的问题含糊不清,我想说这取决于任何一方将访问/插入的信息类型。据我了解,数据库的结构应该反映您组织数据的方式,而不一定反映数据库用户之间的关系。例如,您可以有一个名为“用户状态”的单独表,其中包含 0->审阅者、1->审阅-ee,然后将用户状态列为用户表中的外键,作为指示给定用户是否为列的列Reviewer 或 Reviewee,从而无需单独的 User 表。

    【讨论】:

      【解决方案4】:

      你可以有一个“类型”列,其值为“reviewer”和“reviewee”

      【讨论】:

        【解决方案5】:

        这在很大程度上取决于您为这些用户类型保留了哪些数据。如果非常相似,单个表可能没问题,但您需要一个区分字段(列)而不是分配一个 ID 范围。

        如果您需要关于审阅者和审阅者的不同信息,并且将这些信息放在一起是有意义的,那么您最好将它们分成至少两个表格。

        【讨论】:

        • 那么对于那些只是普通用户(审阅者)的用户,我会做 userID、otherID 并且只将 otherID 留空吗?
        • 被审稿人也是审稿人吗?
        【解决方案6】:

        如果描述这两个不同用户的属性不同,那么您可能需要将它们分开。如果它们共享相同的属性,例如 firstName、lastName 等,那么您可以将它们保存在同一个表中。

        【讨论】:

          【解决方案7】:

          有一次,有人说,“总是把相似的东西放在同一张桌子上。”

          这是真的,因为 SO'ers 对“喜欢”的定义是如此模棱两可,以至于他总是可以创建一个正确的定义。

          这么说,你应该在这里做同样的事情。审稿人和被审稿人都是“人”这一事实无关紧要。真正的问题是任何人都可以两者兼而有之吗?如果不是这样,那么您将没有问题,实际上应该使用单独的表。

          这样想。

          假设这是真的评论者永远不会成为评论者。在某个地方,您将拥有一个包含 Reviewer_ID 和 Reviewee_ID 的表。您将为这两个表构建一个 FK。这些约束保证您将拥有一名审阅者和一名审阅者……您永远不会有两个之一。

          但是,如果他们可以“穿衣打扮”,可以这么说,并且您构建了两张桌子,那么您要么必须将同一个人放在具有不同 ID 的两张桌子上,这是不可能的(除了添加更多层)才能知道他们是同一个人,否则您将不得不重铸为超类型/子类型样式。

          把相似的东西放在同一张桌子上。 like 的真正含义是行为上的。可以复习的东西,即使是教授和电影,也应该放在一张桌子上。您如何处理它们的不同属性(可空列或超类型/子类型)取决于您提供的更多信息)。

          【讨论】:

            猜你喜欢
            • 2012-07-19
            • 2013-04-30
            • 1970-01-01
            • 1970-01-01
            • 2015-01-25
            • 1970-01-01
            • 2011-03-17
            • 2021-01-22
            • 2013-02-26
            相关资源
            最近更新 更多