0

问题 - 我正在为学校创建一个小组论坛应用程序,需要为以下要求创建设计匹配。

  • 组和组成员之间的多对多关系。
  • 小组成员可以是学生或员工。(将来也可能是其他一些用户角色)。
  • 我的数据库中已经存在 Student 和 Staff 表。

环境 - Java、Spring、Hibernate、MySQL

方法 -

1.a) 数据库设计

组:| 编号 | 姓名 | is_active |

组成员:| 编号 | group_id | 用户角色 | 学生ID | 员工编号 | is_banned | is_default_user |

1.b) 类设计(DTO 类)

Group : GroupMember groupMembers[*] 等

GroupMember : UserRole userRole、Student student、Staff staff 等。

2.a) 数据库设计

组:| 编号 | 姓名 | is_active |

组成员:| 编号 | group_id | is_banned | is_default_user |

学生会员:| 编号 | group_member_id | 学生ID |

员工:| 编号 | group_member_id | 员工编号 |

2.b) 类设计

Group : GroupMember groupMembers[*] 等

GroupMember : UserRole userRole、Member member等

接口成员:getMember():Object

StudentMember 扩展 Student 实现 Member:getMember():Student

StaffMember 扩展了员工实现成员:getMember():Staff

我更喜欢第二种方法。似乎它更具可扩展性。在第一种方法中,始终有 1 列为空。这是浪费。

对于此类问题,上述环境(支持休眠:我是新蜜蜂)有没有更好的方法?

4

1 回答 1

0

是的,还有其他方法。基本上,您有一个 Member 实体,该实体有两个子类:StudentMember 和 StaffMember。StaffMember 与 Staff 关联,StudentMamber 与 Student 关联。

这种继承可以用三种不同的方式映射。

  1. 一切都在一个表中。这将导致您的第一个数据库设计:user_role 列是鉴别器列,student_id 或 staff_id 为空。

  2. 每个具体类都有自己的表。这将导致两个相同的表,除了一个将有一个 student_id 列,一个将有一个 staff_id 列。

  3. 每个班级都有自己的桌子。这将导致 3 个表:一个(成员)包含所有公共列(id、banner、group_id 等),一个仅包含 StudentMember 特定列(ID、引用成员表和学生ID),以及包含 StaffMember 特定列(ID、引用成员表和员工 ID)的列。

所有方法都有优点和缺点:

  • 第一个导致可以为空的连接列,但非常有效(例如,不需要连接来加载组的所有成员)。另一个表也不可能对 StudentMember 有 FK,而只能对 Member。
  • 第二个导致列重复,并且需要加入来加载成员(但没有加入来加载StudentMember或StaffMember),但它没有可为空的外键,并且可以对StaffMember或StudentMember有一个FK,但不是任何会员。
  • 第三个效率低下,因为它需要为每个查询连接。但它没有列重复,你可以有任何你想要的外键。

鉴于您只有一个列在子实体之间有所不同,我会选择第一个解决方案,它更易于理解、查询和优化,并导致更简单的查询。

所有这些继承策略都在文档中进行了描述。

于 2013-01-30T14:38:41.327 回答