【问题标题】:CQL3 Each row to have its own schemaCQL3 每行都有自己的架构
【发布时间】:2014-09-25 17:35:08
【问题描述】:

我想在 .Net 应用程序中使用 Cassandra。我的目标是将一些数据存储在一个列族中,但每一行数据都有不同的架构。

示例(一个非常简单的示例)我想要一个“Toys”列族来存储以下对象,(注意它们除了 ID 属性之外还有非常不同的属性)

玩具对象 1 { "id":"1", “名称”:“汽车”, “门数”:4, “喜欢”:3}

玩具对象 2 { "id":"2", “类型”:“平面”, "flying_range":"100m"}

玩具对象 3 { "id":"3", “类别”:“火车”, "number_of_carriages":10}

根据我对 Datastax CSharp 驱动程序的初步理解和使用,我必须始终更改不适合我的表(列族)。我希望每一行都有自己的架构。 Thrift API 或许能够解决这个问题,但 HectorSharp 似乎已经死了。

一个与我的要求相似但没有我想要的答案的问题

Cassandra for a schemaless db, 10's of millions order tables and millions of queries per day

我是否期望每一行都有自己的架构,或者有没有办法使用 Cassandra+Csharp 来做到这一点?

提前感谢您的回答。

【问题讨论】:

    标签: c# cassandra cql3


    【解决方案1】:

    旧版本的 Cassandra 没有架构,这意味着您没有任何地方可以定义行可以包含的内容。您现在需要的可以部分在 Cassandra 2.1 上使用 Map 完成

    CREATE TABLE toys (
        id text PRIMARY KEY,
        toy map<text, text>
    )
    

    放一些数据...

    INSERT INTO toys (id, toy) VALUES ( '1', {'name':'Car', 'number_of_doors':'4', 'likes':'3'});
    INSERT INTO toys (id, toy) VALUES ( '2', {'type':'Plane', 'flying_range':'100m'});
    INSERT INTO toys (id, toy) VALUES ( '3', {'category':'Train', 'number_of_carriages':'10'});
    

    表格内容...

     id | toy
    ----+-------------------------------------------------------
      3 |    {'category': 'Train', 'number_of_carriages': '10'}
      2 |             {'flying_range': '100m', 'type': 'Plane'}
      1 | {'likes': '3', 'name': 'Car', 'number_of_doors': '4'}
    

    我们现在可以在键上创建索引...

    CREATE INDEX toy_idx ON toys (KEYS(toy));
    

    ...并对 Map 键执行查询 ...

    SELECT * FROM toys WHERE toy CONTAINS KEY 'name';
    
     id | toy
    ----+-------------------------------------------------------
      1 | {'likes': '3', 'name': 'Car', 'number_of_doors': '4'}
    

    现在您可以像处理普通列一样更新或删除地图条目,而无需在写入前读取

    DELETE toy['name'] FROM toys WHERE id='1';
    UPDATE toys set toy = toy + {'name': 'anewcar'} WHERE id = '1';
    SELECT * FROM toys;
    
     id | toy
    ----+-----------------------------------------------------------
      3 |        {'category': 'Train', 'number_of_carriages': '10'}
      2 |                 {'flying_range': '100m', 'type': 'Plane'}
      1 | {'likes': '3', 'name': 'anewcar', 'number_of_doors': '4'}
    

    一些限制

    1. 您无法检索集合的一部分:即使内部地图的每个条目都存储为列,您也只能检索整个集合
    2. 您必须选择是同时为键还是值创建索引 不支持。
    3. 由于输入了地图,因此您不能放置混合值 - 在我的示例中,所有整数现在都是字符串

    我个人认为这种方法的广泛使用是一种反模式。

    HTH, 卡罗

    【讨论】:

    • 谢谢 Carlo,我已经接受了您的回答,认为这是目前最正确的回答,但正如您所指出的,使用地图会将我的所有数据限制为地图定义中定义的类型。在检索此数据并将其发送回希望它们为原始格式的用户时,这会造成问题。
    • 这不是什么大问题。一旦您知道映射中字符串的正确类型是什么,您只需执行 Integer.valueOf() 或 UUID.fromString() 或在将数据发送回客户端之前需要转换的任何内容
    • 几分钟之内,我就了解了 cassandra 的工作、存储、检索和限制。不错的答案(y)
    【解决方案2】:

    补充卡洛的答案:

    1. 集合索引在旧 cassandra 版本(2.1 之前)上不可用。二级指数也有局限性,并且最终是一致的。深入挖掘。
    2. 不要去寻找“给我所有汽车玩具”类型的查询。与 cassandra 的大多数事情一样,想想您将如何访问数据(查询)并相应地建模。根据查询,使用多个表存储具有不同结构的玩具数据以方便不同的查询是完全可以接受的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-28
      • 1970-01-01
      • 1970-01-01
      • 2013-08-23
      • 2011-05-21
      • 1970-01-01
      相关资源
      最近更新 更多