【问题标题】:For storing people in MySQL (or any DB) - multiple tables or just one?用于将人员存储在 MySQL(或任何 DB)中 - 多个表还是只有一个?
【发布时间】:2017-07-21 03:05:53
【问题描述】:

我们公司有许多不同的实体,但这些数据库实体中有很大一部分是人。所以我们有客户、员工、潜在客户、承包商和供应商,他们都有某些共同的属性,即姓名和联系电话号码。

我可能在面向对象的思想上过火了,但现在我正在考虑制作一个包含所有人员的“人员”表,并使用标志/子表“扩展”该模型并将基于角色的属性添加到联结表有必要的。如果我们增长到 250.000 人(在 MySQL 和 ISAM 上),这会极大地影响性能,以至于未来的 DBA 会永远诅咒我吗?我们最常见的搜索是姓名/姓氏组合。

例如像 Salesforce 这样的公司,客户/潜在客户/员工都在一个带有子视图的集中表中(因为需要更好的术语),还是它们被分成不同的表?

警告:这个问题与“我们发现在现实世界中这样做更好”有关,而不是理论设计。我喜欢上面的解决方案,并且相信有了视图、适当的大小和准确的索引,性能不会受到影响。我也觉得上面说的不算MUCK,就是一张挺大的桌子。

【问题讨论】:

    标签: mysql database database-design


    【解决方案1】:

    一个“人”表是最灵活、最有效且无故障的方法。

    您可以轻松地进行有限的搜索 - 例如,查找所有具有此姓氏的人和客户。但是您可能还会发现,当您不知道某人是什么时,您必须查找他们 - 当您有一个“人”表时,这将是最简单的。

    但是,您必须考虑到一个人对您来说是多件事情的可能性 - 一个客户因为购买了一些东西一个承包商因为您雇用他们来完成一份工作。因此,最好有一个“连接”表来为您提供多对多关系。

    create person_type (
       person_id int unsigned,
       person_type_id int unsigned,
       date_started datetime,
       date_ended datetime,
       [ ... ]
    )
    

    (当然,您需要添加索引和外键。person_id 是“person”表的 FK;“person_type_id”是所有可能人员类型的参考表的 FK。我添加了两个日期字段,以便您可以确定某人对您来说什么时候。)

    【讨论】:

    • 所有的答案都正是我要找的,但你找到了我没有想到的一件事——如果我不知道那个人在哪里怎么办。一个主桌的原因正是因为我们有多个角色的人,为我们工作的老客户和不同的角色。集中常见的东西是有意义的。谢谢!
    【解决方案2】:

    由于您有许多不同“类型”的 Persons,为了进行规范化设计,并具有适当的外键约束,最好使用超类型/子类型模式。一个Person 表(所有属性共有)和许多子类型表(EmployeeContractorCustomer 等),都与主 Person 表 1:1 关系,并具有必要的详细信息适用于每种类型的人。

    查看@Branko 的答案作为示例:Many-to-Many but sourced from multiple tables

    【讨论】:

      【解决方案3】:

      一个数据库的 250.000 条记录并不是很多。如果您适当地设置索引,您将永远不会发现任何问题。

      您可能应该为用户设置一个类型。这些类型应该在不同的表中,因此您可以看到类型的含义(使其成为 TINYINT 或类似的)。如果您需要每个用户类型的其他字段,您确实可以为此创建一个不同的表。

      这种方法对我来说听起来很不错

      【讨论】:

      • 感谢您的回答,这是我想听到的。然而,我选择了 D Mac,因为他指出了一些我没有想到的事情。
      【解决方案4】:

      理论上,您有可能成为您工作的公司的客户。

      但如果这里不是这种情况,那么您可以根据角色将人员存储在不同的表中。

      不过,正如 Topener 所说,250.000 并不多。所以我个人觉得将每个人都放在一张桌子上是安全的。

      然后为每个角色(员工、客户等)设置一列

      【讨论】:

        【解决方案5】:

        即使您最终得到一个单表解决方案(用于核心人员属性),您也将希望使用视图对其进行抽象并施加一些约束。

        您最不想做的就是将机密信息发送给客户,这些信息本应发送给员工,因为有人没有正确加入。或者意外的交叉连接导致报表上的收入翻倍(但仅适用于也有员工以某种方式关联的特定客户)。

        这实际上取决于您希望图层的外观以及哪些组件将访问哪些图层以及如何访问。

        另外,我认为您想重新审视您选择 MyISAM 而不是 InnoDB。

        【讨论】:

          猜你喜欢
          • 2020-03-12
          • 2021-11-20
          • 1970-01-01
          • 1970-01-01
          • 2010-09-12
          • 2019-06-13
          • 2010-09-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多