【问题标题】:How to determine relationship (1:1, 1:n, n:m) between tables when reverse engineering逆向工程时如何确定表之间的关系(1:1、1:n、n:m)
【发布时间】:2016-12-04 18:59:56
【问题描述】:

我的数据库中已经创建了一些表,现在我需要为这些表绘制 ER 图。

  1. 标识了主键和外键之间的 表格
  2. 使用密钥确定 pk-fk 关系
  3. 现在我需要确定表之间的基数。我如何能 做这个??请让我知道我是否有任何一套规则 在评估 1:1、1:M 和 M:M 关系时需要考虑。

让我举两个被触动的表格的例子:

  • 表 A 有一个由 pid 和 identitytype 组成的复合键。
  • 表 B 有一个由 pid 和 maritalid 组成的复合键。
  • 表 A 和表 B 使用 pid 和 pid 相互关联 在两个表中都不为空。

让我知道表 A 和表 B 之间的关系类型是 1:1、1:M 还是 M:M。另外,请告诉我您在得出这种关系结论时遵循的步骤顺序。

谢谢, 敏捷。

【问题讨论】:

    标签: database postgresql database-design entity-relationship data-modeling


    【解决方案1】:

    实体-关系模型中的关系与您的想法大不相同。关系不是由外键约束表示的——这是旧的网络数据模型,它仅限于二元关系。实体关系模型表示表中实体集之间的 n 元关系,而不是表之间的关系。

    外键约束将一组列的值限制为另一组列的值的子集。它们有效地用于强制执行实体集(域) - 例如,确保每个 person_id 列都是代表系统中所有已知人员的列的子集。 FK 约束仅在更新期间使用 - 您可以从数据库中删除所有 FK,并且您的 SELECT 查询和 JOIN 将像以前一样工作,进一步证明它们不代表关系。

    关系是两个或多个实体集之间的关联,每个实体集由一个合适的键表示。关系实例总是记录在表的行中。例如:

    • 驾照和人员之间的 1:1 关系可以通过将许可证密钥和人员密钥放在一起作为表的两列来表示,并且两者(分别)受到唯一约束。无论是在许可证表、人员表还是单独的驾照表中,都是一个实现细节。

    • 汽车与其所有者之间的 1:N 关系可以通过将汽车密钥和人员密钥放在一起作为表的两列来表示,并且实体集在多方面受到唯一约束。这通常在记录多方实体属性的表中实现。

    前面的关系很简单,我们可以对它们进行非规范化,不需要将关系记录在单独的表中。但是,对于更高级别的关系,我们需要单独的表:

    • 学生和科目之间的 M:N 关系可以通过将学生键和科目键放在一起作为表的两列来表示,并且两者的组合受到唯一约束。

      李>
    • 供应商、产品和地区之间的 M:N:P 关系可以通过将供应商键、产品键和地区键一起表示为表的三列,并且三列的组合受到唯一约束。

    • 区域、产品和供应商之间的 M:N:1 关系(唯一授权)将通过将区域键、产品键和供应商键放在表的三列中来表示,并且组合区域和产品密钥受到唯一约束。

    看到图案了吗?

    如果实体集的特征谓词(其所需属性)在不同的表中表示,则关系的每个角色/组件都可以定义一个外键约束。这意味着单个 n 元关系可能需要 n 个不同的 FK 约束。

    从现有表中确定关系的基数:

    1. 确定表中表示的实体集。并非所有列都代表实体集 - 有些列代表值集,这意味着值本身作为标签或度量具有意义。

    2. 确定实体集的哪些组合被唯一地约束在一起。这些是关系的许多方面,我们将给它们提供 M、N、P 等变量。

    3. 每个其他实体集都依赖于先前的组合,并用基数 1 表示。

    事情没那么简单。除了实体集之外,表的键还可能涉及值集。在这些情况下,我们遇到了弱实体/识别关系/子类型化的情况。这些通常是(但不总是)1:N 关系,其中子实体的键与父实体的键部分重叠。

    更多信息,推荐Peter Chen的论文The Entity-Relationship Model - Toward a Unified View of Data

    【讨论】:

    • 您能否将这些规则应用到我的示例示例中,因为它可以帮助我更好地理解您的解决方案。
    • 您拥有的两个表可能与pid 表示的同一实体集相关。表 B 可能表示 M:N 关系 - id 字段往往是实体集的代理标识符,两列构成其主键。表 A 可能描述了一个子类型或弱实体集,这意味着pid(标识父实体集)和pid, identitytype(标识子实体集)之间存在 1:N 标识关系。
    【解决方案2】:

    你应该看看这个 SO 问题: postgresql-describe-table

    实际上,如果不查看架构定义,如果没有反例,您无法知道表是 1:1、1:n 还是 n:m 关系(如果 n = m = 1) .

    您可以进行扫描,但确定这种关系的是约束条件。

    如果你没有那个数据,那么你只能用例子来证明 1:n 和 n:m,但是没有约束定义就不能证明 1:1 不是 n:m。

    1:1 的关系如下所示:

    PK-PK

    这只能是一对(零或一),因为两个表都只能有唯一的键,1:n 和 n:m 是不允许的。这必须在一定程度上受到软件的限制,以确保单独表的 PK = PK,或者更常见的是,如果您真的想要 1:1 的数据存储,标准化,在同一个表中。否则,您需要通过事务插入或其他方式确保密钥协调。不建议使用自动生成的密钥。

    1:n 的关系如下所示:

    PK-FK

    FK(外键)将其定义为受限于另一个表中的主键,但可以是多重性的。

    n:m 关系如下所示:

    PK - FK|FK - PK

    那里有三张桌子。两个具有主键(PK)的规范化表和一个具有定义表之间映射 n:m 的 FK 关系的连接表。

    当然,所有这些都可以通过使用数据库的代码进行约束,因此,表约束是数据模式的唯一可靠定义。

    外键必须指向另一个表中的主键,所以你不能有FK:FK关系,也没有数据库定义的PK:PK关系。这必须通过代码进行事务插入来限制。通常的约定是按照标准化数据格式将 PK:PK 的数据存储在同一个表中。

    好的,那么,添加评论,针对表 A 和 B;你可以肯定地说你有由 pid:identitytype 和 pid:maritalid 组成的主键,如果是这种情况,为了讨论,说 identitytype 和 maritalid 是 int,那么你有 int:int 和 int: int,它什么也没告诉你。如果 identitytype 与 maritalid 重叠,则无法可靠地将它们区分开来。如果你只打算在 pid 上匹配,那么你有一个 N:M 关系,因为你有 pid:N-pid:M 不同的可能性会导致 N:M 关系。

    【讨论】:

    • 我有约束信息,我有主键和外键约束,如果您在上面引用的示例中需要更多约束,请告诉我,我可以与您分享...我想要知道使用这些表格描述我们如何识别
    • i如果您可以共享约束信息,也许会有所帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-03
    • 1970-01-01
    • 2019-12-16
    • 1970-01-01
    相关资源
    最近更新 更多