1

我有创建社交提要(新闻提要)的任务。我认为没有必要解释标准功能 - 一切都像 FB 一样。我选择了解决方案apache cassandra并设计了一个数据列Posts用于存储有关帖子用户的信息:

CREATE TABLE Posts (
  post_id  uuid,
  post_at  timestamp,
  user_id  text,
  name     varchar,
  category set<text>,
  link     varchar,
  image    set<varchar>,
  video    set<varchar>,
  content  map<text, text>,
  private  boolean,

  PRIMARY KEY ((post_id, user_id), post_at)
)
WITH CLUSTERING ORDER BY (post_at DESC) COMPACT STORAGE;

下表包含 id 用户帖子:

CREATE TABLE posts_user (
  post_id  bigint,
  post_at  timestamp,
  user_id  bigint,
  PRIMARY KEY ((post_id), post_at, user_id)
)

WITH CLUSTERING ORDER BY (post_at DESC) AND COMPACT STORAGE;

你觉得怎么样,好不好?你对这样的数据模型做了什么改变?

4

1 回答 1

1

有几个问题和一些改进跳出来了。

  1. COMPACT STORAGE 现在已弃用(如果您想利用 CQL 3 功能)。我认为您不能Posts像上面定义的那样创建表,因为它使用 CQL 3 特性(集合)和 COMPACT STORAGE 以及声明多个不属于主键的列。

  2. posts_user具有完全不同的密钥类型Posts。我不清楚这两个表之间的关系是什么,但我想它们post_id之间应该是一致的,而你将它作为uuid一个表和另一个表bigint。与其他领域也存在差异。

  3. 假设post_id它是唯一的并且表示单个帖子的 id,将其作为Posts表中复合主键的第一部分是很奇怪的,因为如果您知道,post_id那么您已经可以唯一地访问该记录。此外,由于它是分区键的一部分,它还阻止您对多个帖子进行更广泛的选择并利用您的post_at排序。

解决此问题的常用方法是创建一个专用索引表,以按照您想要的方式对数据进行排序。

例如

CREATE TABLE posts (
  id       uuid,
  created  timestamp,
  user_id  uuid,
  name     text,
  ...
  PRIMARY KEY (id)
);

CREATE TABLE posts_by_user_index (
  user_id    uuid,
  post_id    uuid,
  post_at    timestamp,
  PRIMARY KEY (user_id,post_at,post_id)
  WITH CLUSTERING ORDER BY (post_at DESC)
);

或更全面地说:

CREATE TABLE posts_by_user_sort_index (
  user_id    uuid,
  post_id    uuid,
  sort_field text,
  sort_value text,
  PRIMARY KEY ((user_id,sort_field),sort_value,post_id)
);

但是,在您的情况下,如果您只想以一种方式选择数据,那么您可以使用posts表格进行排序:

CREATE TABLE posts (
  id       uuid,
  post_at  timestamp,
  user_id  uuid,
  name     text,
  ...
  PRIMARY KEY (user_id,post_at,id)
  WITH CLUSTERING ORDER BY (post_at DESC)
);

如果您希望稍后添加额外的索引,这只会使事情变得更加复杂,因为您不仅需要通过帖子 id 来索引每个帖子,还需要通过它的 user 和 post_at 字段来索引。

于 2014-08-26T23:26:28.363 回答