0

我的数据模型非常简单。它模拟对网页的访问。

这是我的访问模型的样子(语法是express-cassandra 模式语法):

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'}

我对这个模型有几个问题:

问题一:

我很确定我想存储 URL 的各个部分而不是将整个 URL 存储为单个字符串,因为它允许我更轻松地运行查询以访问特定域、访问域中的特定路径、访问安全页面与访问不安全页面,从安全页面到不安全页面(或相反)的链接等。

但是,将 URL 的各个部分存储为 A) 单个列或 B) 作为单个 Map column 会更好吗

另外,我是否必须创建具有不同主键的附加表才能支持来自对 url 不同部分的查询的所有各种查询?

问题2

我将有许多不同的方式来查询数据。

  • 获取所有用户的所有访问
  • 获取单个用户的所有访问
  • 获取给定日期的所有访问量或在给定日期内按小时分组
  • 获取对给定域的所有访问
  • 计算对按路径分组的给定域的所有访问

那么,考虑到各种不同类型的查询,我应该如何存储这个模型?

我目前基本上将完全相同的字段存储在多个表中,只是具有不同的主键(一个表只有(id)支持“获取所有用户的所有访问”,另一个表(id,userId)支持“获取所有访问对于特定用户”等。

这就像它创建数据的多个副本只是为了支持基本相同的查询,但在 where 子句中添加了一个附加条件。

有没有更好的方法来建模这个?

4

1 回答 1

0

关于问题 1:由于 URL 的组件始终具有相同的键(主机、端口、路径等),因此将它们作为单独的列而不是映射更有效。尤其是在 Cassandra 3(或即将推出的 Scylla 3.0)中,新的、更高效的文件格式不需要为每一行重复列名 - 但这样的重复对于地图来说是必要的(理论上,这可能有不同的每个实例中的键)。

关于问题 2:您可以做一件事,而不是自己维护多个表(并且总是担心这些不同表的内容是否一致),您可以使用物化视图功能(再次,在 Cassandra 3 和 Scylla 3 中添加)为您维护所有这些不同的表格。这仍然需要所有这些表在磁盘上的额外存储空间,但会简化您的应用程序。您可以做的另一件事是使用二级索引 - 它不会复制所有数据,而是创建额外的索引表,以便在表中找到原始数据。例如,这样的辅助表将用于在给定 URL 路径的情况下获取具有该路径的访问列表(原始表的键)。但你不

于 2018-11-18T13:36:11.490 回答