【问题标题】:Query results not ordered despite WITH CLUSTERING ORDER BY尽管 WITH CLUSTERING ORDER BY,但查询结果未排序
【发布时间】:2015-01-07 07:46:39
【问题描述】:

我将所有用户的帖子存储在表中。我想检索用户关注的所有用户的帖子。

CREATE TABLE posts (
  userid int,
  time timestamp,
  id uuid,
  content text,
  PRIMARY KEY (userid, time)
)WITH CLUSTERING ORDER BY (time DESC)

我在另一个表中有关于所有用户关注谁的数据

CREATE TABLE follow (
  userid int,
  who_follow_me set<int>,
  who_i_follow set<int>,
  PRIMARY KEY ((userid))
) 

我正在查询类似

select * from posts where userid in(1,2,3,4....n);

2 个问题:

  1. 为什么我仍然以随机顺序获取数据,尽管在帖子中指定了 CLUSTERING ORDER BY。 ?
  2. 模型是否正确以最佳地满足查询(用户可以有 n 个关注者)?

我正在使用 Cassandra 2.0.10。

【问题讨论】:

    标签: cassandra cql


    【解决方案1】:

    “为什么我仍然以随机顺序获取数据,尽管帖子中指定了 CLUSTERING ORDER BY?”

    这是因为ORDER BY 仅适用于特定分区键中的行。因此,在您的情况下,如果您想查看特定用户的所有帖子,如下所示:

    SELECT * FROM posts WHERE userid=1;
    

    这将返回按time 排序的结果,因为userid=1 分区键中的所有行都将由它聚集。

    “模型是否正确以最佳地满足查询(用户可以有n个关注者)?”

    只要您不关心按时间戳排序的结果,它就会起作用。为了能够查询按时间排序的所有用户的帖子,您需要提供不同的分区键。在不太了解您的应用程序的情况下,您可以使用 GROUP 之类的列(例如)并对其进行分区。

    假设您将所有用户平均分配到八个组:A、B、C、D、E、F、G 和 H。假设您的表格设计更改如下:

    CREATE TABLE posts (
      group text,
      userid int,
      time timestamp,
      id uuid,
      content text,
      PRIMARY KEY (group, time, userid)
    )WITH CLUSTERING ORDER BY (time DESC)
    

    然后您可以像这样查询 B 组所有用户的所有帖子:

    SELECT * FROM posts WHERE group='B';
    

    这将为您提供 B 组中所有用户的所有帖子,按时间排序。因此,基本上,为了让您的查询按时间适当地对帖子进行排序,您需要将帖子数据分区到用户 ID 以外的其他内容上。

    编辑

    PRIMARY KEY (userid, follows)) WITH CLUSTERING ORDER BY (created DESC);
    

    那是行不通的。实际上,这应该会产生以下错误:

    code=2200 [无效查询] message="Missing CLUSTERING ORDER for column follow"

    即使您确实将 follows 添加到您的 CLUSTERING ORDER 子句中,您也会看到:

    code=2200 [Invalid query] message="CLUSTERING ORDER 指令中只能定义聚类键列"

    CLUSTERING ORDER 子句只能用于集群列,在这种情况下,集群列仅是 follows 列。将您的 PRIMARY KEY 定义更改为在 follows (ASC) 和 created (DESC) 上进行聚类。我已经对此进行了测试,并插入了一些示例数据,并且可以看到该查询有效:

    aploetz@cqlsh:stackoverflow> SELECT * FROM posts WHERE userid=2 AND follows=1;
    
     userid | follows | created                  | id
    --------+---------+--------------------------+--------------------------------------
          2 |       1 | 2015-01-25 13:27:00-0600 | 559cda12-8fe7-45d3-9a61-7ddd2119fcda
          2 |       1 | 2015-01-25 13:26:00-0600 | 64b390ba-a323-4c71-baa8-e247a8bc9cdf
          2 |       1 | 2015-01-25 13:24:00-0600 | 1b325b66-8ae5-4a2e-a33d-ee9b5ad464b4
    
    (3 rows)
    

    不过,如果您只想通过 userid 进行查询,您可以看到所有关注者的帖子。但在这种情况下,帖子只会在每个 followerid 中进行排序,如下所示:

    aploetz@cqlsh:stackoverflow> SELECT * FROM posts WHERE userid=2;
    
     userid | follows | created                  | id
    --------+---------+--------------------------+--------------------------------------
          2 |       0 | 2015-01-25 13:28:00-0600 | 94da27d0-e91f-4c1f-88f2-5a4bbc4a0096
          2 |       0 | 2015-01-25 13:23:00-0600 | 798053d3-f1c4-4c1d-a79d-d0faff10a5fb
          2 |       1 | 2015-01-25 13:27:00-0600 | 559cda12-8fe7-45d3-9a61-7ddd2119fcda
          2 |       1 | 2015-01-25 13:26:00-0600 | 64b390ba-a323-4c71-baa8-e247a8bc9cdf
          2 |       1 | 2015-01-25 13:24:00-0600 | 1b325b66-8ae5-4a2e-a33d-ee9b5ad464b4
    
    (5 rows)
    

    【讨论】:

    • 这个答案肯定给出了一些更好的方向,但我想从我关注的所有用户中按时间降序获取所有帖子。我将在下面提供我的新架构
    【解决方案2】:

    这是我的新架构,

    CREATE TABLE posts(id uuid, 
    userid int,
    follows int,
    created timestamp,
    PRIMARY KEY (userid, follows)) WITH CLUSTERING ORDER BY (created DESC);
    

    这里的 userid 代表谁发布了它,follows 代表他的追随者之一的用户 ID。假设用户 x 关注了 10 个其他人,我正在制作 10+1 个插入。肯定有太多的数据重复。然而,现在通过以下查询更容易为其中一位用户获取时间表

    select * from posts where follows=?
    

    【讨论】:

      猜你喜欢
      • 2013-01-14
      • 1970-01-01
      • 1970-01-01
      • 2021-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-22
      相关资源
      最近更新 更多