0

我试图更好地了解我可以在 CQL3 中实际混合静态和动态列的级别。我在 CQL 3 中创建了一个表来存储用户订阅数据,但我也在测试在表中存储一个tenant_id(带有二级索引)的方法,以便我可以快速识别哪些用户属于哪些租户(租户是用户所属的更高级别的实体)。

我的创建表语句如下,然后是一些虚拟数据插入:

cqlsh:demodb> CREATE TABLE subscription_by_user (
              user_id text,
              tenant_id uuid,
              subscription_id int,
              type text,
              distribution int,
              PRIMARY KEY (user_id, subscription_id) );

cqlsh:demodb> CREATE INDEX subscription_ids ON subscription_templates_by_user (tenant_id);


cqlsh:demodb> INSERT INTO subscription_by_user (user_id, tenant_id, subscription_id, type, distribution) VALUES ('user1', f81d4fae-7dec-11d0-a765-00a0c91e6bf6, 2, 'MESSAGE', 4);

cqlsh:demodb> INSERT INTO subscription_by_user (user_id, tenant_id, subscription_id, type, distribution) VALUES ('user2', f81d4fae-7dec-11d0-a765-00a0c91e6bf6, 3, 'TOPIC', 5);

cqlsh:demodb> INSERT INTO subscription_by_user (user_id, tenant_id, subscription_id, type, distribution) VALUES ('user1', f81d4fae-7dec-11d0-a765-00a0c91e6bf6, 3, 'USER', 4);

这一切都很好,我得到了使用 cql 3 API 的期望:

cqlsh:demodb> SELECT * FROM subscription_by_user  ;

 user_id | subscription_id | distribution | tenant_id                            | type
---------+-----------------+--------------+--------------------------------------+------------
   user2 |               3 |            5 | f81d4fae-7dec-11d0-a765-00a0c91e6bf6 | TOPIC
   user1 |               2 |            4 | f81d4fae-7dec-11d0-a765-00a0c91e6bf6 | BOARD
   user1 |               3 |            4 | f81d4fae-7dec-11d0-a765-00a0c91e6bf6 | USER

但是,行的底层存储会导致 Cassandra 为每个新订阅复制tenant_id:

[default@demodb] list subscription_templates_by_user;
Using default limit of 100
Using default column limit of 100
-------------------
RowKey: user2
=> (column=3:, value=, timestamp=1366150799244000)
=> (column=3:distribution, value=00000005, timestamp=1366150799244000)
=> (column=3:tenant_id, value=f81d4fae7dec11d0a76500a0c91e6bf6, timestamp=1366150799244000)
=> (column=3:type, value=746573742d7479706532, timestamp=1366150799244000)
-------------------
RowKey: user1
=> (column=2:, value=, timestamp=1366150764854000)
=> (column=2:distribution, value=00000004, timestamp=1366150764854000)
=> (column=2:tenant_id, value=f81d4fae7dec11d0a76500a0c91e6bf6, timestamp=1366150764854000)
=> (column=2:type, value=746573742d74797065, timestamp=1366150764854000)
=> (column=3:, value=, timestamp=1366151741325000)
=> (column=3:distribution, value=00000004, timestamp=1366151741325000)
=> (column=3:tenant_id, value=f81d4fae7dec11d0a76500a0c91e6bf6, timestamp=1366151741325000)
=> (column=3:type, value=746573742d74797065, timestamp=1366151741325000)

我的问题是:有没有办法让我(使用 CQL 3)以每行仅列出一次 subscription_id 的方式构造表?如果没有,是否可以使用较旧的 cassandra-cli API 来执行此操作?看起来这将是一个可行的用例,实际上是一个将静态数据与动态数据(即订阅位)混合的问题,但我很可能是错的。我知道 map 和其他 CQL 3 集合类型是这样做的一种方式,但是我必须一次检索整个集合的事实让我有点紧张,我宁愿不将一些复杂的对象序列化到 map 值槽中,如果我可以帮助它。

谢谢!

4

1 回答 1

2

如果您不需要通过订阅执行范围查询,或者查询“用户X的所有订阅是什么”,那么您可以将其作为分区键的一部分:

CREATE TABLE subscription_by_user (
     user_id text,
     tenant_id uuid,
     subscription_id int,
     type text,
     distribution int,
     PRIMARY KEY ((user_id, subscription_id))
);

如果您确实需要其中任何一个,那就把它收起来并承担存储空间的损失;其中大部分将被压缩掉。无论您使用的是 CQL 还是 Thrift,这都是正确的。

于 2013-04-17T13:19:00.573 回答