【问题标题】:Cassandra: select only latest rowsCassandra:只选择最新的行
【发布时间】:2016-04-06 13:30:57
【问题描述】:

我使用下表:

CREATE TABLE IF NOT EXISTS lp_registry.domain (
    ownerid text,
    name1st text,
    name2nd text,
    name3rd text,
    registrar text,
    registered timestamp,
    expiration timestamp,
    updated timestamp,
    technologies list<text>,
    techversions list<text>,
    ssl boolean,
    PRIMARY KEY (
        (name1st, name2nd, name3rd), 
        registrar, ownerid, registered, expiration, updated
    )
);

表不会更新,只会添加新行。每次爬虫检查域时,都会添加新行。

我正在执行这个选择:

SELECT * FROM lp_registry.domain WHERE 
    registrar = 'REG-WEDOS' AND 
    ownerid = 'FORPSI-JAF-S497436' 
ALLOW FILTERING;

但我想要的结果只是每个唯一“name3rd.name2nd.name1st”具有最新“更新”值的行。

如果我在标准 SQL 数据库中,我会使用带有 MAX 或 GROUP BY 的嵌套选择。但是,Cassandra (MAX(), DISTINCT and group by in Cassandra) 不支持此功能。但是我应该在 CQL 中做什么?

【问题讨论】:

    标签: php cassandra cql cassandra-2.2 nosql


    【解决方案1】:

    扩展到Cedric's answer(这是一个很好的建议,并认为这是接受的答案)你会得到一个大致如下的表结构:

    CREATE TABLE IF NOT EXISTS lp_registry.domain (
        ownerid text,
        name1st text,
        name2nd text,
        name3rd text,
        registrar text,
        registered timestamp,
        expiration timestamp,
        updated timestamp,
        technologies list<text>,
        techversions list<text>,
        ssl boolean,
        PRIMARY KEY ((registrar, ownerid), updated, name1st, name2nd, name3rd)
    ) WITH CLUSTERING ORDER BY (updated desc);
    

    When selecting data it will return rows with the most recent updated values within the partition for the registrar and ownerid you are querying.

    此查询将非常快,因为您的数据将由注册商在磁盘上组织,所有者 ID 与行按更新降序排列。

    这是 cassandra 的一个关键概念,因为您的数据是根据您查询它的方式来组织的。您在查询中失去了灵活性,但您会感到很自在,因为您正在检索有组织的数据。这就是为什么根据您的查询对数据进行非规范化至关重要的原因。

    如果您想检索最近更新的所有数据,事情就会变得复杂起来。这个问题用 cassandra 不容易解决,除非所有东西都共享同一个分区,而这个分区有自己的一组问题 (example strategy using a 'dummy' partition key)。

    【讨论】:

    • 谢谢安迪。所以不可能在 cassandra stackoverflow.com/questions/22889722/… 中做这样的事情?
    • 如果不将所有内容放在同一个分区中,可能不会。或者,您可以使用 SparkSQL 之类的东西和 spark cassandra 连接器来进行更灵活的查询。
    【解决方案2】:

    应该修改整个架构。你正在做的SELECT,显然从你的应用程序的角度来看一个重要的不应该需要ALLOW FILTERING:你应该对你的数据进行非规范化并创建一个表,其中registrarownerid是分区键。

    在该非规范化结构中,updated 应该是一个分区键,按DESC 排序。查询将是

    SELECT * FROM lp_registry.domain WHERE registrar='XXX' AND ownerid='YYY' LIMIT 10;
    

    正如您所说的插入行但从不更新,在您的应用程序中将新数据插入到多个非规范化表中应该并不复杂(如果需要)。

    Andy's answer 为您的表结构提供更多详细信息和示例。

    【讨论】:

    • 非常感谢您的回复和建议。对不起我的问题,但我看不到只有最新行的唯一域名的技巧。该示例将为给定的注册商和所有者选择 10 个最近更新的域。但我将如何实现它们的独特性?
    • @Michal 我不确定我是否理解您的问题/评论,但我会在今天晚些时候尝试更新我的答案。
    猜你喜欢
    • 2019-11-06
    • 2014-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    相关资源
    最近更新 更多