使用带有 bookshelfjs (knex) 的 ON DUPLICATE KEY UPDATE 在事务中插入多对多关系时的最佳实践

Pie*_*che 5 javascript mysql database bookshelf.js knex.js

好吧,我正在开发一个个人项目,您可以用它来制作“观看”列表。用户可以使用公共 API (TheMovieDB) 查找他们听说过的好电影,并将其添加到他们的观看列表中。每当添加电影时,我都会将数据保存到数据库中。我使用下表(不包括与问题无关的列):

用户

  • ID

电影

  • 身份证(PK)
  • tmdbID(唯一)

电影用户

  • 身份证(PK)
  • movie_ID(电影表中的 FK 引用 ID)
  • user_ID(FK引用用户表中的ID)

流派

  • 身份证(PK)
  • 名称(唯一)

流派_电影

  • 身份证(PK)
  • genre_ID(流派表中的 FK 引用 ID)
  • movie_ID(电影表中的 FK 引用 ID)

我选择了 MariaDB,因为我想要 ON DUPLICATE KEY UPDATE 功能,因为我在这个数据库中没有任何原始数据,所以例如当有人想将一部电影添加到他们的数据库中,但我数据库中已经有这部电影时,我只想在 movie_users 表中添加一个新行。同时,当涉及到流派时,我也会使用该功能。

就语言而言,我将 NodeJS 与 BookshelfJS 一起使用。

现在我根本不是 SQL 方面的专家,所以我不确定我的工作方式是否是最佳的。此外,我对 Promise 不太熟悉。这是我在将电影添加到数据库时使用的代码: http: //codeshare.io/BPWDV

我使用交易是因为我认为这是最安全的方式?我还必须使用 knex.raw ( http://knexjs.org/#Raw-Queries ),这样我就可以使用 ON DUPLICATE KEY UPDATE。基本上这是发生的事情:

  1. 我尝试根据任何现有行将电影插入电影表中
  2. 如果电影已经在表中,我会查找电影的 ID,以便可以在 movie_users 表中使用它。如果电影最初不在那里,我不必查找 ID,因为我会取回插入行的 ID。
  3. 我在 movie_users 表中插入一行
  4. 我绘制了一系列电影的类型。对于每种类型,我都会像电影一样尝试,它会根据任何可能的重复项插入或不执行任何操作。如果没有插入,我会查找表中已有的流派 ID。
  5. 然后,我使用流派的 ID 和电影的 ID 将一行插入到 Genomes_movies 表中

就我个人而言,这看起来是完成这样的事情的一种可怕的方式,所以我觉得我一定做错了。整个承诺链看起来也感觉很尴尬。它有效,但我认为还有更好的方法吗?

我还计划使用 actor 表和 actor_movies 表,但我不知道如何将其放入其中(以及整个 Promise.map 事物)。

所以最终,我的问题是:如果代码是正确的,我该如何清理代码,或者如果代码根本不是最优的,那么完成我打算做的事情的更好方法是什么?