0

我是 Casssandra 的新手,我觉得很难实现数据模型。

我在设计一张桌子时遇到了很多问题。

在我提到表定义之前,我想向您展示我们必须检索和更新记录的方法

select * from email where username='suresh' and inactive='N' and type='outbound'
    order by insert_ts desc allow filtering;
update email set inactive='Y' where username='suresh' and inactive='N' 
    and id=101;

要创建一个表,我应该遵循所有 cassandra 定义的规则。我在为表创建索引时遇到了问题

如果我像这样创建主键

PRIMARY KEY(username, inactive,type,insert_ts);

我能够检索记录,但是当我更新时,我收到错误消息“在集合中找到主键部分”错误。

如果我创建主键和辅助键,如下所示

PRIMARY KEY(username, type,insert_ts);
Secondary index = inactive;

我可以进行更新,但是当我检索时,我收到错误消息“二级索引将不允许使用 order by 子句”

我已经使用 cql 创建了电子邮件表,例如

Create table email(id int, username varchar, comment text, 
  inactive boolean, insert_ts timestamp, type varchar,
PRIMARY KEY(<<some columns yet to decide>>));

请建议我如何创建满足我查询的电子邮件表。

4

2 回答 2

0

根据您的信息,inactive不应该是主键的一部分,因为您打算随着时间的推移更改它而不创建新行。使用它作为基本假设,您需要使用PRIMARY KEY(username, type, insert_ts);.

您将无法同时按二级索引过滤和使用ORDER BY [anything]。从 2.0.3 开始,查询引擎不允许这样做。两种缓解方法是可能的:

1)不要做inactive索引,不要用它来过滤。

鉴于您的示例,inactive似乎是一个低基数值(Y 或 N),此外,您一次操作几行(您通过usernameand/or限制查询id)。因此,就结果数量而言,inactive从查询中省略不应该是昂贵的。使用时可以inactive在客户端过滤行SELECT

2)不要使用ORDER BY时间戳。

与上面相同,除了在客户端上进行过滤,您现在负责在客户端上进行排序。

应根据您的数据和用例来决定哪种缓解措施更合适。我的直觉是#1 是最好的方法,因为您要引入一个极低的基数,可能会频繁更新索引,以增加便利性。

于 2014-01-27T03:06:16.317 回答
0

感谢您的答复。

根据您的建议,我了解应从主键中删除基数较低的非活动列。我很好,我将在客户端进行非活动过滤。但是,在客户端过滤 insert_ts 并不能解决我的问题,因为该表中将存在数千条电子邮件记录。

Create table email(id int, username varchar, comment text,
  inactive boolean, insert_ts timestamp, type varchar,
PRIMARY KEY(username,type,insert_ts, id))
With Clustering(Type ASC, insert_ts desc, id asc);

另外我想在主键中添加 ID 列,因为我们需要显示限制为 100 的电子邮件记录。Cassandra 有 Limit 子句负责过滤,我可以使用 id 值来查找下一个 100 记录。

例如:

Select * from email where username='suresh' and type='outbound' 
  order by type,insert_ts desc, id 
Limit 101;

在这种情况下,我知道 101 条记录 ID,我将它用于需要获取下 100 条记录的请求。

我希望我能很好地理解它。如果您发现任何差距,请告诉我。

于 2014-01-27T07:52:01.037 回答