使用ORM时,在数据库设计中需要注意哪些事项


19

当您知道使用对象关系映射器(ORM)维基百科访问数据库时,需要注意哪些数据库设计陷阱?另请参阅实体框架NHibernate或LLBLGenPro。

作为示例,我将注意到SqlServer的RPC调用的2100参数限制。当使用LLBLgen和使用复合主键的联接表时,这是一个问题。有关复合键,请参见MSDN文章


4
没有冒犯,而是“连接具有多个主键的表”。这重新定义了表的基本规则之一,每个表一个PK。你到底是什么意思
玛丽安

这如何达到2100参数限制?您的表格有那么多列吗?另外,我假设您的意思是“对象关系映射”而不是“对象角色建模”
John Saunders

如果将大量值传递给SQL'IN'(LINQ array.Contains(member)),则2100参数限制有时会成为问题。但是,这实际上对数据库设计没有任何帮助。那更多是查询模式问题。遭受“折磨”的ORM最简单的解决方法是将列表插入到[永久]临时表中,然后联接到该临时表和/或使用子查询从其起源选择要查询的项目。(无论您是否使用OR映射器,将成千上万个项目传递给SQL'IN'通常都是不好的)。
KristoferA


4
@BozoJoe:根据定义,一个表只能有一个主键。没有DBMS允许您为单个表定义多个主键。
a_horse_with_no_name 2015年

Answers:


17

经历标准归一化技术,主要是第三范式。一些ORM可以选择在数据库级别定义的关系,因此您不必手动进行。

我真的会反过来问我应该对ORM了解多少。确保您知道:-如何配置查询?-如何覆盖ORM并编写自己的查询?-我可以改用存储的proc吗?

该数据库应与ORM无关,因为它比应用程序更耐久。


+1:“数据库应与ORM无关”。坚持数据库设计标准,好的ORM也会很高兴。
MicSim 2015年

12
  1. 切勿让ORM创建或更新架构。始终使用其生成的SQL作为模板,但在进行更改之前先进行遍历(我已经看到我们的ORM会创建冗余索引,使用错误的数据类型...所有这些错误的东西)

  2. 请注意您的ORM无法执行的操作。Django有一阵子不支持通过ORM进行分组,这很痛苦(仍然是,旧系统很有趣!)。因此,对于DBA而言,必须意识到ORM的局限性,即使他们不是为ORM编写代码的人也是如此

  3. 定期获取慢速日志,通过mysqlslowlog对其进行汇总,然后查看前10个左右的日志。基本上,它将向您显示花费了总计时间最多的查询。在过去一个月中,平均只花1秒钟但运行了5万次的​​查询就会在该汇总报告中显示出来,就像拇指酸痛;)

我不会说完全放弃ORM那样极端。如果您使用ORM的开发人员不是DBA,则他们编写的SQL可能比ORM糟糕或糟糕。因此,最终它将由DBA负责观察发生的情况。


1
并考虑将非常复杂的逻辑放入存储的proc中。ORM可以调用存储的proc,对于非常复杂的逻辑,更容易对proc进行性能调整。
HLGEM

7

我马上注意到有关遗留数据库的一些事情,这些遗留数据库不同于由ORM创建的数据库,例如SequelActiveRecord for Ruby。

  1. 在所有名为的表中使用主键'id'。是的,可以覆盖,但这id是默认设置。
  2. 在表中使用复数名称。
  3. 使用下划线(“ snakecase”)分隔创建表和字段的描述性名称的单词。
  4. _id外键附加的使用:布局通常类似于referenced_table_id

我一直手工编写SQL多年,因为我不信任ORM,但是在过去的两三个中,我开始使用前面提到的两个ORM,它们与现有数据库的集成程度令人印象深刻,以及如果遵循这些约定,他们可以如何解密数据库,或者我花时间给他们提供了解旧版数据库所需的提示。

我不知道是否有用于设计模式以与ORM配合使用的通用准则,但是我认为拥有一些标准会使我们所有人受益。绝对有时间和地点进行ORM,尤其是如果您使用的是良好的OO语言并且时间紧迫。


1
仅供参考:对于许多OR映射器,有一些工具可以处理命名约定的差异。我有一个Visual Studio外接程序,它使用基于规则的命名来处理Entity Framework和Linq-to-SQL。有关更多信息,请参见huagati.com/dbmltools
KristoferA

1
id是用于命名id字段的SQL反模式,不应使用。
HLGEM

关心解释为什么?当我们需要进行一对多和多对一查找时,如何处理表之间的关系?在我使用的不使用ID的ORM中,肯定会违反流程。
Tin Man

2

(())取决于您使用的OR映射器,因此花一些时间研究有疑问的数据库DB具有OR映射器支持/不支持的功能。

例如,Microsoft的OR映射器不支持SQL Server的所有内置数据类型,不支持某些更新/高级的TSQL功能(递归查询,优化器提示等)。

从理论上讲,一个好的OR映射器应该足够灵活,以克服(并允许您将一个设计良好的关系数据库模式映射到一个好的对象模型)。实际上,在所有难题都到位之前,我们还有一段路要走。尽管许多OR映射器都支持高级映射,但它通常以复杂的查询和性能问题为代价。

为了获得良好的数据库性能(并保持dba的理智:)),在进行数据库模式设计时,仍应遵循最佳实践。首先进行规范化,然后在需要的地方进行规范化。在代码方面,不要过于关注对象模型;即使OR映射器支持复杂的继承模式和合并多表一起,这些也都是在那里你出现问题的时间与过于复杂的查询命中数据库等领域的实体档案,型材,异型材,不只是拿ORM生成的查询是理所当然的。请记住,OR映射器生成的查询通常可以像普通的SQL查询一样进行调整,并且对象端的两个功能等效的查询(例如linq查询)有时会导致完全不同的SQL查询。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.