【问题标题】:How do I get ID of an exiting table entry or insert a new one in case it doesn't exist efficiently?如何获取现有表条目的 ID 或插入一个新条目以防它不存在有效?
【发布时间】:2010-08-18 21:25:58
【问题描述】:

我使用SQLite 来维护一个数据库,其中包含一个带有路径的表。表的 CREATE 语句如下所示

CREATE TABLE path (id INTEGER PRIMARY KEY AUTOINCREMENT,
                   name TEXT,
                   UNIQUE(name));

我正在寻找一种简短的方式来在 SQL 中说“将此给定路径插入路径表并给我它分配的 id,或者只给我一个 id,以防它已经存在”。

现在,我正在使用多个 SQL 语句(前面的伪代码)执行此操作:

unsigned int getIdForPath(p) {
  result = exec("SELECT id FROM path WHERE name='$p';");
  if result.empty {
    exec("INSERT INTO path VALUES(NULL, '$p');");
    result = exec("SELECT last_insert_rowid() FROM path;");
  }
  return result.toInt();
}

所以,我首先尝试查找 id;如果它似乎不存在,我添加一个新条目,最后执行另一个 SELECT 以获取最近使用的 id。这似乎有点笨拙,可能效率低下。

有没有更紧凑和/或更有效的方式来实现这个逻辑?

UPDATE:常见的情况是条目确实已经存在,所以上面伪代码中的初始SELECT在大多数情况下都会找到结果。

【问题讨论】:

    标签: sql optimization sqlite query-optimization


    【解决方案1】:

    如果值不存在,您可以分两步使用INSERT OR IGNORE 插入该值,然后选择元素的id。

    【讨论】:

    • 真的!但是,我的问题应该更准确。常见的情况是值 确实 已经存在。因此,在任何情况下,使用 INSERT OR IGNORE 和 SELECT 将执行两个查询,而问题中的伪代码在大多数情况下只会执行一个查询。当然,当您回答时您不知道这一点,因此向您 +1 以提供比我更短的解决方案。 :-)
    • 如果该值在大多数情况下已经存在,那么您的代码已经很有效了。
    • 很高兴知道;仍然,是否有可能有一个比我写的更短的同样(或更高)有效的解决方案?也许是一些巧妙的嵌套 SQL 查询?
    • 接受这个答案;我想你是对的 - 如果共同路径是该值已经存在,那么简单的 SELECT 就尽可能高效。
    猜你喜欢
    • 1970-01-01
    • 2017-07-04
    • 2012-07-17
    • 1970-01-01
    • 2013-12-09
    • 2019-12-02
    • 1970-01-01
    • 2020-02-26
    • 2023-02-21
    相关资源
    最近更新 更多