如何在 Cassandra 中存储嵌套数据
How do I store nested data in Cassandra
考虑以下 "documents",这两个文档将如何存储在一个集合中。
// collection posts:
{
id: 1,
name: "kingsbounty",
fields: {
"title": {
"title": "Game Title",
"value": "Kings Bounty"
}
},
{
"body": {
"title": "Game Description",
"value": "Kings Bounty is a turn-based fantasy..."
}
}
}
// collection posts:
{
id: 2,
name: "outrun",
fields: {
"vehicle": {
"title": "Vehicle",
"value": "Ferrari Testarossa"
},
"color": {
"title": "Vehicle Color",
"value": "Red"
},
"driver": {
"title": "Driver",
"value": "David Hasselhoff"
}
}
}
注意 fields 是一张大小不一的地图。
因为 cassandra 不允许定义这种类型 fields <map <map, text>>
我想学习 "cassandra" 的方法,非规范化的方法。
这种方式没有非规范化,但可以存储和检索任意长度的嵌套数据。
CREATE TABLE posts (
id uuid,
name text,
fields list<text>
PRIMARY KEY (id)
);
CREATE INDEX post_name_key ON posts (name);
CREATE TABLE post_fields (
post_name text,
field_name text,
title text,
value text,
PRIMARY KEY (post_name, field_name)
);
INSERT INTO posts (id, name, fields) VALUES ( uuid(), 'kingsbounty', [ 'title', 'body' ] );
INSERT INTO posts (id, name, fields) VALUES ( uuid(), 'outrun', [ 'vehicle', 'color', 'driver' ] );
INSERT INTO post_fields (post_name, field_name, title, value) VALUES ( 'kingsbounty', 'title', 'Game Title', 'Kings Bounty');
INSERT INTO post_fields (post_name, field_name, title, value) VALUES ( 'kingsbounty', 'body', 'Game Description', 'Kings Bounty is a turn-based fantasy...');
INSERT INTO post_fields (post_name, field_name, title, value) VALUES ( 'outrun', 'vehicle', 'Vehicle', 'Ferrari Testarossa');
INSERT INTO post_fields (post_name, field_name, title, value) VALUES ( 'outrun', 'color', 'Vehicle Color', 'Red');
INSERT INTO post_fields (post_name, field_name, title, value) VALUES ( 'outrun', 'driver', 'Driver', 'David Hasselhoff');
SELECT fields FROM posts WHERE name = 'kingsbounty';
fields
-------------------
['title', 'body']
SELECT * FROM post_fields WHERE post_name = 'kingsbounty';
post_name | field_name | title | value
-------------+------------+------------------+-----------------------------------------
kingsbounty | body | Game Description | Kings Bounty is a turn-based fantasy...
kingsbounty | title | Game Title | Kings Bounty
SELECT fields FROM posts WHERE name = 'outrun';
fields
--------------------------------
['vehicle', 'color', 'driver']
SELECT * FROM post_fields WHERE post_name = 'outrun';
post_name | field_name | title | value
-----------+------------+---------------+--------------------
outrun | color | Vehicle Color | Red
outrun | driver | Driver | David Hasselhoff
outrun | vehicle | Vehicle | Ferrari Testarossa
存储此类数据的更好的非规范化方法是什么?
使用您想要 return 的任何信息创建 table。假设您需要 returned 所有信息,将其存储到单个 table 中,如下所示,并在客户端进行必要的操作。
CREATE TABLE posts (
id uuid,
name text,
fields map<text,text>,
PRIMARY KEY (id)
);
insert into posts (id,name,fields) values (uuid(),'kingsbounty',{'title':'"title": "Game Title","value": "Kings Bounty"','body':'"title": "Game Description","value": "Kings Bounty is a turn-based fantasy..."'});
insert into posts (id,name,fields) values (uuid(),'outrun',{'vehicle':'"title": "Vehicle","value": "Ferrari Testarossa"','color':'"title": "Vehicle Color","value": "Red"','driver':'"title": "Driver","value": "David Hasselhoff"'});
cqlsh> select id,name,fields from posts;
id | name | fields
--------------------------------------+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
dd31393d-2654-42ec-a5fb-73ab13c12932 | kingsbounty | {'body': '"title": "Game Description","value": "Kings Bounty is a turn-based fantasy..."', 'title': '"title": "Game Title","value": "Kings Bounty"'}
a1e2b512-7177-4a2d-8da3-528b9d5097c0 | outrun | {'color': '"title": "Vehicle Color","value": "Red"', 'driver': '"title": "Driver","value": "David Hasselhoff"', 'vehicle': '"title": "Vehicle","value": "Ferrari Testarossa"'}
irc 上来自 #cassandra 的 jeffj 建议我什至不需要第一个 table。
我现在开始明白了。
CREATE TABLE posts (
name text,
field text,
title text,
value text,
PRIMARY KEY (name, field)
);
INSERT INTO posts (name, field, title, value) VALUES ( 'kingsbounty', 'title', 'Game Title', 'Kings Bounty');
INSERT INTO posts (name, field, title, value) VALUES ( 'kingsbounty', 'body', 'Game Description', 'Kings Bounty is a turn-based fantasy...');
INSERT INTO posts (name, field, title, value) VALUES ( 'outrun', 'vehicle', 'Vehicle', 'Ferrari Testarossa');
INSERT INTO posts (name, field, title, value) VALUES ( 'outrun', 'color', 'Vehicle Color', 'Red');
INSERT INTO posts (name, field, title, value) VALUES ( 'outrun', 'driver', 'Driver', 'David Hasselhoff');
SELECT field FROM posts WHERE name = 'kingsbounty';
field
-------
body
title
SELECT * FROM posts WHERE name = 'kingsbounty';
name | field | title | value
-------------+-------+------------------+-----------------------------------------
kingsbounty | body | Game Description | Kings Bounty is a turn-based fantasy...
kingsbounty | title | Game Title | Kings Bounty
SELECT fields FROM posts WHERE name = 'outrun';
field
---------
color
driver
vehicle
SELECT * FROM posts WHERE name = 'outrun';
name | field | title | value
--------+---------+---------------+--------------------
outrun | color | Vehicle Color | Red
outrun | driver | Driver | David Hasselhoff
outrun | vehicle | Vehicle | Ferrari Testarossa
考虑以下 "documents",这两个文档将如何存储在一个集合中。
// collection posts:
{
id: 1,
name: "kingsbounty",
fields: {
"title": {
"title": "Game Title",
"value": "Kings Bounty"
}
},
{
"body": {
"title": "Game Description",
"value": "Kings Bounty is a turn-based fantasy..."
}
}
}
// collection posts:
{
id: 2,
name: "outrun",
fields: {
"vehicle": {
"title": "Vehicle",
"value": "Ferrari Testarossa"
},
"color": {
"title": "Vehicle Color",
"value": "Red"
},
"driver": {
"title": "Driver",
"value": "David Hasselhoff"
}
}
}
注意 fields 是一张大小不一的地图。
因为 cassandra 不允许定义这种类型 fields <map <map, text>>
我想学习 "cassandra" 的方法,非规范化的方法。 这种方式没有非规范化,但可以存储和检索任意长度的嵌套数据。
CREATE TABLE posts (
id uuid,
name text,
fields list<text>
PRIMARY KEY (id)
);
CREATE INDEX post_name_key ON posts (name);
CREATE TABLE post_fields (
post_name text,
field_name text,
title text,
value text,
PRIMARY KEY (post_name, field_name)
);
INSERT INTO posts (id, name, fields) VALUES ( uuid(), 'kingsbounty', [ 'title', 'body' ] );
INSERT INTO posts (id, name, fields) VALUES ( uuid(), 'outrun', [ 'vehicle', 'color', 'driver' ] );
INSERT INTO post_fields (post_name, field_name, title, value) VALUES ( 'kingsbounty', 'title', 'Game Title', 'Kings Bounty');
INSERT INTO post_fields (post_name, field_name, title, value) VALUES ( 'kingsbounty', 'body', 'Game Description', 'Kings Bounty is a turn-based fantasy...');
INSERT INTO post_fields (post_name, field_name, title, value) VALUES ( 'outrun', 'vehicle', 'Vehicle', 'Ferrari Testarossa');
INSERT INTO post_fields (post_name, field_name, title, value) VALUES ( 'outrun', 'color', 'Vehicle Color', 'Red');
INSERT INTO post_fields (post_name, field_name, title, value) VALUES ( 'outrun', 'driver', 'Driver', 'David Hasselhoff');
SELECT fields FROM posts WHERE name = 'kingsbounty';
fields
-------------------
['title', 'body']
SELECT * FROM post_fields WHERE post_name = 'kingsbounty';
post_name | field_name | title | value
-------------+------------+------------------+-----------------------------------------
kingsbounty | body | Game Description | Kings Bounty is a turn-based fantasy...
kingsbounty | title | Game Title | Kings Bounty
SELECT fields FROM posts WHERE name = 'outrun';
fields
--------------------------------
['vehicle', 'color', 'driver']
SELECT * FROM post_fields WHERE post_name = 'outrun';
post_name | field_name | title | value
-----------+------------+---------------+--------------------
outrun | color | Vehicle Color | Red
outrun | driver | Driver | David Hasselhoff
outrun | vehicle | Vehicle | Ferrari Testarossa
存储此类数据的更好的非规范化方法是什么?
使用您想要 return 的任何信息创建 table。假设您需要 returned 所有信息,将其存储到单个 table 中,如下所示,并在客户端进行必要的操作。
CREATE TABLE posts (
id uuid,
name text,
fields map<text,text>,
PRIMARY KEY (id)
);
insert into posts (id,name,fields) values (uuid(),'kingsbounty',{'title':'"title": "Game Title","value": "Kings Bounty"','body':'"title": "Game Description","value": "Kings Bounty is a turn-based fantasy..."'});
insert into posts (id,name,fields) values (uuid(),'outrun',{'vehicle':'"title": "Vehicle","value": "Ferrari Testarossa"','color':'"title": "Vehicle Color","value": "Red"','driver':'"title": "Driver","value": "David Hasselhoff"'});
cqlsh> select id,name,fields from posts;
id | name | fields
--------------------------------------+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
dd31393d-2654-42ec-a5fb-73ab13c12932 | kingsbounty | {'body': '"title": "Game Description","value": "Kings Bounty is a turn-based fantasy..."', 'title': '"title": "Game Title","value": "Kings Bounty"'}
a1e2b512-7177-4a2d-8da3-528b9d5097c0 | outrun | {'color': '"title": "Vehicle Color","value": "Red"', 'driver': '"title": "Driver","value": "David Hasselhoff"', 'vehicle': '"title": "Vehicle","value": "Ferrari Testarossa"'}
irc 上来自 #cassandra 的 jeffj 建议我什至不需要第一个 table。
我现在开始明白了。
CREATE TABLE posts (
name text,
field text,
title text,
value text,
PRIMARY KEY (name, field)
);
INSERT INTO posts (name, field, title, value) VALUES ( 'kingsbounty', 'title', 'Game Title', 'Kings Bounty');
INSERT INTO posts (name, field, title, value) VALUES ( 'kingsbounty', 'body', 'Game Description', 'Kings Bounty is a turn-based fantasy...');
INSERT INTO posts (name, field, title, value) VALUES ( 'outrun', 'vehicle', 'Vehicle', 'Ferrari Testarossa');
INSERT INTO posts (name, field, title, value) VALUES ( 'outrun', 'color', 'Vehicle Color', 'Red');
INSERT INTO posts (name, field, title, value) VALUES ( 'outrun', 'driver', 'Driver', 'David Hasselhoff');
SELECT field FROM posts WHERE name = 'kingsbounty';
field
-------
body
title
SELECT * FROM posts WHERE name = 'kingsbounty';
name | field | title | value
-------------+-------+------------------+-----------------------------------------
kingsbounty | body | Game Description | Kings Bounty is a turn-based fantasy...
kingsbounty | title | Game Title | Kings Bounty
SELECT fields FROM posts WHERE name = 'outrun';
field
---------
color
driver
vehicle
SELECT * FROM posts WHERE name = 'outrun';
name | field | title | value
--------+---------+---------------+--------------------
outrun | color | Vehicle Color | Red
outrun | driver | Driver | David Hasselhoff
outrun | vehicle | Vehicle | Ferrari Testarossa