设置SQLite数据库以进行群集分析

时间:2015-03-28 22:54:45

标签: python sqlite cluster-analysis database-performance

我对数据库完全陌生。我想就如何设置和使用SQLite数据库进行集群分析和主题建模任务获得一些建议。

我有一个2 GB的文件,其中每一行都是一个json对象。以下是文件中的示例json对象:

{"body": "Heath Ledger's Joker...", "subreddit_id": "t5_2qh3s", "name": "t1_clpmhgo", "author": "l3thaln3ss", "created_utc": "1414799999", "subreddit": "movies", "parent_id": "t3_2kwdi3", "score": 1, "link_id": "t3_2kwdi3", "sub_type": "links - high"}

我创建了一个SQLite数据库,如下所示:

import json
import sqlite3
import sys

def main(argv):
    if len(argv) != 2:
        sys.exit("Provide a database name.")

    dbName = argv[1]
    db = sqlite3.connect(dbName)

    db.execute('''CREATE TABLE IF NOT EXISTS Comments
              (name text primary key,
               author text,
               body text,
               score integer,
               parent_id text,
               link_id text,
               subreddit text,
               subreddit_id text,
               sub_type text,
               created_utc text,
               foreign key (parent_id) references Comment(name));''')

    db.commit()
    db.close()

if __name__ == "__main__":
    main(sys.argv)

这是数据库的良好初始设置吗?

我像这样填充数据库:

import json
import sqlite3
import sys

def main(argv):
    if len(argv) != 2:
        sys.exit("Provide a comment file (of json objects) name.")

    fname = argv[1]

    db = sqlite3.connect("commentDB")
    columns = ['name', 'author', 'body', 'score', 'parent_id', 'link_id', 'subreddit', 'subreddit_id', 'sub_type', 'created_utc']

    query = "insert or ignore into Comments values (?,?,?,?,?,?,?,?,?,?)"

    c = db.cursor()

    with open(fname, 'r') as infile:
        for comment in infile:
            decodedComment = json.loads(comment)
            keys = ()
            for col in columns:
                keys += (decodedComment[col],)
            print str(keys)
            print
            c.execute(query, keys)

    c.close()
    db.commit()
    db.close()


if __name__ == "__main__":
    main(sys.argv)

最终,我将基于评论中的共享频繁词汇来聚集子搜索,用户通过分析在subreddit注释中找到的词语来评论主题模型的位置和差异。请注意,我还有更多2 GB的文件,所以理想情况下,解决方案应该是相对可扩展的。关于如何设置(特别是通过改进我所写的)数据库来完成这类工作的任何一般性建议将不胜感激。

谢谢!

编辑:删除了有关插入效果的问题。

2 个答案:

答案 0 :(得分:1)

一些小的改进表明了自己 - 例如CREATE TABLE Comments references Comment(name)有一个Comment,我很确定Comments拼写错误,你的意思是keys(因此发布的代码不起作用)。

速度方面,将特殊名称tuple构建为list有点浪费 - keys = () for col in columns: keys += (decodedComment[col],) 会好得多,即替换

        keys = [decodedComment[col] for col in columns]

execute

稍微好一点的性能(可能没有明确记录,但是光标的PostgreSQL方法需要第二个arg,这个列表就像一个元组一样快乐。)

但总的来说你有一个良好的开端 - 在摄取单个2GB输入文件后应该没问题。 然而,sqlite,在许多方面都很棒,对于那个大小的倍数来说,它并没有真正扩展 - 你需要一个“真正的”数据库。我建议使用MySQL但可能MariaDB(及其变种,例如body)和商业(非开源)产品也可以。

如果“更多”(2GB文件)你的意思是数百甚至数千,甚至“严重”的专业数据库可能会在某些时候开始在接缝处吱吱作响,这取决于你计划向它们投射的具体处理方式;提到“评论中的每一个字”(暗示我想象{{1}}字段需要处理 - 源于&c;到一个单词集合中)在承诺非常繁重的处理方面略显令人担忧。

一旦成为问题,“NoSQL”产品或者严重意味着扩展,例如BigQuery,可能值得您花时间。但是,对于小规模的实验,你肯定可以从sqlite开始,并用它来开发你想到的“聚类”的算法;然后扩展到PostgreSQL或其他什么来检查那些在中等规模工作上的规模;只有在这一点上,如果需要,还需要额外的工作来考虑非关系解决方案,虽然非常强大,但往往需要对某些访问模式的承诺(关系数据库,你可能需要的最多的是增加索引,可能更适合更多的实验阶段游戏!)。

答案 1 :(得分:1)

传统的SQL和NoSQL数据库对于这样的分析并不是特别有用。缺乏允许精确获得相似性的能力,或者无法通过聚类算法加速查询的能力。

在大多数实际使用中,您最终会得到这样的工作流程:

  1. 将数据库中的数据加载到分析应用程序中(通常将其转储为某种CSV格式)
  2. 执行分析
  3. 将结果写回数据库
  4. 这不是很漂亮或有效,肯定会让你失望。但鉴于即使在商业报价中缺乏分析灵活性,我们也得到了所有这些。甚至一些商业报价中提供的分析功能 - 它具有足够的功能 - 通常也是这样的。

    在您的特定用例中,可以使用Lucene作为后备数据库。如果你有一个可以通过Lucene查询加速的聚类算法实现,那就是。