【问题标题】:Cassandra composite key queriesCassandra 组合键查询
【发布时间】:2014-08-07 04:18:45
【问题描述】:

这更像是一个设计问题。

假设我有这张表(为了便于阅读,省略了大部分列):

CREATE TABLE IF NOT EXISTS users (
userid uuid,
emailaddress text,
passwordhash text,
passwordsalt text,
datecreated timestamp,
PRIMARY KEY (userid, emailaddress)
);

在这张表上,我有时需要通过 emailaddress 获取 userid,其他时候,只需使用 userid 获取其余值,因此查询是:

  1. 通过emailaddress搜索,获取userid并在其他地方使用
  2. userid 搜索,获取特定用户的所有值并在其他地方使用。

仅通过 userid 查询有效,因为它是复合键表中的第一个键,但对于通过 emailaddress 查询(事先不知道用户 ID),我将不得不打开 ALLOW FILTERING,这是强烈不鼓励的.

问题是:知道这种设计在 Cassandra 的运行方式方面并不好,否则我将如何实现我的目标(通过 useridemailaddress 获取用户详细信息)?我应该创建 2 个这样的表吗?

CREATE TABLE IF NOT EXISTS users (
userid uuid,
passwordhash text,
passwordsalt text,
datecreated timestamp,
PRIMARY KEY (userid)
);

CREATE TABLE IF NOT EXISTS useremails (
emailaddress text,
userid uuid,
PRIMARY KEY (emailaddress)
);

或者有没有更简洁的方法来实现我想做的事情?对于我对 Cassandra 的来龙去脉缺乏了解,我提前道歉。我仍在学习它并尝试从正确的角度解决问题,而不是破解(ALLOW FILTERING 允许我这样做)。

非常感谢,

【问题讨论】:

    标签: cassandra


    【解决方案1】:

    Cassandra 将数据存储在分区中,主键定义中的第一个键是分区键。您希望查询命中单个(或至少 n 个)分区,而不是进行集群范围的搜索(这是允许过滤所允许的)。

    你有第二张桌子的想法是个好主意。我会同意的。请记住,两个 1 毫秒的查询比一个 2 秒的查询要好 :)

    【讨论】:

    • 谢谢你。然后,我将添加第二个(可能还有第三个表)。我想我必须习惯 Cassandra 需要的过度非规范化:)。
    【解决方案2】:

    如果您期望有大量用户,您自己管理带有索引的第二张表是一个不错的选择。如果预期的用户数量稍低(约 10-50 百万),您也可以使用二级索引。此选项在Cassandra 1.1 documentation 中讨论。由于您似乎使用的是 Cassandra 2.0,您可能也想看看 Cassandra 2.0 documentation

    何时使用二级索引

    Cassandra 的内置二级索引最适合列族 有许多包含索引值的行。越独特 特定列中存在的值,您将获得更多开销 平均而言,有查询和维护索引。例如, 假设您有一个包含十亿用户的用户表,并且想要查看 按他们居住的州增加用户。许多用户将共享相同的 州的列值(例如 CA、NY、TX 等)。这将是一个 二级索引的好候选。

    何时不使用二级索引

    不要使用二级索引来查询大量记录 少量结果。例如,如果您在列上创建索引 有许多不同的值,字段之间的查询将产生 许多人寻求的结果很少。在十亿的列族中 用户,通过他们的电子邮件地址查找用户(一个值是 通常每个用户都是唯一的)而不是他们的状态,很可能 非常低效。可能会更有效率 手动维护动态列族作为索引的一种形式 而不是使用二级索引。对于包含唯一的列 数据,有时使用二级索引在性能方面很好 为方便起见,只要查询量到索引列 家庭适中,不承受恒定负荷。

    构建和使用二级索引

    二级索引的一个优点是易于操作 填充和维护索引。二级索引是内置的 后台自动,不会阻塞读取或写入。 客户端维护的列族作为索引必须手动创建; 例如,如果 state 列已通过创建列进行索引 像 users_by_state 这样的家庭,您的客户端应用程序必须 使用来自 users 列族的数据填充列族。

    如您所见,您有 2 个选项,如果表的预期大小相当小,则使用二级索引使其立即工作而无需更改太多代码,或者如果应用程序使用 2 个表设置如果太大,或者如果您希望它在未来扩展到该级别。

    始终尽量避免使用 ALLOW FILTERING,

    希望对你有帮助!

    【讨论】:

    • 非常感谢塞尔吉奥。由于该应用程序处于起步阶段并且仍在开发中,因此我可以更改代码以添加第二个表。我查看了索引,但正如您提到的文章指出的那样,由于我的电子邮件地址都是唯一的,二级索引似乎效率低下。再次感谢。顺便说一句,我只希望拥有超过 5000 万用户 :)。
    • 强烈建议您不要使用二级索引通过电子邮件搜索用户。未命中分区的基于二级索引的查询是集群范围的查询。二级索引用于低基数列 - 在您的情况下,每个用户可能有不同的电子邮件(高基数)。如果您遇到包含大量行的分区并且需要在分区内进行搜索,二级索引会更有帮助。避免在查询中未命中分区的情况下使用二级索引(即始终按主键中的第一列进行过滤)。
    • 是的灰烬。这就是我在评论中添加的内容。我不会在这个实例中使用二级索引,因为正如你所指出的,这些值分布很广,而是使用一个新表来保存这些数据。非常感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-10
    • 2015-08-09
    • 2014-11-17
    • 1970-01-01
    • 2017-11-12
    相关资源
    最近更新 更多