Модель данных Cassandra для простого приложения обмена сообщениями

Я пытаюсь выучить 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)

Прочитав пару учебников Кассандры, я подумал о том, как смоделировать базу данных. Моя главная задача - очень эффективно смоделировать базу данных. Поэтому я стараюсь избегать таких вещей, как вторичные индексы и т. Д. Это моя модель до сих пор:

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
)

Чтобы распределить данные равномерно и прочитать минимальное количество разделов (возможно, только один), я могу быстро найти пользователя по его имени или электронной почте. Недостатком этого является то, что я удваиваю свои данные, но стоимость хранилища довольно дешевая, поэтому я считаю, что это хороший компромисс вместо использования вторичных индексов. Последний вход в систему также должен быть записан дважды, но Кассандра эффективна при записи, поэтому я считаю, что это также хороший компромисс.

Что касается контактов, я не могу придумать какой-либо другой способ смоделировать это, поэтому я смоделировал это очень похоже на то, как в реляционной базе данных. Я считаю, что это довольно денормализованный дизайн, который должен быть хорош для работы в соответствии с книгами, которые я прочитал?

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];

ура

Ответы на вопрос(2)

Ваш ответ на вопрос