Java 卡桑德拉;关于索引的最佳实践?

Java 卡桑德拉;关于索引的最佳实践?,java,cassandra,Java,Cassandra,我正在对Cassandra模式进行建模,以便对该主题更加熟悉,并且想知道关于创建索引的最佳实践是什么 例如: create table emailtogroup(email text, groupid int, primary key(email)); select * from emailtogroup where email='joop'; create index on emailtogroup(groupid); select * from emailtogroup where grou

我正在对Cassandra模式进行建模,以便对该主题更加熟悉,并且想知道关于创建索引的最佳实践是什么

例如:

create table emailtogroup(email text, groupid int, primary key(email));
select * from emailtogroup where email='joop';
create index on emailtogroup(groupid);
select * from emailtogroup where groupid=2 ;
或者我可以创建一个完整的新表:

create table grouptoemail(groupid int, email text,  primary key(groupid, email));
select * from grouptoemail where groupid=2;
他们俩都做这项工作


我希望创建一个新表更快,因为现在groupid变成了分区键。但我不确定创建索引时发生了什么“魔法”,以及这种魔法是否有缺点。

这取决于groupid的基数。委员会:

不使用索引时

不要使用索引来查询大量记录以获取少量数据 结果的数量。例如,如果在 具有许多不同值的高基数列是一个查询 在这两个字段之间会产生许多搜索,但结果很少。在 表中有10亿用户,按用户的电子邮件地址查找用户(a 值,而不是由用户的 国家,很可能是非常低效的。可能会更糟 将表作为索引形式手动维护是非常有效的 使用卡桑德拉内置索引的方法。对于包含唯一 对于数据,有时使用索引进行索引是非常明智的 方便,只要查询卷到具有 索引列是中等的,不在恒定负载下

当然,不支持计数器列,其中每个 价值是不同的

相反,在极低的基数列上创建索引, 例如布尔列,没有意义。索引中的每个值 成为索引中的一行,导致所有 例如,假值。为多个索引列编制索引 让foo=true和foo=false没有用处

因此,基本上,如果您要处理一个大型数据集,并且groupid不会返回很多行,那么二级索引可能不是最好的主意


第4周讨论如何有效地建模这些问题。如果有机会,请检查一下。

这取决于groupid的基数。委员会:

不使用索引时

不要使用索引来查询大量记录以获取少量数据 结果的数量。例如,如果在 具有许多不同值的高基数列是一个查询 在这两个字段之间会产生许多搜索,但结果很少。在 表中有10亿用户,按用户的电子邮件地址查找用户(a 值,而不是由用户的 国家,很可能是非常低效的。可能会更糟 将表作为索引形式手动维护是非常有效的 使用卡桑德拉内置索引的方法。对于包含唯一 对于数据,有时使用索引进行索引是非常明智的 方便,只要查询卷到具有 索引列是中等的,不在恒定负载下

当然,不支持计数器列,其中每个 价值是不同的

相反,在极低的基数列上创建索引, 例如布尔列,没有意义。索引中的每个值 成为索引中的一行,导致所有 例如,假值。为多个索引列编制索引 让foo=true和foo=false没有用处

因此,基本上,如果您要处理一个大型数据集,并且groupid不会返回很多行,那么二级索引可能不是最好的主意


第4周讨论如何有效地建模这些问题。如果有机会,请检查一下。

根据我的说法,您的第一种方法是正确的

create table emailtogroup(email text, groupid int, primary key(email));
因为1)在您的情况下,电子邮件是一种独特的主键候选邮件,2)多封电子邮件可以属于同一组,是二级索引的候选邮件。请参阅本帖-

分区键用于在不同的节点之间分布数据,如果您希望节点之间保持平衡(即,在每个节点之间均匀分布数据),那么您希望分区键尽可能随机

第二种表格创建形式对范围扫描很有用。例如,如果您有这样一个用例

i) 列出用户在2010年1月1日至2013年1月1日期间加入的所有电子邮件组

在这种情况下,您可能需要设计一个类似

create table grouptoemail(email text, ts timestamp, groupid int, primary key(email, ts));

在这种情况下,用户加入的所有电子邮件将聚集在磁盘上。(一起存储在磁盘上)

根据我的说法,您的第一种方法是正确的

create table emailtogroup(email text, groupid int, primary key(email));
因为1)在您的情况下,电子邮件是一种独特的主键候选邮件,2)多封电子邮件可以属于同一组,是二级索引的候选邮件。请参阅本帖-

分区键用于在不同的节点之间分布数据,如果您希望节点之间保持平衡(即,在每个节点之间均匀分布数据),那么您希望分区键尽可能随机

第二种表格创建形式对范围扫描很有用。例如,如果您有这样一个用例

i) 列出用户在2010年1月1日至2013年1月1日期间加入的所有电子邮件组

在这种情况下,您可能需要设计一个类似

create table grouptoemail(email text, ts timestamp, groupid int, primary key(email, ts));

在这种情况下,用户加入的所有电子邮件gropus都将聚集在磁盘上。(一起存储在磁盘上)

感谢布莱斯的澄清,这有点像普通的二级索引,只是有点扭曲。我明天会检查给定的链接。感谢布莱斯的澄清,它有点像普通的二级索引,只是有点扭曲。明天我会查看给定的链接。约翰,要想让你正确思考这个问题有点困难。如果我理解正确:分区键的唯一性,除非你想切片,否则分区键需要在一起。和低唯一性(低基数)