【问题标题】:Cassandra multi-dimensional datamodelCassandra 多维数据模型
【发布时间】:2017-08-10 18:54:25
【问题描述】:

我是 Cassandra 数据建模的新手,我有一个场景,如果可能的话,我需要在单行中容纳 多维 数据(是的,我知道 Cassandra 是列式存储)。我的示例数据集(试图简化我的用例,忍受我的格式)

时间戳、transaction_id、item_code、user_id、payment_method

20130304221518, abcd, 3, 6, 信用卡

20130304221519, efgh, 4, 5, cashondelivery

20130305180402, ijkl, 4, 5, cashondelivery

例如,payment_mode,user_id,item_code 是我的维度,我想聚合具有给定维度的数据集。我的简单聚合结果将是

payment_method = {cashondelivery = 2, credit card = 1)
Transaction_by_unique_user_id ={5 =2,6=1}
item_code = {item sold =3, Unique_item_sold (4 =2 ,3=1) }

请注意,在不久的将来,我可能需要添加更多维度,并且数据模型也应该适应这些维度。我想以 Cassandra 方式对其进行建模,并且我面前有以下方法。

  1. 每个维度的新表。
  2. 将维度添加为新列并使用map 作为数据类型。 如果您注意到我的一个结果item_code = {item sold =3, Unique_item_sold (4 =2 ,3=1) },这种结果不能以map 数据类型和维度作为列名来容纳。

  3. 将每个维度值作为新行插入单个表中。

还要注意,我会经常读取数据。所以读取不应该对我的数据模型造成性能影响。 *我的聚合将每 1 小时的数据发生一次,我使用 Spark 进行分析 *。请建议我正确的方法。任何建议都非常感谢。

【问题讨论】:

  • 您要汇总所有数据还是特定日期、月份或年份?
  • 基本上,聚合将在几分钟到几小时的数据集中发生。
  • 你的聚合结果是只有count(cashondelivery = 2)还是交易id列表?
  • 大部分是的.....

标签: apache-spark cassandra cql


【解决方案1】:

我认为,您必须定期插入大量数据。所以我们要慎重选择分区键,不让庞大的数据插入单个分区。虽然您每小时汇总一次结果,但我选择分区作为每小时间隔。

这是主表架构:

CREATE TABLE transaction (
    hour int,
    day int,
    month int,
    year int,
    transaction_id text,
    item_code bigint,
    payment_method text,
    user_id bigint,
    PRIMARY KEY ((hour, day, month, year), transaction_id)
); 

您可以在此处将时间戳字段分为小时、日、月和年。

如果您想聚合结果,您应该使用 Spark 或 Hadoop,这是此类工作的最佳选择。

如果你想在 cassandra 中做这种工作,你必须为每个维度使用单独的表。在主表插入数据时,也必须在每个表中插入数据。

聚合支付方式:

CREATE TABLE payment_method_counter (
    hour int,
    day int,
    month int,
    year int,
    type text,
    count counter,
    PRIMARY KEY ((hour, day, month, year), type)
);

您可以使用以下查询插入数据:

UPDATE payment_method_counter SET count = count + 1 WHERE hour = 1 AND day = 1 AND month = 1 AND year = 2017 AND type = 'cashondelivery';

聚合 Transaction_by_unique_user_id :

CREATE TABLE user_transaction_counter (
    hour int,
    day int,
    month int,
    year int,
    userid bigint,
    count counter,
    PRIMARY KEY ((hour, day, month, year), userid)
);

并插入查询:

UPDATE user_transaction_counter SET count = count + 1 WHERE hour = 1 AND day = 1 AND month = 1 AND year = 2017 AND userid = 5;

出售的总商品:

CREATE TABLE item_sold_counter (
    hour int,
    day int,
    month int,
    year int,
    item_code bigint,
    count counter,
    PRIMARY KEY ((hour, day, month, year), item_code)
);

你可以查询:

UPDATE item_sold_counter SET count = count + 1 WHERE hour = 1 AND day = 1 AND month = 1 AND year = 2017 AND item_code = 4;

在此处,对于已售出的总商品,请使用 item_code = 0 之类的特殊值。对于每件售出的商品,还要插入一个带有item_code = 0的值

获取结果:

你可以得到一个小时的聚合结果,如下查询:

cassandra@cqlsh:test> SELECT * FROM payment_method_counter  WHERE hour = 1 AND day = 1 AND month = 1 AND year = 2017;

 hour | day | month | year | type           | count
------+-----+-------+------+----------------+-------
    1 |   1 |     1 | 2017 | cashondelivery |     2
    1 |   1 |     1 | 2017 |     creditcard |     1

(2 rows)
cassandra@cqlsh:test> SELECT * FROM user_transaction_counter WHERE hour = 1 AND day = 1 AND month = 1 AND year = 2017;

 hour | day | month | year | userid | count
------+-----+-------+------+--------+-------
    1 |   1 |     1 | 2017 |      5 |     2
    1 |   1 |     1 | 2017 |      6 |     1

(2 rows)
cassandra@cqlsh:test> SELECT * FROM item_sold_counter  WHERE hour = 1 AND day = 1 AND month = 1 AND year = 2017;

 hour | day | month | year | item_code | count
------+-----+-------+------+-----------+-------
    1 |   1 |     1 | 2017 |         0 |     3
    1 |   1 |     1 | 2017 |         3 |     1
    1 |   1 |     1 | 2017 |         4 |     2

【讨论】:

  • 感谢您花时间研究该场景。将尝试此操作并回复您。
  • 您建议在这里为每个维度设置不同的表格?
  • 是的,我的数据量很大,我正在使用 spark 进行处理
  • @BalajiReddy spark 最适合您的用例。
  • @Ashraful Islam 是的
猜你喜欢
  • 2018-04-02
  • 1970-01-01
  • 1970-01-01
  • 2019-01-17
  • 2013-01-31
  • 1970-01-01
  • 1970-01-01
  • 2018-06-26
相关资源
最近更新 更多