我应该如何在 Cassandra 中存储嵌套的 JSON 对象?

问题描述 投票:0回答:2

这是我第一次使用 Cassandra,我有如下数据结构,想将其保存在 Cassandra 中:

{"user_id": "123",
 "user_cards": {
  "first_card": {
    "card_number": 456
  }
 }
}

我通过互联网搜索并找到了如下示例:

use json;
CREATE type json.sale ( id int, item text, amount int );
CREATE TABLE json.customers ( id int  PRIMARY KEY, name text, balance int, sales list> );

INSERT INTO json.customers (id, name, balance, sales) 
VALUES (123, 'Greenville Hardware', 700,
[{ id: 5544, item : 'tape', amount : 100},
{ id: 5545, item : 'wire', amount : 200}]) ;

但我不确定这是否是最好的方法?我记得根据我使用 MySQL 或 MongoDB/Mongoose 的经验,我们为嵌套的 JSON 对象定义了单独的表,并将该表的外键放在父表的列中(或者在 Mongo 中填充)。

听说Cassandra反对规范化,最好对它做非规范化,我不知道我应该采取什么方法?

我还有另一个关于数据压缩的问题,如果我像上面举的例子那样做,cassandra 会处理它吗?

cassandra blob data-modeling denormalization nested-json
2个回答
1
投票

从表面上看,我认为这是一个很好的做法。我唯一担心的是每个客户是否有很多销售额……比如数百万。但如果商业用途的收益不会超过几千左右,这可能没问题。

如果没有,将日期/时间组件添加到分区键(如年份或其他内容)可能是有意义的:

PRIMARY KEY ((id, year_of_sale))

这将确保每个分区的销售额按年设置上限。

要考虑的另一件事是需要支持的查询模式。目前只支持

id
查询。但如果没关系,那么你应该可以开始了!


0
投票

可以使用

INSERT ... JSON
CQL 命令以 JSON 格式插入数据。例如:

INSERT INTO table_name JSON '{
    "column_name": "value"
}'

但它比那更细微,所以请允许我解释一下。

Cassandra 中的数据建模与传统关系数据库中的数据建模完全相反。我们没有研究如何将数据存储到表中,而是首先列出所有应用程序查询,然后为每个应用程序查询设计一个表。我们这样做是为了针对读取优化表。

例如,假设应用程序需要“检索用户的所有卡片”,我们需要设计一个表:

  • 数据按用户分区,AND
  • 卡片“聚集”(组合在一起)。

表模式看起来像:

CREATE TABLE cards_by_user (
    user_id int,
    card_number int,
    card_type text,
    card_expiry text,
    ...
    PRIMARY KEY (user_id, card_number)
) WITH CLUSTERING ORDER BY (card_number ASC)

与RDBMS中的二维表相比,这个Cassandra表是多维的,每个分区(用户)可以有一个或多个行(卡片)。

要为用户创建新的卡片条目,插入 JSON 格式数据的 CQL 语句如下所示:

INSERT INTO cards_by_user
JSON '{
    "user_id": "123",
    "card_number": "456",
    "card_type": "visa",
    "card_expiry": "07/2028"
}'

您可以使用相同的

INSERT
格式插入多行卡片。例如:

INSERT INTO cards_by_user
JSON '{
    "user_id": "123",
    "card_number": "789",
    "card_type": "mastercard",
    "card_expiry": "04/2025"
}'

检索用户的所有卡片:

SELECT * FROM cards_by_user WHERE user_id = 123;

 user_id | card_number | card_expiry | card_type
---------+-------------+-------------+------------
     123 |         456 |     07/2028 |       visa
     123 |         789 |     04/2025 | mastercard

如您所见,不必使用用户定义类型 (UDT) 来存储数据。我们建议尽可能将数据映射到本机 CQL 列而不是 UDT,以降低维护数据和代码所需的复杂程度。

作为旁注,如果您更喜欢使用 JSON 文档,那么可以看看 Stargate.io——一个开源数据 API 网关,它有一个文档 API,允许您存储和检索类似于 MongoDB 的 JSON 文档.

查看 datastax.com/dev 上的 免费教程,您可以在动手实验室中试用它。干杯!

© www.soinside.com 2019 - 2024. All rights reserved.