【问题标题】:When to INSERT or UPDATE with composite primary key models in ORM?何时使用 ORM 中的复合主键模型插入或更新?
【发布时间】:2010-12-10 07:03:06
【问题描述】:

我有一个自制的 ORM 系统,目前只支持自增主键。这工作得很好,但现在是支持复合主键的时候了。我知道代理与复合主键之间的圣战,我个人认为每个都有一席之地。无论如何... :)

使用自增主键,很容易判断在保存模型时是否必须运行 INSERTUPDATE 语句:这取决于是否设置了主键。

但是对于(非自动递增的)复合主键,这并不容易分辨,因为即使您正在执行INSERT,您也必须设置所有复合主键字段值。

那么,对于我的问题:如何确定在使用复合主键时是否应该运行 INSERTUPDATE 语句?

以下是我想出的解决方案:

  1. 事先查询是否存在复合主键的记录。这似乎是最好的选择,即使每次保存都必须运行额外的查询。
  2. 使用 MySQL 的 INSERT ... ON DUPLICATE KEY UPDATE 语法。但是我的 Model 类完成的其他操作需要知道记录是否是新的,例如是验证所有列(当记录是新的时)还是只验证修改的列(当记录已经存在时)。

您有更好的解决方案吗?还是其中之一是我最好的选择?感谢您的洞察力!

【问题讨论】:

    标签: sql mysql language-agnostic orm


    【解决方案1】:

    如果我可以避免的话,我真的不会将自己与 RDBMS 特定的语法联系起来,所以我会排除第 2 条规则。

    第三个选项是让用户决定和处理错误,在你的 ORM 中提供 Create() 和 Update() 方法,如果你应该在你应该 Create() 的时候依靠 RDBMS 出错并出现重复键错误没有。

    我个人会在 ORM 中提供第一种和第三种方法,因此人们可以选择最合适的替代方法(非关键代码路径的易用性,或对性能重要的地方的控制)。

    【讨论】:

      【解决方案2】:

      相信你可以使用REPLACE或者使用

      “INSERT ... ON DUPLICATE KEY UPDATE”正如你所说..这可能有助于手册。

      使用 ON DUPLICATE KEY UPDATE, 如果每行受影响的行值为 1 该行作为新行插入,并且 2 如果更新了现有行。

      【讨论】:

      • 这是有用的信息,但一等奖是真正了解记录是否是新的。很好的建议,谢谢!
      • 我很高兴它有点用处。但这是我的想法,即使使用自动增量..你怎么知道是否需要预先更新或插入记录?您将传递某种标志,表明这是对 x id 的更新,或者如果 id 不存在,则假定它是新记录或这些行上的某些内容。或者我不完全理解你在说什么。
      • 是的,在模型上调用 save() 时,它会检查是否设置了主键。如果是,则更新;如果没有,请插入。
      • hmmm 所以我猜你在这种情况下被选项 1 卡住了,否则我能想到的只是传递一个单独的标志来指示它的更新或插入或更新()和插入( ) 而不是 save(),我相信你已经想到已经有充分的理由拒绝了。所以我想你在那里遇到了一个额外的查询。
      【解决方案3】:

      如果我必须使用你的工具,这就是我想要的行为(以及其他 OR/M 使用的行为):

      1. 在您的类上维护一个 IsNew 属性。获取数据时,将该属性设置为 false。当用户创建新类时,将其设置为 true。

      2. 当保存操作到来时,现在您知道是基于该属性 (IsNew) 执行 INSERT 还是 UPDATE。

      好处:

      • 没有其他查询。
      • 如果用户想要在不先获取数据的情况下进行更新,您可以将该属性设为公开,以便他们可以设置 IsNew=false,然后将进行更新。
      • 无论您有单个或复合 PK、自动增量列等,都没有关系。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-09-19
        • 1970-01-01
        • 2013-11-20
        • 1970-01-01
        • 2020-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多