ORM建模:数据库优先 vs 类优先

14

我正在尝试使用Sparx Enterprise Architect设计一个数据模型,并最终将其转化为MySQL数据库。

我的第一种方法是使用数据模型图,它可以用于生成DDL(或通过反向工程实现相反的效果)。

这个方法非常有效,但我的一个同事指出了一个问题:我们打算使用ORM(几乎肯定是Hibernate)将表映射到Java类。他的评论是,“数据库优先”方法将排除使用继承等良好的OO技术。

这似乎是一个好观点,但我想知道是否有任何限制。如果我从头开始使用类图而不是数据模型图,是否有一种方法可以在此模型中包含所有必要的Hibernate注释、配置等?如果我以后需要建模特定于数据库的功能(如约束、触发器等),在这种类型的模型中是否都是可能的,考虑到类图并不真正针对这种类型的功能?


我总是喜欢以数据模型图开始,从中创建我的类图,然后以尽可能简化我的工作的方式映射我的类。 - Genzotto
谢谢,你的意思是说你手动制作两个图表吗?理想情况下,我希望只需要维护一个图表,并将其用作生成类和数据库模式的单一来源(在模型外部最小化“连线”)。 - Steve Chambers
在这种情况下,我会保留数据模型图,但我认为答案取决于个人和你喜欢的工作方式。 - Genzotto
我更熟悉数据库优先的方法,从未尝试过类优先的方法。问题实际上是要确定在使用这种方式时无法捕获模型(即类图)中的任何内容。 - Steve Chambers
5个回答

11

我更喜欢先建模数据库。数据库是业务中最有价值的部分,应用逻辑只是操纵业务数据的接口。

由于数据库往往比应用技术存在时间更长,最好提前设计,因为设计通常由数据关系和数据查询模型驱动。

大多数 ORM 是为了将领域对象建模到现有模式中而设计的,ORM 工具的任务是处理任何可能的数据库模式映射问题。

对于快速原型设计,我可以考虑从领域对象生成模式,但在设计大型企业系统架构时,这种方法并不是最佳选择。

Hibernate 只提供有限的 DDL 功能,我不喜欢失去额外的特定于数据库的功能,例如PosgreSQL domainsinstead-of triggersmaterialized views 或者 MySQL triggers

一个工具如Flyway最好用于自动化模式迁移过程。


一些好的例子,但是这些都似乎与MySQL无关。我想知道的一些事情是MySQL触发器以及控制索引、外键和引用完整性的所有Hibernate注释(ON DELETE RESTRICT/CASCADE/SET NULL/NO ACTION)等。 - Steve Chambers

10
让我通过提问来回答这个问题:如果你想建造一座房子,你会先建好房子再做蓝图还是你会先做计划呢?:)
软件开发的目的是逐渐降低抽象级别。我们从一个非常抽象的项目想法开始,然后制定一些需求(这显然要稍微具体一些),接着进行架构、设计,最终达到编码的水平(最低抽象级别)。
数据模型是最低可能抽象级别的模型(可以直接映射到 DDL),因此这是您将要处理的最后一件事情。
领域类模型是数据库更高层次的抽象。它甚至是 Hibernate 层的抽象,因为它也依赖于实现层面的抽象。
所以,我首先肯定会使用类和 OO 的全部功能来建模领域。尝试制定独立于实现的类模型。不要假设 JAVA、Hibernate、DB 或其他任何东西,而是集中精力处理领域逻辑。制定一种“乌托邦”领域模型,逻辑上完美结构化的领域类。
然后使用相应的转换从此模型派生出 Hibernate 层和 DB 本身。

7
无论使用哪种技术,您都应该始终坚持“真相优先”。在XML接口中,真相在哪里?在其XSD规范中,而不是任意语言中的某些实现类。同样,在与RDBMS交互时,真相在哪里?它在数据库中,以DDL形式编写。数据库应该“拥有”其模式,而不是从某个派生的客户端表示生成它。我在这里写过这个话题
这是控制数据库模式的唯一合理方法,对于数据库至关重要。这也是合理的唯一方式,可以:
  • 在上线后演变模式,不能简单地删除并重新创建它
  • 控制数据库性能,特别是当您编写SQL查询而不是使用ORM来导航实体时。

我们打算使用ORM(几乎肯定是Hibernate)将表映射到Java类。他的评论是,“数据库优先”方法会排除使用好的OO技术,如继承。

你应该问自己为什么需要继承。由于你正在使用关系模型来存储数据,因此应该使用关系模型的建模功能,并且所有客户端表示(例如ORM)都应该从中派生。在这个领域中,继承甚至是一种可行的建模技术也很少见,大多数情况下仍然不起作用,因为经过20多年的面向对象编程,人们已经得出结论,早期面向对象编程过度使用了继承,特别是数据结构的继承。应该优先选择组合,而且更具有关系性。
很可能你的关系模型将比你的面向对象客户端表示更加持久,你应该确保关系模型是健全和规范化的等等。

这似乎是一个好观点,但我想知道是否存在任何限制。如果我从头开始使用类图而不是数据模型图,是否有办法在这个模型中包含所有必要的Hibernate注释、配置等?如果我以后需要对数据库特定的功能进行建模,如约束、触发器等,是否可以在模型中实现,考虑到类图并不真正针对这种类型的内容?

我认为您不需要通过派生类图来浏览数据库模型。以ERD的形式思考(您可以从DDL中生成它)。ORM的表示将简单地反映出这一点。

1
领域模型优先,始终如一。 然后同时处理数据库和实体。

0

我支持领域驱动设计,先创建类/代码。

首先创建Hibernate实体类,这是你将要编写的内容 - 如果你不打算编写SQL,为什么要关心持久化的内容呢?我的流程是先创建类,如果需要的话从中输出UML(虽然很少有这种资源的奢侈),然后让Hibernate构建数据库。

我尽量避免使用特定于供应商的数据库功能 - 它们通常会有些奇怪。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接