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

stszievb  于 2023-04-11  发布在  Cassandra
关注(0)|答案(2)|浏览(286)

这是我第一次使用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会照顾它吗?

bvjxkvbb

bvjxkvbb1#

从表面上看,我认为这是一个很好的方法。我唯一担心的是,如果每个客户都有很多销售额......比如数百万。但是,如果商业用途不会产生超过几千个左右的收益,这可能是好的。
如果没有,可以在分区键中添加日期/时间组件,例如year或其他内容:

PRIMARY KEY ((id, year_of_sale))

这将确保销售额将按年限制在每个分区。
另一件需要考虑的事情是,它需要支持的查询模式。现在,它只支持id查询。但是如果可以的话,那么你应该可以开始了!

ilmyapht

ilmyapht2#

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

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

但它比这更微妙,所以请允许我解释一下。
Cassandra中的数据建模与传统关系数据库中的数据建模完全相反。我们不是研究如何将数据存储到表中,而是首先列出所有应用程序查询,然后为每个应用程序查询设计一个表。我们这样做是为了优化表的读取。
例如,假设应用程序需要“检索用户的所有卡片”,我们需要设计一个表,使得:

  • 数据按用户分区,并且
  • 卡被“群集”(分组在一起)。

表模式看起来像这样:

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)来存储数据。我们建议尽可能将数据Map到本机CQL列而不是UDT,以降低维护数据和代码所需的复杂性。
顺便说一下,如果你更喜欢使用JSON文档,那么可以看看Stargate.io--一个开源数据API网关,它有一个文档API,允许你存储和检索类似于MongoDB的JSON文档。
看看the free tutorial on datastax.com/dev,你可以在动手实验室中尝试一下。干杯!

相关问题