Retourned
Retourned

Reputation: 11

CassandraDB table with multiple Key-Value

I am a new CassandraDB user. I am trying to create a table which has 3 static columns, for example "name", "city" and "age", and then I was thinking in two "key" and "value" columns, since my table could receive a lot of inputs. How can I define this table? I am trying to achieve something scalable, i.e:

Table columns --> "Name", "City", "Age", "Key", "Value"

Name: Mark

City: Liverpool

Age: 26

Key: Car

Value: Audi A3

Key: Job

Value: Computer Engineer

Key: Main hobby

Value: Football

I am looking for the TABLE DEFINITION.. Any help? Thank you so so much in advance.

Upvotes: 1

Views: 251

Answers (2)

Aaron
Aaron

Reputation: 57748

table which has 3 static columns

So by "static" I assume you're not referring to Cassandra's definition of static columns. Which is cool, I know what you mean. But the mention did give me an idea of how to approach this:

trying to create the table definition

I see two ways to go about this.

CREATE TABLE user_properties (
    name TEXT,
    city TEXT STATIC,
    age INT STATIC,
    key TEXT,
    value TEXT,
    PRIMARY KEY (name,key));

Because we have static columns (only stored w/ the partition key name) adding more key/values is just a matter of adding more keys to the same name, so INSERTing data looks like this:

INSERT INTO user_properties (name,city,age,key,value)
    VALUES ('Mark','Liverpool',26,'Car','Audi A3');
INSERT INTO user_properties (name,key,value)
    VALUES ('Mark','Job','Computer Engineer');
INSERT INTO user_properties (name,key,value)
    VALUES ('Mark','Main hobby','Football');

Querying looks like this:

> SELECT * FROm user_properties WHERE name='Mark';

 name | key        | age | city      | value
------+------------+-----+-----------+-------------------
 Mark |        Car |  26 | Liverpool |           Audi A3
 Mark |        Job |  26 | Liverpool | Computer Engineer
 Mark | Main hobby |  26 | Liverpool |          Football

(3 rows)

This is the "simple" way to go about it.

Or

CREATE TABLE user_properties_map (
    name TEXT,
    city TEXT,
    age INT,
    kv MAP<TEXT,TEXT>,
    PRIMARY KEY (name));

With a single partition key as the PRIMARY KEY, we can INSERT everything in one shot:

INSERT INTO user_properties_map (name,city,age,kv)
    VALUES ('Mark','Liverpool',26,{'Car':'Audi A3',
                                   'Job':'Computer Engineer',
                                   'Main hobby':'Football'});

And querying looks like this:

> SELECT * FROm user_properties_map  WHERE name='Mark';

 name | age | city      | kv
------+-----+-----------+--------------------------------------------------------------------------
 Mark |  26 | Liverpool | {'Car': 'Audi A3', 'Job': 'Computer Engineer', 'Main hobby': 'Football'}

(1 rows)

This has the added benefit of putting the properties into a map, which might be helpful if that's the way you're intending to work with it on the application side. The drawbacks, are that Cassandra collections are best kept under 100 items, the writes are a little more complicated, and you can't query individual entries of the map.

But by keying on name (might want to also include last name or something else to help with uniqueness), data should scale fine. And partition growth won't be a problem, unless you're planning on thousands of key/value pairs.

Basically, choose the structure based ons the standard Cassandra advice of considering how you'd query the data, and then build the table to suit it.

Upvotes: 1

Gunwant
Gunwant

Reputation: 979

If I understand correctly, you want to create a key-value store, grouped by "name", "city" and "age". There are few solutions for this approach -

First by using STATIC columns -

create table record_by_id(
recordId text,
name text static,
city text static,
age int static,
key text,
value text
primary key (recordId, key)
);

Which this table design, Name, City, Age remain constant for same recordid. You can any number of key- values for same record id.

Second Approach would be -

create table record_by_id(
name text ,
city text ,
age int ,
key text,
value text
primary key ((name,city,age),key)
);

In this design, Name , city and age is are part of partition key. The key column is part of clustering key.

Both approach are scalable but first approach is good for maintenance.

Upvotes: 1

Related Questions