如何在Cassandra中按ID或日期选择数据?

如何在Cassandra中按ID或日期选择数据?,cassandra,Cassandra,我有一个非常简单的数据表。但在阅读了大量的互联网示例后,我仍然越来越困惑如何解决以下场景: 1)表格 我的数据表如下所示(没有定义primayr键,因为这是我理解的问题): 现在我的目标是使用不同的方法来选择数据 2)按UID选择: SELECT * FROM documents WHERE uid = ‘xxxx-yyyyy-zzzz’ 3)按日期限制选择 SELECT * FROM documents WHERE created >= ‘2015-06-05’ 所以

我有一个非常简单的数据表。但在阅读了大量的互联网示例后,我仍然越来越困惑如何解决以下场景:

1)表格

我的数据表如下所示(没有定义primayr键,因为这是我理解的问题):

现在我的目标是使用不同的方法来选择数据

2)按UID选择:

SELECT * FROM documents
    WHERE uid = ‘xxxx-yyyyy-zzzz’
3)按日期限制选择

SELECT * FROM documents
    WHERE created >= ‘2015-06-05’
所以我的问题是:


我在Cassandra中的表定义应该是什么样的,这样我才能执行这些选择?

要实现这两个查询,需要两个表。 第一个看起来像:

CREATE TABLE documents (
    uid text,
    created text,
    data text,
    PRIMARY KEY (uid));
您可以通过以下方式检索数据:
SELECT*,其中uid='xxxx-yyyy-zzzzz'
当然,uid必须是唯一的。您可能需要考虑UUID数据类型(而不是文本)

第二个更微妙。如果将分区设置为完整日期,则无法执行范围查询,因为范围查询仅在“群集”列上可用。因此,您需要找到分区密钥的最佳位置,以便:

  • 确保单个分区不会太大(最大100MB, 否则你会遇到麻烦)
  • 满足您的查询要求
  • 例如:

    CREATE TABLE documents_by_date (
        year int,
        month int,
        day int,
        uid text,
        data text,
        PRIMARY KEY ((year, month), day, uid);
    

    如果在一天内,您没有太多文档(这样您的分区就不会增长太多),那么这种方法可以很好地工作。这允许您创建查询,例如:
    SELECT*FROM documents\u by\u date,其中year=2018,month=12,day>=6,day问题不指定您的数据将如何与用户和创建时间相关。但由于它是一个文档,我假设一个用户将在一次“创建”的时间创建一个文档

    下面是您可以使用的表定义

    CREATE TABLE documents (
        uid text,
        created text,
        data text
        PRIMARY KEY (uid, created)
    ) WITH CLUSTERING ORDER BY (created DESC);
    
    使用CLUSTERING ORDER BY(created DESC),可以帮助您通过为给定用户创建的方法获取数据顺序

    对于您的第一个需求,您可以像下面给出的那样进行查询

    SELECT * FROM documents WHERE uid = 'SEARCH_UID';
    
    对于您的第二个需求,您可以查询如下所示

    SELECT * FROM documents WHERE created > '2018-04-10 11:32:00' ALLOW FILTERING;
    

    在扫描所有分区时,应认真使用允许筛选。如果我们必须创建一个单独的表,并将日期作为主键,那么如果在同一秒插入多个文档,这将变得很棘手。集群顺序最适合于给定用户的文档需要按时间排序的需求。

    第一个表中每个用户不能有多个文档,因为主键只有UID。我目前假设UID后面的含义是“唯一id”。如果意思是“用户id”,那么它肯定需要更改。好的,让它更清楚。UID是来自另一个系统的唯一id。我需要这个密钥来获取一个特定的数据条目。因此,第一张表是明确的。创建日期用于在不知道UID的情况下获取数据。一个文档需要1-100MB。所以我知道documents_by_date表不应该复制数据列-对吗?从select语句中,可以按确切的年/月或年/月/日进行选择。因此,对于第二个表,该表的分区应始终低于100MB。那么您建议使用两个表吗?不建议使用Cassandra存储大文件(大于几MB)。您可以将其存储在单独的文件系统中,并将链接/url保存在Cassandra中吗?AWSS3就是一个很好的例子。另外,请记住,Cassandra节点密度不应超过2TB,存储大文件会使其非常昂贵。您仍然需要两个表来实现两个查询。如果在prod中使用一个带有“允许筛选”的表,则性能会很差,并且没有可扩展性。uid是唯一标识符,不是特定于用户的。我的来源是一个工作流系统,它将数据归档到表中。每个文档条目都是唯一的。但创建日期对于从特定时间点选择存档数据非常重要。因为uid是唯一标识符,每个记录的数据大小可以在1到100 MB之间。你认为一张桌子还是个好办法吗?或者我应该把日期分到第二张表中?也可以只选择特定的日期或月份。因此,我实际上不需要一个更大/更低的select语句。你觉得怎么样?啊,我明白了。如果它不是特定于用户的,那么只保留它作为主键就可以了。考虑到您在按特定日期提取的需求方面具有灵活性,我认为使用Christophe建议的2表方法更有意义。但为了简单起见,我建议使用纪元时间而不是年和月。按日期创建表文档(创建时间bigint、uid文本、数据文本、主键(创建时间、uid));谢谢您的回答。我将使用这两个表。
    SELECT * FROM documents WHERE created > '2018-04-10 11:32:00' ALLOW FILTERING;