gpt4 book ai didi

database-design - 如何避免嵌套事务

转载 作者:行者123 更新时间:2023-12-03 17:40:33 28 4
gpt4 key购买 nike

我目前正在实现一些依赖于 SQLite 数据库的功能。在这样做的过程中,我遇到了一个我没有预料到的限制。这让我想知道我是否以正确的方式解决了我的问题。我希望有人可以提出一种考虑到要求的不同方法。

目标

目标是尽快将大量对象存储到数据库中。但是,如果在任何时候确定不应存储这些对象,则该操作不应对数据库产生任何影响。确切的存储查询(“插入”)取决于之前的插入。

用例

考虑一个非常大的“实例信息包”集合,每个包代表一些相应抽象实例的部分知识。因此,整个集合代表了一个或多个抽象实例的完整知识。每个包的信息组成为:

  1. 实例 ID;用于唯一标识与此信息相关的抽象实例。
  2. 属性映射; (attribute_uri, attribute_value)-对,其中 attribute_uri 唯一标识属性,attribute_value 是相应的文本值。

instance_id 和 attribute_id 都可以在表中找到,分别为 TBL_INSTANCES 和 TBL_ATTRIBUTES。这里使用的数据库模型是 EAV 模型。

插入后,表 TBL_ENTRIES 应包含以下形式的条目:

[ entry_id | instance_id | attribute_id | attribute_value ]

问题

实现似乎很简单:

  1. 设置保存点
  2. 开始交易
  3. 为 TBL_ENTRIES 中的多个插入准备语句
  4. 对于集合中的每个实例:
    • 4.1。在TBL_INSTANCES中查找instance_id。如果不存在,请将其添加到 TBL_INSTANCES
    • 4.2。对于实例属性映射中的每个属性:
      • 4.2.1。在 TBL_ATTRIBUTES 中查找 attribute_id。如果不存在,请将其添加到 TBL_ATTRIBUTES。
      • 4.2.2。将条目添加到 TBL_ENTRIES
  5. 如果在任何时候发生错误,则回滚到保存点,否则提交。

不幸的是,在查找步骤(4.1 和 4.2.1)中,SQLite 报告“无法在事务内启动事务”错误。阅读文档,这似乎在于查找调用 sqlite3_exec 例程的事实,该例程(除非我弄错了)似乎在内部设置了一个事务。

问题

如果不允许嵌套事务,我应该如何执行查找步骤(基本上是“INSERT OR REPLACE”表达式,后跟“SELECT”查询)?有没有办法避免它们或在当前事务中使用 sqlite3_exec ?如果不是,我处理问题的方式是否错误?也许我不应该使用单独的整数作为键,例如直接使用attribute_uri作为key,而不是查找对应的attribute_id。

无论如何,我仍然需要在事务期间做一些等效的事情,因为真正的速度增益在于准备实例集合上的语句,而不是属性集合:一个实例可能只有一个或两个属性,而实例集合中的实例数量总是很大。

我使用的是 C/C++、SQLite 3.7。

非常感谢您对我的方法提出任何建议或评论!

最佳答案

来自SQLite documentation on BEGIN TRANSACTION :

Transactions created using BEGIN...COMMIT do not nest. For nested transactions, use the SAVEPOINT and RELEASE commands

我似乎记得嵌套事务应该已经存在于任何 SQLite 3.7.* 中。

关于database-design - 如何避免嵌套事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14444701/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com