【问题标题】:iOS / SQLite, efficiently updating lots of recoreds with a guid?iOS / SQLite,使用 guid 有效地更新大量记录?
【发布时间】:2018-01-02 17:12:27
【问题描述】:

我正在尝试找出将(不同)guid 添加到可能有数千条记录的新字段的最快方法。

我很确定 SQLite 没有提供创建 guid 的函数。所以我需要以某种方式为每一行创建这个。

我想出的想法做得很远。

  1. 只需在字段为空且限制为 1 的情况下执行更新查询。显然,即使在事务中这也会很慢。

  2. 将 cte(公用表扩展)与一个临时表一起使用,我在其中建立包括 guid、更新/连接在内的值。但是我似乎无法让临时表在 iOS 中工作,我不断收到一个名为乱序错误的库。

  3. 在更新查询中使用内联子查询。但是我不知道如何识别需要 guid 的行,除了它们是空白的。我需要使用递归,我相信这又需要 cte?

编辑:这是我的解决方案,感谢@CL。对于想法...

void newguid(sqlite3_context *context, int argc, sqlite3_value **argv)
{
    if (argc != 1 || sqlite3_value_type(argv[0]) != SQLITE_TEXT) {
        sqlite3_result_null(context);
        return;
    }

    @autoreleasepool {
        CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
        NSString *uuidString = (__bridge_transfer NSString *)CFUUIDCreateString(kCFAllocatorDefault, uuid);
        CFRelease(uuid);

        sqlite3_result_text(context, [uuidString UTF8String], -1, SQLITE_TRANSIENT);
    }
}

- (void)createSqlGuidFunction:(sqlite3*)db
{
    if (sqlite3_create_function_v2(db, "newguid", 1, SQLITE_ANY, NULL, &newguid, NULL, NULL, NULL) != SQLITE_OK)
    {
        NSLog(@"%s: sqlite3_create_function_v2 error: %s", __FUNCTION__, sqlite3_errmsg(db));
    }
}

【问题讨论】:

  • 为什么不在插入行时添加 guid?
  • 谢谢@Malik,我正在用我的应用程序的新版本升级我的桌子。我需要 guid 作为我所有表的唯一键,因此我可以将它用于 iCloud/多用户同步。
  • 啊!这就说得通了。下面看看我的回答

标签: ios sql iphone sqlite


【解决方案1】:

documentation 这么说

应用程序可以使用此函数与 hex() 和/或 lower() 一起生成全局唯一标识符,如下所示:

hex(randomblob(16))

lower(hex(randomblob(16)))

但如果你想使用不同的机制来生成 GUID,你可以register your own function

【讨论】:

  • 谢谢,这是解决方案的一部分,但是这不会创建一个唯一的 guid,我认为真正的 guid 基于时间戳并包括连字符。话虽如此,这是一个好的开始。 ⭐️ 我也想知道 iOS SQLite 框架是否支持这一点。
  • 啊,这很有趣gist.github.com/mmarcon/1323584/… 我会进一步研究这个,看看我是否能想出一个更好的 guid 实现。我会在几天后回复。
  • 我已根据您的想法将我的解决方案添加到我的问题中。谢谢。太棒了!
【解决方案2】:

我建议做这样的事情

ALTER TABLE newTable RENAME TO oldTable;
CREATE TABLE newTable (//Define your columns here along with the GUID column);

然后您可以从 oldTable 中选择所有值并与 GUID 一起插入 newTable。完成后,使用

DROP TABLE oldTable

【讨论】:

  • SQLite 本身不支持将 guid 作为列类型。我在代码中使用 varchar 和我自己的函数来创建 guid。
  • 我知道。 GUID column 是指将存储 GUID 值的列而不是列的类型
  • 那么我如何在每一行中获得唯一的 guid?我需要运行单独的插入查询吗?这是我提到的性能瓶颈之一。
  • 正确。您将使用循环迭代来自oldTable 的结果,并将它们与guid 一起插入newTable(将在每次循环迭代时重新创建)。如果您认为这将是一项昂贵的操作,您也可以考虑在 background queue 上运行此流程
  • 谢谢,但我看不出这会比我提到的第一种方法更快吗?我还需要在用户使用该应用程序之前执行此过程,因此在后台运行不会有帮助。
猜你喜欢
  • 2014-05-12
  • 2011-02-19
  • 2016-08-15
  • 1970-01-01
  • 1970-01-01
  • 2012-01-07
  • 1970-01-01
  • 2021-11-15
  • 2023-03-06
相关资源
最近更新 更多