【问题标题】:Common child table to many master tables in database数据库中许多主表的公共子表
【发布时间】:2013-10-13 12:56:24
【问题描述】:

我正在使用 mysql 数据库和 php 来构建 Web 应用程序。

我有一个子表attachment,这是许多主表的通用表:teacherstudentclassRoom(和其他)。 主表数超过 10 个,比如说 n 个表。

我的问题是:

  1. 在数据库中只创建一个名为“附件”的表,并将其与主表关联。
    这将导致附件表中有 n 个外键(即: n-1 未使用的列),这也将导致模型中的 n-1 个属性,而无需在每次创建模型时都被初始化或使用。

  2. 为每个名为 (master_i_Attachment) 的主表 (master_i) 创建一个表,并将其与主表相关联。但这会导致我的代码中有 n 个附件表和 n 个附件模型。

有什么建议吗?

【问题讨论】:

  • 该表的用例是什么?
  • 附件表用于存储(名称、文件路径、文件类型、文件大小、注释和其他详细信息...)。

标签: php mysql database oop database-design


【解决方案1】:

您可以做的是只拥有一个包含以下字段的表:id、reference_id(您的父表之一)、reference_type(即 reference_id 属于哪个表)、(附件表中的所有其他字段) .

然后,例如,如果您想获取特定父类型的附件,您可以对该类型运行 SELECT 查询过滤,例如WHERE reference_type='classroom'。

或者,如果您想获取具有特定 ID 的教室的附件:

SELECT * FROM attachment WHERE reference_id=<ID> AND reference_type = 'classroom';

您可能希望在 (reference_id, reference_type) 上有一个复合唯一键,这将确保您不会得到重复的附件(除非您希望给定类型的给定 ID 有多个附件,在这种情况下,键不应该是唯一的)。

此解决方案是否适合您的需求取决于您将如何使用数据,即您将最常运行哪种查询。

【讨论】:

  • 您的解决方案很好,但我认为这会影响数据的完整性。我需要外键来将孩子与主人联系起来。所以如果主记录有孩子,我不能删除它
  • 您可以对触发器执行相同的操作,但实际上,您必须为所有父表设置触发器。在这种情况下,您的选项 2 可能是最佳选择。
  • 如果我采用了选项 #2。让我们把问题转移到代码上,代码呢?我正在考虑制作一个模型来管理数据库中的所有附件表,并在模型类中使用类型属性来区分它们。这是一个好习惯吗?
  • 对我来说这似乎是一个合理的解决方案。
【解决方案2】:

基于database normalization concept,不鼓励在数据库中使用冗余和未初始化(或空)值。实际上,规范化试图越来越多地隔离数据(这意味着任何异常都有更多的表)。 但是您可以简单地忽略规则或对数据库进行非规范化以解决性能问题。

在您的情况下,我认为最简单(和规范化)的方法是选择编号 #2(每种附件类型的单独表格)。但是你可以像 Ashalynd 所说的那样调整你的设计。在您的表中放置一个type 列以指定父表。顺便说一句,使用这种方法会增加数据库级联更改的复杂性。

【讨论】:

  • 如果我采用了选项 #2。让我们把问题转移到代码上,那代码呢?我正在考虑制作一个模型来管理数据库中的所有附件表,并在模型类中使用类型属性来区分它们。这是一个好习惯吗?
  • 我认为这在不变的程序中不会成为问题。但是如果你想把它看作一个软件工程问题,我认为正确的方法是在你的代码中使用面向对象的概念。例如,一个用于管理附件的抽象类,可以专门针对每种附件类型(虽然这更复杂,但将来很容易更改和扩展)。
猜你喜欢
  • 1970-01-01
  • 2020-12-17
  • 2012-10-25
  • 2015-02-22
  • 2014-10-08
  • 2011-11-25
  • 2022-01-11
  • 2011-04-23
  • 2012-10-08
相关资源
最近更新 更多