【发布时间】:2009-03-22 13:27:52
【问题描述】:
我知道标题可能听起来有点矛盾,但我要问的是关于 ORM 框架(在本例中为 SQLAlchemy,但我想这适用于其中任何一个),它允许您定义架构在您的应用程序中。
是直接更改数据库架构,然后手动更新程序中的列类型更好,还是在应用程序中定义表,然后使用 ORM 框架的表生成函数来生成架构和然后为你在数据库端建表?
【问题讨论】:
我知道标题可能听起来有点矛盾,但我要问的是关于 ORM 框架(在本例中为 SQLAlchemy,但我想这适用于其中任何一个),它允许您定义架构在您的应用程序中。
是直接更改数据库架构,然后手动更新程序中的列类型更好,还是在应用程序中定义表,然后使用 ORM 框架的表生成函数来生成架构和然后为你在数据库端建表?
【问题讨论】:
请记住,除了最微不足道的情况外,应用程序和数据库往往存在 M:M 关系。如果您的应用程序很可能具有与其他系统、报告、数据提取或加载的接口,或者数据迁移到另一个系统上或从另一个系统上迁移出来,那么该数据库有多个利益相关者。
善待应用程序中的其他利益相关者。花点时间正确地建立架构,并在应用程序设计中考虑数据质量。密切关注使用该应用程序的任何其他人,并确保您不会在不告诉他们的情况下破坏他们所依赖的架构的一部分。这意味着数据库或多或少都有自己的生命。集成度越高,数据库越独立。
当然,如果没有其他人使用或关心数据,请随意忽略我的建议。
【讨论】:
我个人认为,您应该根据自己的优点来设计数据库。数据库是处理领域数据建模的最佳场所。数据库也是应用程序减速的最大来源,让您的 ORM 设计您的数据库对我来说似乎是个坏主意。 :)
当然,我身后只有几个大项目。我还在每天学习。 :)
【讨论】:
定义数据库架构的最佳方式是从对应用程序域建模开始(域驱动设计吗?),然后根据您定义的域对象查看哪些表形成。
我认为这是最好的方法,因为实际上数据库只是一个保存应用程序信息的地方,它永远不应该主导设计。它也不是唯一保存信息的地方。例如,我们有想要使用平面文件或数据库的用户。他们还可以使用 XML 文件。因此,从您的域对象开始,然后从那里生成表(或平面文件或 XML 架构或其他),最终将导致更好的设计。
虽然这可能取决于您使用面向对象的语言,但使用 Hibernate/NHibernate、SubSonic 等 ORM 工具确实可以让您轻松完成此转换,包括生成数据库创建脚本。
就性能而言,性能应该是您在应用程序中最后考虑的因素之一,它永远不应该驱动设计。在根据您的域建立并运行良好的架构后,您可以随时进行调整以提高其性能。
【讨论】:
很大程度上取决于您对要使用的特定数据库产品的技能水平。可以将其视为“手动”和“自动”变速箱汽车之间的区别。 ORM 为您提供“自动”传输,只需开始设计您的类,然后让 ORM 担心以某种方式将其存储到数据库中。
听起来不错。大多数 ORM 的问题在于,在他们追求 PI“无知”的过程中,他们通常不会利用可以为给定任务提供优雅解决方案的特定数据库功能。请注意,我没有说所有 ORM,只是说大多数。
我的想法是首先自己设计概念数据模型。然后您可以朝任一方向前进,向上朝向应用程序空间,或向下朝向物理数据库。但是请记住,只有您知道使用视图而不是表是否更有利,如果您对表进行规范化或反规范化,那么对于该表来说,哪些非聚集索引有意义,是自然键还是代理键适合这个表等等……当然,如果你觉得这些问题超出了你的掌握,那就让ORM来帮你吧。
还有一件事,您确实需要将应用程序设计与数据库设计分开。它们几乎不一样。这些数据有多重要?是否可以设计另一个应用程序来使用该数据?重构一个应用程序比重构一个包含分布在数千个表中的十亿行数据的数据库要容易得多。
【讨论】:
好吧,如果您能侥幸成功,那么在应用程序中执行此操作可能是最好的方法。因为它是 DRY 原则的完美示例。
话虽如此,但要摆脱它总是很困难,因为您实际上选择放弃大多数特定于数据库的优化。 (更重要的是,通过查询,但它仍然适用于模式(索引等))。
无论如何,您最终可能会手动更改架构,然后您将陷入脆弱的数据库架构,这将成为您最糟糕的噩梦的根源:)
我的 2 美分
【讨论】:
尽可能根据自己的要求进行设计。试图让它们保持过于严格的同步是增加耦合/降低内聚的一个很好的例子。
想想看,ORM 可以很容易地用于传播耦合(即使在某种程度上可以避免)。
【讨论】: