设计具有相似但不同模型的数据库

Designing a database with similar, but different Models

我有一个您可以创建文档的系统。您 select 要创建的文档类型和显示的表单。然后将数据添加到表单中,然后可以生成文档。在 Laravel 中,事情是通过模型完成的。我正在为每个文档创建一个新模型,但我认为这不是最好的方法。我的数据库示例:

所以它的核心是项目。我创建了一个新项目;我现在可以为该项目创建文档。当我从 select 框中 select 项目简介时,会显示一个表格,我可以在其中输入:

它是三个文本字段和一个标准输入字段。如果我从 select 菜单 select 报告文档,我必须输入该文档的数据(这是几个普通输入、几个文本字段和一个日期)。虽然它们都是文档,但它们需要不同的数据(这就是为什么我为每个文档创建了一个模型)。

问题:如图所示,我希望允许将支持文档与生成的文档一起上传。为此,我有一个 doc_upload table。所以一个文档可以有一个或多个doc_uploads.

回到MVC结构,在我的DocUpload模型中我不能说DocUpload同时属于ProjectBriefDoc和ProjectReportingDoc,因为它只能属于一个Model。因此,我不仅要为每个文档创建一个新模型,我还必须为每个文档创建一个新的上传模型。随着更多文档的添加,我认为这将成为管理的噩梦。

我正在寻找可以处理不同类型文档的更通用的模型。我的问题涉及我需要为每个文档捕获的不同类型的数据,以及如何将其融入我的设计中。

我有一个可行的设计,但我认为这是个坏主意。我正在寻找改进此设计的建议,考虑到每个文档需要不同的输入,并且每个文档都需要允许文件上传。

好的。

我有一个建议..您不必在 doc_upload 引用上有如此紧密的耦合。您实际上可以将其视为模型中的独立 table,不与单个实体挂钩。您仍然可以使用 ORM 来 CRUD 并管理此 table..

我会做的是保留 doc_upload table 并将其用于所有文档的所有 up_load 引用,无论文档所在的 table 模型和在 doc_upload table

中有以下字段

文档类型(可以是目标文档对象的对象名称)

documentid_fk(现在这是相应文档类型中单行的通用键 table(s)

因此给定 table 中的文档(您可以根据模型对象导出文档类型)并且您知道文档本身的 ID,因为您只是从数据库上下文中提取它。 . 应该能够提取 doc_upload table 中匹配这两个值的所有相关文档。

您可以在您的模型中使用反射来了解您所在的实体(文档类型)..而密钥就是密钥..所以您应该能够。

您仍然需要为您希望拥有的每种风格的项目文档创建一个新的模型实体..但如果变化率很小,这可能不会太困难..

您应该能够编写最少量的代码,将所有相关的上传文档提取到您的应用程序中。

您不需要为要创建的每种文档类型都设置 table/Model。

一种更灵活的方法是使用 project_documents table,其中您将使用 project_id 和一些相关数据到它,然后 doc_uploads 与 project_documents table.

相关

通过这种方式,一个项目可以拥有您的业务所需的尽可能多的文档,并且每个文档可以拥有所需的尽可能多的文件。

您可以尝试类似的方法:

如果你仍然想保留两个 tables,你的例子中的 doc_upload table 可以有两个外键和两个 belongsTo() Laravel 模型声明没有冲突(这不是婚姻,是开放式关系)。

或者您可以使用 Polymorphic Relations 做同样的事情,但它是数据库设计的反模式(因为它不能确保数据库级别的数据完整性)。

关于数据库设计的良好参考,google“Bill Karwin”和“SQL 反模式”。

这个人有很好的 Slideshare presentation 和一本关于这个主题的书 - 他曾经也是一个活跃的 SO 用户。

您可以在数据模型设计中使用 zero-or-one 关系的继承。
IMO 有一个名为 project-document 的抽象实体(table),包含所有文档的共享属性,将为您服务。

project-briefproject-report 以及其他类型的文档将是 children of project-document table,具有 zero-or-one 关系。 project-document 的主键将是 children.
的外键和主键 现在 project-documentdoc-upload 之间的 one-to-many 关系将解决问题。
我还建议在 project-document 内添加一个唯一约束 {project_id, doc_type} 以进行基数检查(如有必要)

正如其他答案所暗示的那样,您可能 不希望 为不同的文档使用不同的模型,而是为 "document" 使用一个模型对您的不同流程有不同的看法。 Laravel 似乎有一个很好的 "templating" 系统来实现视图:

http://laravel.com/docs/5.1/blade

http://daylerees.com/codebright-blade/