wol*_*ine 5 redundancy database-design hibernate version hibernate-mapping
我们正在开发一个系统,一个人可以将文档发送给另一个人,一个文档可以有多个附件,如下所示。
Document {
Set<Attachment> attachments;
}
Run Code Online (Sandbox Code Playgroud)
如果 X 向 Y 发送文档 (Doc1,Ver1) 并且 Y 编辑该文档,那么我们必须创建该文档的新版本 (Doc1,Ver2),以便 X 发送框不会反映 Y 所做的更改。
在我们的系统中,将有数百万个文档,其中每个文档可以有数百个附件。此外,一个文件可以在一段时间内通过 n 个人。
我们应该能够获取任何文档版本以及它当时的附件列表,所以我必须维护文档的版本,所以我立即想到的表结构是下面的。
Document - id primary key, ver_id primary key
Attachment - id, doc_id foreign key, doc_ver_id foreign key
Run Code Online (Sandbox Code Playgroud)
但是这种结构的问题是,如果 X 向 Y 发送一个带有 100 个附件的文档,而 Y 做了一些小的修改,那么我必须创建一个新版本并复制新版本的所有附件,其中大部分是相同的与之前的版本一样,由于我们将拥有数百万个文档,并且每个文档将通过 n 人,因此该模型将导致非常庞大的附件表,其中包含大量冗余数据。
所以我们想到了另一种附件结构,如下所示。
Document - id primary key, ver_id primary key
Attachment - id, doc_id, attached_ver_id, detached_version_id
Run Code Online (Sandbox Code Playgroud)
但是我无法使用这种结构为 Document 创建休眠实体,所以我的问题是,是否有任何其他表结构可以更好地以较少的冗余解决此问题,并且是否可以为上表创建休眠映射结构体。
当需要保留数据历史记录时,通常有两种可能的方法:
创建新条目时,将从最新的现有条目复制其详细信息。
第一个条目的详细信息将被存储。每个后续条目都存储对先前版本的更改。
方法#1 通常更简单、更快,因为可以直接查找任何记录的详细信息,而无需构建它们。但方法 #2 使用较少的存储空间。(可能值得注意的是,根据我的经验,方法 #1 始终更可取,因为检索的简单性和速度通常比存储更重要的考虑因素)。
我的理解是,您一开始使用方法#1,但现在更喜欢方法#2。
但是我无法使用这种结构为 Document 创建一个 hibernate 实体,所以我的问题是,是否有其他表结构能够更好地以更少的冗余来解决这个问题,并且是否可以为上面的表创建一个 hibernate 映射结构。
应该完全有可能为这个数据库结构创建实体——每个实体当然只是数据库表的 Hibernate 类表示。建议在文档版本和附件之间添加映射表:
Document - id primary key, ver_id primary key, ...
Attachment - id primary key, ...
DocumentAttachmentDelta - doc_id, doc_ver_id, attachment_id, added_or_removed_flag
Run Code Online (Sandbox Code Playgroud)
这DocumentAttachmentDelta是一个明确定义的映射表,其中 @ManyToOne 关系链接到标识文档版本和附件的主键。它有一个附加的布尔标志,指定是否为此版本的文档删除或添加附件。因此,从上面来看,对于文档的第一个版本,将添加其所有初始附件,但对于后续版本,仅存储增量,这可能是添加或删除。
@Entity
class Document {
/* ...other fields... */
@OneToMany(cascade = CascadeType.ALL, mappedBy = "document", orphanRemoval = true)
List<DocumentAttachmentDelta> documentAttachmentDeltas;
}
@Entity
class Attachment {
/* ...other fields... */
@OneToMany(cascade = CascadeType.ALL, mappedBy = "attachment", orphanRemoval = true)
List<DocumentAttachmentDelta> documentAttachmentDeltas;
}
@Entity
class DocumentAttachmentDeltas {
/* ...other fields... */
@ManyToOne
Document document;
@ManyToOne
Attachment attachment;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
580 次 |
| 最近记录: |