【问题标题】:Cassandra Data Model - Column Families into CQL TableCassandra 数据模型 - CQL 表中的列族
【发布时间】:2016-12-27 02:45:57
【问题描述】:

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

请建议如何将示例表转换为 CQL 表。

【问题讨论】:

  • Cassandra 需要基于查询的建模方法。由于您没有提及您需要支持的查询,因此不可能就您的表的外观做出明智的决定。
  • 谢谢,亚伦。我假设数据需要存储在具有适当行键和列键和列值的列族中。但是一旦完成,我们如何决定在 CQL 表中显示信息。
  • 例如,假设我有这样的相同数据: User(userid, uname, email,dob,loc,mobile,landlinenum) 由于 cassandra 支持无模式(可以添加动态列),因此可能会发生一个用户可能有很少的列,而其他用户可能只有很少的其他列(可能有行占用相同数量的列,其他行也可能占用其他列。如何将其转换为 CQL 表,因为我有所有不同的不同行键的列。

标签: cassandra data-modeling


【解决方案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. 未被赋值的列显示为“null”。请记住,它们不是真正的空值,它们只是以这种方式显示。

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

现在我要了解您的查询要求,您通常希望为所需的每个查询创建一个表。我有由userid 键入的“用户”表...但实际上,这有多大用处?应用程序通常通过email 或loc 之类的方式进行查询。

为了处理电子邮件,我将创建一个具有相同列定义的新表,称为“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)

这就是为什么了解您的查询模式会有所作为。在第一个示例中,“users”表不支持email 的查询。

【讨论】:

  • 感谢 Aaron 的详细解释。感谢您为回答我的问题所做的努力。再次感谢您。
猜你喜欢
  • 2018-06-26
  • 2013-08-27
  • 1970-01-01
  • 2020-05-31
  • 2011-10-02
  • 2015-10-26
  • 1970-01-01
  • 2013-08-01
  • 2012-03-21
相关资源
最近更新 更多