我的数据模型非常简单。它可以模拟对网页的访问。
这是我的Visit模型的样子(语法为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
我将要使用多种不同的方式来查询数据。
因此,鉴于各种不同类型的查询,我应该如何存储此模型?
我目前基本上具有完全相同的字段,这些字段存储在具有不同主键的多个表中(一个表仅包含(id)以支持“获取所有用户的所有访问”,另一个表具有(id,userId)以支持“获取特定用户的所有访问次数”,等等。
感觉就像它创建数据的多个副本只是为了支持本质上相同的查询,但where子句有一个附加条件。
是否有更好的方法对此建模?
答案 0 :(得分:0)
关于问题1:由于URL的组件始终具有相同的键(主机,端口,路径等),因此将它们作为单独的列而不是映射具有更高的效率。尤其是在Cassandra 3(或即将推出的Scylla 3.0)中,新的,更有效的文件格式不需要为每一行重复列名-但是这种重复对于映射来说是必需的(理论上,它们可能会有不同键)。
关于问题2:您可以做一件事,而不是自己维护多个表(并且始终担心这些不同表的内容是否一致),您可以使用“物化视图”功能(再次在Cassandra 3和Scylla中添加) 3)为您维护所有这些不同的表。对于所有这些表,这仍然需要磁盘上的额外存储空间,但是会简化您的应用程序。 您可以做的另一件事是使用二级索引-二级索引不会复制所有数据,而是创建其他索引表以允许在表中查找原始数据。例如,在给定URL路径的情况下,将使用这种辅助表来获取具有此路径的访问列表(原始表的键)。但是您不需要自己维护该表-您需要做的只是要求为特定列建立索引,Cassandra会自动为您维护该表并将其用于查询中以查询该列的某个值。