如何在这种特殊情况下对cassandra进行建模?

时间:2016-01-13 09:48:25

标签: cassandra

如果我有下面的表结构,我该如何通过

查询
"source = 'abc' and created_at >= '2016-01-01 00:00:00'"?

CREATE TABLE articles (
    id text,
    source text,
    created_at timestamp,
    category text,
    channel text,
    last_crawled timestamp,
    text text,
    thumbnail text,
    title text,
    url text,
    PRIMARY KEY (id)
)

我想根据这个建模我的系统: http://www.ebaytechblog.com/2012/07/16/cassandra-data-modeling-best-practices-part-1/

编辑:

我们所做的与您提出的建议非常相似。区别在于我们的主键没有括号源: PRIMARY KEY (source, created_at, id)。我们还有另外两个索引:

CREATE INDEX articles_id_idx ON crawler.articles (id); 
CREATE INDEX articles_url_idx ON crawler.articles (url); 

我们的系统真的很慢。你有什么建议?

感谢您的回复!

2 个答案:

答案 0 :(得分:4)

给定表结构

CREATE TABLE articles (
    id text,
    source text,
    created_at timestamp,
    category text,
    channel text,
    last_crawled timestamp,
    text text,
    thumbnail text,
    title text,
    url text,
    PRIMARY KEY ((source),created_at, id)
)

您可以发出以下查询:

SELECT * FROM articles WHERE source=xxx // Give me all article given the source xxx

SELECT * FROM articles WHERE source=xxx AND created_at > '2016-01-01 00:00:00'; // Give me all articles whose source is xxx and created after 2016-01-01 00:00:00

主键中的couple(created_at,id)用于保证文章的唯一性。实际上,在同一个created_at时间,可能有两篇不同的文章

答案 1 :(得分:1)

鉴于来自previous question you posted的知识,我说索引会降低您的查询速度,您需要解决两件事:

  1. 仅在文章尚不存在的情况下撰写文章
  2. 根据
  3. 创建的源和范围查询查询文章

    基于这两个,我会选择两个表:

    反向索引表

    CREATE TABLE article_by_id (
        id text,
        source text,
        created_at timestamp,
        PRIMARY KEY (id) ) WITH comment = 'Article by id.';
    

    此表格将用于在文章首次到达时插入文章。基于INSERT ... IF NOT EXISTS之后的return语句,您将知道文章是现有的还是新的,如果它是新的,您将写入第二个表。此表还可用于根据文章ID查找第二个表的所有关键部分。如果您需要完整的文章数据,您可以添加到此表以及所有字段(类别,频道等)。这将是一个瘦的行,只保留一个分区中的单个文章。

    INSERT示例:

    INSERT INTO article_by_id(id, source, created_at) VALUES (%s,%s, %s) IF NOT EXISTS; 
    

    无论是否应用此查询,Java驱动程序都返回true或false。可能它在python驱动程序中是相同的但我没有使用它。

    按来源排列查询和查询的表

    由于doanduyhai建议您创建第二个表:

    CREATE TABLE articles (
        id text,
        source text,
        created_at timestamp,
        category text,
        channel text,
        last_crawled timestamp,
        text text,
        thumbnail text,
        title text,
        url text,
        PRIMARY KEY ((source),created_at, id)
    )
    

    在此表中,只有在第一次INSERT返回true时才会写入,这意味着您有新文章,而不是现有文章。此表将按来源提供范围查询和查询。

    改进建议

    timeuuid使用timestamp代替created_at,您确定没有两篇文章可以拥有相同的created_at,您可以将id全部放在一起并依赖{{1} }}。但是从第二个问题我可以看出你依赖外部id,所以想把它作为旁注。