简单消息传递应用程序

时间:2015-09-08 00:47:44

标签: database cassandra data-modeling cqlsh

我正在努力学习Cassandra并始终找到最好的方法是从创建一个非常简单的小应用程序开始。因此,我正在创建一个基本的消息传递应用程序,它将使用Cassandra作为后端。我想做以下事情:

  • 用户将使用用户名,电子邮件和密码创建一个帐户。该 电子邮件和密码可以随时更改。
  • 用户可以添加其他用户作为他们的联系人。用户会添加一个 通过搜索用户名或电子邮件联系。联系人不需要 如果我添加一个用户他们是我的联系人,那就是相互意义,我不会 需要等待他们接受/批准Facebook中的任何内容。
  • 从一个用户向另一个用户发送消息。发件人需要 能够看到他们发送的消息(按时间排序)和 发送给他们的消息(按时间排序)。用户打开时 我需要检查数据库中的任何新消息 用户。我还需要标记消息是否已被阅读。

当我来自关系数据库世界时,我的关系数据库看起来像这样:

UsersTable
    username (text)
    email (text)
    password (text)
    time_created (timestamp)
    last_loggedIn (timestamp)
------------------------------------------------ 
ContactsTable
    user_i_added (text)
    user_added_me (text)
------------------------------------------------     
MessagesTable
    from_user (text)
    to_user (text)
    msg_body (text)
    metadata (text)
    has_been_read (boolean)
    message_sent_time (timestamp)

通过阅读几本Cassandra教科书,我想到了如何建模数据库。我主要关注的是以非常有效的方式对数据库进行建模。因此,我试图避免二级索引等问题。到目前为止,这是我的模型:

CREATE TABLE users_by_username (
    username text PRIMARY KEY,
    email text,
    password text
    timeCreated timestamp
    last_loggedin timestamp
)

CREATE TABLE users_by_email (
    email text PRIMARY KEY,
    username text,
    password text
    timeCreated timestamp
    last_loggedin timestamp
)

为了均匀地传播数据并读取最少量的分区(希望只有一个),我可以根据用户的用户名或电子邮件快速查找用户。这方面的缺点显然是我的数据增加了一倍,但是存储成本非常便宜,所以我觉得这是一个很好的权衡,而不是使用二级索引。最后登录也需要写两次,但Cassandra在写作时很有效,所以我相信这也是一个很好的权衡。

对于联系人,我无法想到任何其他方式对此进行建模,因此我将其模拟为非常类似于我在关系数据库中的方式。根据我读过的书,这是一个非常规范化的设计我应该对性能有好处吗?

CREATE TABLE "user_follows" (
  follower_username text,
  followed_username text,
  timeCreated timestamp, 
  PRIMARY KEY ("follower_username", "followed_username")
);

CREATE TABLE "user_followedBy" (

  followed_username text,
  follower_username text,
  timeCreated timestamp,
  PRIMARY KEY ("followed_username", "follower_username")
);

我被困在如何创建下一部分。对于消息传递,我正在考虑这个表,因为它创建了宽行,可以对消息进行排序。 我需要消息来回答两个问题。它首先需要能够向用户显示他们拥有的所有消息,并且还能够向用户显示 新邮件是未读的。这是一个基本模型,但我不确定如何使它更有效?

CREATE TABLE messages (
    message_id uuid,
    from_user text,
    to_user text,
    body text,
    hasRead boolean,
    timeCreated timeuuid,
    PRIMARY KEY ((to_user), timeCreated )
) WITH CLUSTERING ORDER BY (timeCreated ASC);

我还在考虑使用STATIC柱这样的东西来粘合'将用户和消息以及SETS结合在一起来存储联系人关系,但从我目前的狭隘理解来看,我提出的方式更有效率。我问是否有任何想法可以提高这个模型的效率,如果有更好的实践做我想做的事情,或者我是否可以面对这个设计隐藏的问题?

总之,我正在尝试围绕查询进行建模。如果我使用关系数据库,这些基本上就是我想要回答的查询:

To Login:
SELECT * FROM USERS WHERE (USERNAME = [MY_USERNAME] OR EMAIL = [MY_EMAIL]) AND PASSWORD = [MY_PASSWORD];
------------------------------------------------------------------------------------------------------------------------
Update user info:
UPDATE USERS (password) SET password = [NEW_PASSWORD] where username = [MY_USERNAME];
UPDATE USERS (email) SET password = [NEW_PASSWORD ] where username = [MY_USERNAME];
------------------------------------------------------------------------------------------------------------------------ 
To Add contact (If by username):
INSERT INTO followings(following,follower)  VALUES([USERNAME_I_WANT_TO_FOLLOW],[MY_USERNAME]);
------------------------------------------------------------------------------------------------------------------------
To Add contact (If by email):
SELECT username FROM users where email = [CONTACTS_EMAIL];
    Then application layer sends over another query with the username:
INSERT INTO followings(following,follower)  VALUES([USERNAME_I_WANT_TO_FOLLOW],[MY_USERNAME]);
------------------------------------------------------------------------------------------------------------------------
To View contacts:
SELECT following FROM USERS WHERE follower = [MY_USERNAME];
------------------------------------------------------------------------------------------------------------------------
To Send Message:,
INSERT INTO MESSAGES (MSG_ID, FROM, TO, MSG, IS_MSG_NEW) VALUES (uuid, [FROM_USERNAME], [TO_USERNAME], 'MY MSG', true);
------------------------------------------------------------------------------------------------------------------------
To View All Messages (Some pagination type of technique where shows me the 10 recent messages, yet shows which ones are unread):
SELECT * FROM MESSAGES WHERE TO = [MY_USERNAME] LIMIT 10;
------------------------------------------------------------------------------------------------------------------------
Once Message is read:
UPDATE MESSAGES SET IS_MSG_NEW = false WHERE TO = [MY_USERNAME] AND MSG_ID = [MSG_ID];

干杯

1 个答案:

答案 0 :(得分:2)

对于cassandra或noSQL数据建模初学者,您的应用程序的数据建模涉及一个过程,例如

1-了解您的数据,设计概念图
2-详细列出您的所有问题 3-使用定义的规则和模式映射您的查询,最适合cassandra
4-创建一个逻辑设计,表格包含从查询中派生的字段 5-现在创建一个模式并测试它的接受度。

如果我们很好地建模,那么很容易处理诸如新的复杂查询,数据过载,数据一致性设置等问题。

参加此免费在线数据建模培训后,您将获得更多清晰度

https://academy.datastax.com/courses/ds220-data-modeling

祝你好运!