难以定义 Cassandra 数据模型
Posted
技术标签:
【中文标题】难以定义 Cassandra 数据模型【英文标题】:Difficulty in defining Cassandra datamodel 【发布时间】:2014-01-26 08:02:26 【问题描述】:我是 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>>));
请建议我如何创建满足我查询的电子邮件表。
【问题讨论】:
【参考方案1】:根据您的信息,inactive
不应该是主键的一部分,因为您打算在不创建新行的情况下随时间更改它。使用它作为基本假设,您需要使用PRIMARY KEY(username, type, insert_ts);
。
您将无法同时按二级索引过滤和使用ORDER BY [anything]
。从 2.0.3 开始,查询引擎不允许这样做。有两种可能的缓解方法:
1) 不要将inactive
设为索引,也不要将其用于过滤。
鉴于您的示例,inactive
似乎是一个低基数值(Y 或 N),此外,您一次操作几行(您通过 username
和/或 @987654327 限制查询@)。因此,就结果数量而言,从查询中省略 inactive
应该不会很昂贵。使用SELECT
时,您可以在客户端过滤inactive
行。
2) 不要使用ORDER BY
时间戳。
与上面相同,除了在客户端进行过滤,您现在负责在客户端进行排序。
应根据您的数据和用例来决定哪种缓解措施更合适。我的直觉是,#1 是最好的方法,因为您引入了一个极低的基数,可能会频繁更新索引,以增加便利性。
【讨论】:
【参考方案2】:感谢您的回复。
根据您的建议,我了解应从主键中删除基数较低的非活动列。我很好,我将在客户端进行非活动过滤。但是,在客户端过滤 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 条记录的请求。
我希望我能很好地理解它。如果您发现任何差距,请告诉我。
【讨论】:
根据您目前提供的内容,您应该没有问题基于 insert_ts 进行过滤或排序。因为它是插入一行后永远不会改变的东西,您可以将其添加到主键中,然后根据原始帖子中的第一个 SELECT 查询在 WHERE 或 ORDER BY 中使用它(唯一的区别是,您不会不再在 WHERE 中处于活动状态)。 至于 id,我不认为你需要一个额外的列来做你想做的事。只需存储主键的最后一个返回值(用户名 + 类型 + insert_ts)并将该值用于分页,不需要额外的列。详情请看这个答案:***.com/questions/11832886/…。以上是关于难以定义 Cassandra 数据模型的主要内容,如果未能解决你的问题,请参考以下文章