【问题标题】: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 的运行方式方面并不好,否则我将如何实现我的目标(通过 userid 或 emailaddress 获取用户详细信息)?我应该创建 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
    相关资源
    最近更新 更多