鉴于我在Cassandra中持有以下对象:
Foo数组:
{
"id":1,
"name": "this is a name",
"bundleFields" : [
"bundleByMe",
"me2",
"me also",
]
},
{
"id":2,
"name": "anotherName",
"bundleFields" : [
"bundleByMe",
"me2",
"me also",
]
},
{
"id":3,
"name": "thridName",
"bundleFields" : [
"differentBundleCriteria"
]
}
我想查询类似SELECT * FROM FOO where bundleFields = ["...", "..."]
的内容。
这显然不起作用,因为list<>
的查询是不可能的(没有主键)。
这是我目前拥有的架构:
CREATE TABLE IF NOT EXISTS Foo (
id int,
name varchar,
bundleFields list<varchar>,
PRIMARY KEY(id)
);
我能想象的唯一解决方案是另一个表,其中PRIMARY KEY包含bundleFields-Array的连接值,这将允许bundleString查找:
CREATE TABLE IF NOT EXISTS fooByBundleString (
bundleString varchar,
fooId int,
PRIMARY KEY(bundleString)
);
这是cassandra中这个问题的推荐方法。
必须序列化/反序列化bundleFields-array的想法对我来说感觉不对。
感谢您的建议!
编辑:由于@rs_atl建议表fooByBundleString的正确DDL应该是(注意PRIMARY KEY中的附加fooId
):
CREATE TABLE IF NOT EXISTS fooByBundleString (
bundleString varchar,
fooId int,
PRIMARY KEY(bundleString, fooId)
);
创建一个覆盖索引,否则就不可能为不同的fooId存储相同的bundleString。
答案 0 :(得分:1)
正如您所描述的那样创建索引是正确的解决方案。但是它应该是覆盖索引,这意味着您希望复制查询中实际需要返回的任何值。否则,您最终会在应用程序中进行分布式连接,这非常昂贵。通常,偏好非规范化数据模型到归一化关系模型。这与您最喜欢的RDBMS中必须执行的操作基本相同,以便快速进行查询。不同之处在于您必须在应用程序中管理索引;卡桑德拉不会为你做这件事。