cassandra表反规范化的适当方法,以支持具有附加参数的类似查询

js81xvg6  于 2021-06-15  发布在  Cassandra
关注(0)|答案(1)|浏览(328)

我的数据模型非常简单。它模拟了对网页的访问。
这就是我的访问模型的样子(语法是express cassandra schema语法):

fields: {
    id: {
        type: 'uuid',
        rule: {
            required: true,
            message: 'id is required'
        }
    },
    userId: {
        type: 'int',
        rule: {
            required: true,
            message: 'userId is required'
        }
    },
    dateOfVisit: {
        type: 'timestamp',
        rule: {
            required: true,
            message: 'dateOfVisit is required'
        }
    },
    urlPort: 'int',
    urlHost: {
        type: 'text',
        rule: {
            required: true,
            message: 'urlHost is required'
        }
    },
    urlPath: 'text',
    urlQuery: 'text',
    urlProtocol: {
        type: 'text',
        rule: {
            required: true,
            message: 'urlProtocol is required'
        }
    },
    urlHash: 'text',
    pageTitle: 'text'
},
key: [['id'], 'dateOfVisit'],
clustering_order: {'dateOfVisit': 'desc'}

我对这种模式有几个问题:
问题1:
我很确定我想存储url的部分,而不是将整个url存储为单个字符串,因为它允许我更轻松地运行查询,以访问特定域、访问域中的特定路径、访问安全页与访问不安全页、从安全页到不安全页(或相反)的链接等。
但是,将url的各个部分存储为a)单个列还是b)单个Map列更好。
另外,我是否需要用不同的主键创建额外的表来支持在url的不同部分上进行查询的所有不同查询?
问题2
我将有很多不同的方法来查询数据。
获取所有用户的所有访问
获取单个用户的所有访问
在某一天或某一天内按小时安排所有访问
获取对给定域的所有访问
对按路径分组的给定域的所有访问进行计数
因此,考虑到各种不同类型的查询,我应该如何存储这个模型?
目前,我在多个表中存储了完全相同的字段,只是主键不同(一个表的just(id)支持“获取所有用户的所有访问”,另一个表的(id,userid)支持“获取特定用户的所有访问”,等等)。
这感觉就像它创建了数据的多个副本,只是为了支持基本上相同的查询,但是where子句有一个附加条件。
有没有更好的方法来模拟这个?

nwnhqdif

nwnhqdif1#

关于问题1:由于url的组件总是具有相同的键(主机、端口、路径等),因此将它们作为单独的列而不是Map更有效。尤其是在cassandra 3(或即将推出的scylla 3.0)中,新的、更高效的文件格式不需要为每一行重复列名,但是这种重复对于一个Map来说是必要的(理论上,在每个示例中都可能有不同的键)。
关于问题2:您可以做一件事,而不是自己维护几个表(并且总是担心这些不同表的内容是否一致),您可以使用物化视图功能(同样,在cassandra 3和scylla 3中添加),它为您维护所有这些不同的表。这仍然需要磁盘上为所有这些表提供额外的存储空间,但会简化应用程序。您可以做的另一件事是使用辅助索引—它不会复制所有数据,而是创建额外的索引表,以便在表中查找原始数据。e、 例如,在给定url路径的情况下,这样一个辅助表将用于获取具有此路径的访问列表(原始表的键)。但是您不需要自己维护这个表—您所需要做的只是请求索引一个特定的列,cassandra将自动为您维护这个表,并在搜索这个列的特定值的查询中使用它。

相关问题