CQL3 Each row to have its own schema

前端 未结 2 1703
迷失自我
迷失自我 2020-12-06 02:54

I want to use Cassandra in a .Net application. My objective is to store some data in a column family, but each row of data will have varying schema.

Example (A very

2条回答
  •  悲&欢浪女
    2020-12-06 03:22

    Older versions of Cassandra were Schema-less, meaning that you didn't have anywhere a definition of what a row could contain. What you need now could be partially done with a Map on Cassandra 2.1

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

    Put some data ...

    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'});
    

    Table content ...

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

    We can now create an index on keys ...

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

    ... and perform queries on Map keys ...

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

    Now you can update or delete map entries like you would do with normal columns, without reading before writing

    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'}
    

    A few limitations

    1. you can not retrieve part of a collection: even if internally each entry of a map is stored as a column you can only retrieve the whole collection
    2. you have to choose whether creating an index on keys or on values, both simultaneously are not supported.
    3. since maps are typed you can't put mixed values -- in my examples all integers are now strings

    I personally consider an extensive usage of this approach an anti-pattern.

    HTH, Carlo

提交回复
热议问题