我有一个完整的会计系统内置物业管理应用程序。我有一个日记账分录表,控制各种会计活动的所有过账,例如:
发票
付款
账单
存款
在某些情况下,有必要将这些实体连接到日记账分录表,以便按不同的属性和单位聚合会计分录。
我在找最好的办法。我有几个选择:
1) 在日记账分录表中添加外键以链接到发票id、付款id、账单id、存款id,然而,这些组合的大多数将是互斥的(即存款不会有付款),所以我会有这样的情况,即对于给定的日记账分录,我会在那些不适用于该给定日记账分录的外键中有空值。
2) 我可以创建一个外键,我们称之为doc\u id,另一列doc\u type来指示文档的类型(发票、付款、账单、存款、,etc),并使doc\u id和document\u type\u id的组合引用其中一个扩展表上的主键(即doc\u id=1&doc\u type=invoice,该组合将引用invoice表上的主键)。
哪种方法更好?还是我想的都错了?
1条答案
按热度按时间ltskdhd11#
这听起来像是标准的基本实体/子实体模式。有一个表,我们称之为journalentries,它包含所有日记条目共有的属性:id、条目类型、创建时间、创建者等等。
请注意,id是主键,因此是唯一的。因此,从域定义的Angular 来看,使id和etype的组合唯一的约束是多余的。它所做的只是为外键定义一个锚点。
这些FK将在子实体表中--每个子实体一个表:发票、付款、账单和存款。请注意,如果在journalentries表中将条目定义为存款(etype='d'),则只能在deposits表中创建相应的条目。例如,您不能在payments表中错误地使用该id。
让我们定义一个子实体表:
现在,让我们创建一个活动,它总是有一个发票与之关联,并且可以有任意数量的其他条目。这些约束确保只能插入发票,并且id值必须与定义为发票的journalentries条目匹配。
可能有任意数量的附加条目,它们可能是任意条目类型,因此您需要一个交集表:
请注意,“日记条目”是与其中一个子实体表中的关联数据相关联的日记数据。因此,对任何日记条目的fk引用都应该引用journalentries表,而不是任何子实体表,即使您知道它是什么类型的条目。所以activities行引用journalentries表,使用etype字段作为额外的数据完整性工作,因为它必须是发票。交集表包含任何类型的条目,因此它的fk目标就是pk。
注意:为了便于说明,journalentries表中的类型指示符被check语句约束。在实际的数据库中,更好的设计是条目类型查找表。这样可以保持数据的完整性,但设计要灵活得多(加上mysql仍然(!)不实现检查约束。)