首页 文章

如何在Cassandra中使用与其他列相同的TTL向集合中添加元素

提问于
浏览
2

我有一张 table

CREATE TABLE myTable (
    id bigint,
    other_id text,
    my_set SET<bigint>,
    my_date timestamp,
    PRIMARY KEY (id, other_id)
);

我想在所有列中都有一个共同的TTL,所以在TTL到期后,该行消失了 .

我设法用以下方法插入新行:

INSERT INTO myTable (id, other_id, my_date, my_set) 
VALUES (1,'foo','2014-10-20 12:05:08-0300', {22}) 
USING TTL 20;

我也可以更新我的集合添加新元素:

UPDATE myTable USING TTL 20 SET my_set=my_set + {99}
                             WHERE id=1 AND other_id='foo';

但我的问题是这个新元素有一个新的TTL,所以一段时间后,数字22消失,99仍然存在 .

How can I add a new element to my set with the same TTL of the other elements of the set?

我想的解决方案是提出两个问题:

  • 向my_date列询问他的TTL

  • 使用该TTL使UPDATE向my_set添加新元素

Is there a better solution?

2 回答

  • 0

    我不太了解您的解决方案正在努力实现的目标 . 但根据我的经验,大型集合中的TTL是坏消息(或者集合中有超过几十个元素) .

    无论如何,由于封面集以(name = setName:valueOfItem,value =)(see this article for more)的形式实现为离散列,你必须在顶部破解 . 我的建议是将集合封装在一个集群列中,如下所示:

    CREATE TABLE my_table (
        id bigint,
        other_id text,
        collection_ttl timeuuid,
        my_set SET<bigint>,
        my_date timestamp,
        PRIMARY KEY (id, other_id, collection_ttl)
    );
    

    collection_ttl可能只是插入时间,主要用于跟踪包含的Collection的TTL .

    或者您可以将您的Set展开到一个Clustering列中,并通过执行以下操作实现基本相同的操作:

    CREATE TABLE my_table_no_set (
        id bigint,
        other_id text,
        my_set_key bigint,
        my_set_value text,
        my_date timestamp,
        PRIMARY KEY (id, other_id, my_set_value)
    );
    

    如果你有一个相当大的集合,这对Cassandra来说会更友好,你可以在order_id或类似的东西上做一个TTL .

  • 1

    您可以在 SELECT 中使用 TTL() 函数

    SELECT TTL(my_set) FROM myTable;
    

    然后使用该值......但我认为这不会对您要做的事情起作用 .

    相反,我会添加创建行的日期 . 或多或少,这样的事情:

    CREATE TABLE myTable (..., created_on timestamp);
    INSERT INTO myTable (..., created_on) VALUES (..., toTimestamp(now()));
    ...
    SELECT created_on FROM myTable WHERE ...
    INSERT INTO myTable ... USING TTL now - created_on ...
    

    (而不是 toTimestamp(now()) ,您可能必须使用 dateOf(now()) ,具体取决于您使用的CQL版本; see documentation . 当然,您也可以使用自己的时间戳值 . )

    如果 now - created_on 小于1,则不应处理该INSERT . (实际上,我在某处读到TTL的最小值应该至少为3秒,但对于数据库TTL来说,即使是3也非常小...)

    还有一个 writetime() 功能 . 但我不太确定这对你是否有用 . 你当然可以尝试一下:

    SELECT writetime(id) FROM myTable WHERE ...
    

    writetime() 在UPDATE上更改的可能性不大,但我不知道它是按列还是按行更改,并且不建议将此类系统信息用于您自己的数据(How to retrieve the timestamp from cassandra?) .

相关问题