Cassandra数据模型 - 列族到CQL表

时间:2016-12-26 15:23:07

标签: cassandra data-modeling

假设我有一个带有字段的用户表示例(userid,username,dob,loc,email)。我有不同的列名称,例如一个用户只能有userid,用户名和第二个用户可以有userid,username,dob和第三个用户可能有其他列等等(代表宽列存储)。每个用户都可以拥有自己的一组列。如何在单个CQL表中表示这一点,因为不同列的数据稀疏。我是否需要使用多个用户表来表示此信息?

请建议如何将样本表转换为CQL表。

1 个答案:

答案 0 :(得分:1)

我看到你在问什么。不,您应该能够将所有列构建到单个表中。让我们说我创建一个这样的users表:

CREATE TABLE users(
  userid bigint,
  username text, 
  email text,
  dob text,
  loc text,
  mobile text,
  landlinenum text,
  PRIMARY KEY (userid));

然后我插入这样的行:

INSERT INTO users (userid,username,email,loc,mobile) VALUES (0,'mreynolds','mal@serenity.com','Minneapolis','111-555-1234');
INSERT INTO users (userid,username,email,loc,landlinenum,dob) VALUES (1,'jcobb','jayne@serenity.com','Minneapolis','111-555-3464','19620227');
INSERT INTO users (userid,username,email,loc,mobile) VALUES (2,'dbook','derrial@serenity.com','New York','111-555-2349');
INSERT INTO users (userid,username,email,loc,mobile,dob) VALUES (3,'stam','simon@serenity.com','San Francisco','111-555-8899','19750416');
INSERT INTO users (userid,username,email,loc,dob) VALUES (4,'rtam','river@serenity.com','San Francisco','19810724');

如果我运行未绑定的查询以撤回所有行和列,我会看到:

aploetz@cqlsh:stackoverflow> SELECT * FROM users;

 userid | dob      | email                | landlinenum  | loc           | mobile       | username
--------+----------+----------------------+--------------+---------------+--------------+-----------
      2 |     null | derrial@serenity.com |         null |      New York | 111-555-2349 |     dbook
      3 | 19750416 |   simon@serenity.com |         null | San Francisco | 111-555-8899 |      stam
      4 | 19810724 |   river@serenity.com |         null | San Francisco |         null |      rtam
      0 |     null |     mal@serenity.com |         null |   Minneapolis | 111-555-1234 | mreynolds
      1 | 19620227 |   jayne@serenity.com | 111-555-3464 |   Minneapolis |         null |     jcobb

(5 rows)

所以这应该告诉你一些事情。

  1. Cassandra并非真正的无架构"与之前的CQL世界一样。您必须在表定义中定义每一列。

  2. 如果说#1,则必须为每列提供值。

  3. not 的列已分配值显示为" null。"请记住,它们不是真正的空值,它们只是以这种方式显示。

  4. 在我的INSERT中,我只指定了具有相应值的列。我没有将其他人设置为空或空。将列值显式设置为null会创建一个逻辑删除。

  5. 现在我要了解您的查询要求,通常需要为每个所需的查询创建一个表。我有"用户"由userid键入的表...但实际上,这有多大用处?应用程序通常通过emailloc等内容进行查询。

    为了处理电子邮件,我会创建一个名为" users_by_email的相同列定义的新表。"主要区别(名称除外)将是PRIMARY KEY定义:PRIMARY KEY (email,username)

    然后我可以通过这样的电子邮件查询用户:

    aploetz@cqlsh:stackoverflow> SELECT * FROM users_by_email WHERE email='river@serenity.com';
    
     email              | username | dob      | landlinenum | loc           | mobile | userid
    --------------------+----------+----------+-------------+---------------+--------+--------
     river@serenity.com |     rtam | 19810724 |        null | San Francisco |   null |      4
    
    (1 rows)
    

    这就是为什么了解您的查询模式会产生影响的原因。在第一个例子中,"用户"表格不支持email的查询。