长时间访问sqlite的最佳方式

时间:2014-09-12 14:40:23

标签: shell sqlite

好的,我有一个shell脚本,它使用sqlite数据库来存储数据。但是,它是一个长时间运行的脚本,随着时间的推移会运行很多小查询。

目前我正在为每个查询调用sqlite3 'my.db' 'SELECT * FROM foo'或类似内容,但我不认为这非常有效,因为sqlite每次都必须重新打开数据库(除非它偷偷地让它们保持打开状态)一段时间?)。

但是,这也意味着如果我需要进行任何设置,例如指定超时选项,那么每次调用sqlite3时我都需要这样做。

我想知道的是,如果有一些替代方法我可以构建我的脚本,例如在交互模式下在后台打开sqlite3进程,并以某种方式用查询和抓取响应来提供它。有没有一个好的,强大的方法来做到这一点?

我已尝试过这些内容,但我并不总是知道查询会返回多少结果(如果有的话),所以我最终不得不像SELECT COUNT(*) FROM foo WHERE bar=1; SELECT * FROM foo WHERE bar=1那样进行查询,所以我总是回到至少一行中可以得到预期的结果数,但是如果我(某种程度上)得到的结果比预期的要多,那就不好了,因为当我运行下一个查询时它们仍然会等待。

这是我尝试的缩写形式(请原谅任何错别字,我肯定会做一些):

#!/bin/sh
mkfifo '/tmp/db_in'
mkfifo '/tmp/db_out'

# Create the sqlite process in the background (assume database setup already)
sqlite3 'my.db' </tmp/db_in >/tmp/db_out &

# Set connection parameters
echo '.timeout 1000' >/tmp/db_in

# Perform a query with count in first result
echo 'SELECT COUNT(*) FROM foo WHERE bar=1;SELECT * FROM bar WHERE bar=1;' >/tmp/db_in
read results </tmp/db_out
while [ $results -gt 0 ]; do
    IFS='|'; read key value </tmp/db_out
    echo "$key=$value"

    results=$(($results - 1))
done

这是沿着正确的路线,还是有更好的方法来做到这一点?我还没有想到让sqlite在每个查询的输出结束时返回一些东西的方法,这将是我认为更好的做事方式。我知道echo选项可用于在输出之前回显查询,我至少可以使用它来确保我没有读取以前查询中剩余的任何内容,但我真的希望能够处理任意长度的结果更正确(首先不需要计数,因为这可能会不同步)。

唯一的另一种选择似乎是将结果转储到文件中,但是因为我可能正在处理大量的查询,所以我真的不想这样做;至少对于FIFO来说,一切都还在记忆中。

[编辑] 我刚刚注意到在写入db_in后我尝试使用close sqlite3的一些shell,在这些情况下我认为fifos可能需要绑定到文件描述符以保持它们打开。我现在不打算将它添加到示例中,因为它使它更复杂,但如果解决方案使用了文件描述符,那么可能应该添加它以保证完整性。

0 个答案:

没有答案