Proper backend structure for a group message application - mysql

favorite
If I'm designing the backend for a messaging app that allows group texts and has the following structure:
Message Table
message id | creator | message data | date created
Conversation Table
conversation id | creator | date created
ConversationtoMessage Table
conversationtomessage id | conversation id | message id
ConversationtoUser Table
conversationtouser id | conversation id | user id
Does it makes sense to have the creator of the conversation column in the conversation table, or is that redundant information given that the creator will also be linked in the conversationtouser table

I think it can be done using two tables only:
users
id (unique id)
username
name
created
messages
id (unique id)
user_id
type (1 for individual messages, 2 for group messages)
message_identifier ( unique id for particular conversation)
message_text
created

Related

MySQL: Get latest unread message from 3 or 4 tables that are associated with eachother

Thank you for your help! I'm pretty new to SQL. And thank you for bearing with me through this long explanation. Just want to make sure I'm detailed:
I'm building a messaging system. What I need to do is retrieve the latest unread messages for 1 or more specified users, in DESC order.
Here is how I have the system currently structured:
A conversation can be created between 2 or more users and/or groups, and each user and/or group is associated to that conversation. Users/groups in the conversation can send messages to each other.
When a message is sent, it is associated to the conversation. Then each user/group in the conversation is associated to that new message.
So to store all of this, I have the following tables:
conversation
message
assoc_message__conversation
assoc_user_group__conversation
assoc_user_group__message
I have the following db-fiddle with my table structure and example data inserted into them:
https://www.db-fiddle.com/f/s5bU15eVSxb5TDXy2GVtUS/0
As you can see, I've put in 4 conversations, each with 2 messages - "First Message" and "Last Message".
Pretend I'm user u-1000001 and group g-1000001. You can see that this user and group are in conversations 1, 2 and 3 together. You can also see that this user and group have read both messages in conversation 1 by looking in the assoc_user_group__message table.
What I need to do, is to be able to specify u-1000001 and/or g-1000001, and retrieve the latest unread message for each conversation the specified user and/or group is in, ordered by latest unread message DESC (by message_id, not send_datetime). I also need to be able to specify a message_id to retrieve X amount of unread messages before the first request, or X amount of new unread messages after the first request (message_id < 4 or message_id > 4).
I need to retrieve the following fields for each unread message: conversation_id, message_id, message, send_datetime, raw_id, user_type. You can see that these fields are across 4 different tables: message, assoc_user_group__message, assoc_user_group__conversation, assoc_message__conversation
The following is an example of what should be retrieved if I put in u-1000001 and g-1000001 (omitting field send_datetime):
| conversation_id | message_id | message | raw_id | user_type |
-----------------------------------------------------------------
| 3 | 6 | Last Msg | 1000001 | user |
-----------------------------------------------------------------
| 2 | 4 | Last Msg | 1000001 | group |
-----------------------------------------------------------------
| 2 | 4 | Last Msg | 1000001 | user |
-----------------------------------------------------------------
And if I were to just put in u-1000001, I would get the same results, just without the group rows. You can see that conversation_id 1 is omitted because both user and group have read the messages in that conversation.
I know this is a complicated question, but I really appreciate your time and help!

DB schema for a resource-based messaging system

My laravel application has some services and products, for simplicity's sake, I will keep it as generic as possible and I am going to call an individual service/product a resource.
I will have to implement a messaging system in such a way, so that a client can send message to the admin (and vice versa) against a single resource.
For example, consider project as being one such resource. An admin can create a project, a client can send messages to the admin who created that project. A client cannot create a project.
This is how I designed the db schema:
Message Storing Part:
conversations(id, message_id, from, to, body, is_seen)
messages(id, resource_id, resource_name)
Resource Storing Part:
projects(id, admin_id, client_id, some_other_column)
another_resource(id, admin_id, client_id, some_other_column)
yet_another_resource(id, admin_id, client_id, some_other_column)
Notice the resource_id and resource_name in the messages table:
resource_id is the id from one of the resource tables (projects, another_resource, yet_another_resource).
resource_name is where my problem is. If I implement this schema, I would have to hardcode a tablename in this column. An entry in the messages table would look like this:
+----+---------------+-------------+---------------------+---------------------+
| id | resource_name | resource_id | created_at | updated_at |
+----+---------------+-------------+---------------------+---------------------+
| 1 | project | 1 | 2018-01-13 15:11:07 | 2018-01-13 15:11:07 |
+----+---------------+-------------+---------------------+---------------------+
As you can see, if some client had to send a message on an entry of another_resource I would have to store the string "another_resource" as the resource_name in messages table and the id of that row of another_resource as the resource_id
I admit that I am not a good db designer but I have a strong feeling that storing a tablename as a column value is not a good idea. There must be some dynamic way of handling it. How could I improve my schema? Any modification, suggestion or advice will be greatly appreciated.

Need database structure for private, group and public chat - MySQL

My basic idea is to build a web-based chat application. I have checked a lot of database structures over the internet for my requirements and the conclusion is that there are so many solutions for that.
So here is the database structure I thought (But I'm pretty sure that it is not 100% correct or at least it can be improved)
Table users:
id | username | email | created_at | updated_at
Table chat_rooms
id | room_type | created_at | updated_at
Table: room_members
id | room_id | user_ids (in serialized form)
Table: messages
id | room_id | sender_id | message | created_at | updated_at
Table: receivers
id | message_id | receiver_id | read_at
There are 3 types of chats:
i) Private chat - a chat between two users
A user will select another user to start to chat with him/her
ii) Group chat - a chat between group of users
A user will add other users into the room to start a group chat
iii) Public chat - a chat between all the users
An open chat room to which anyone can join and send messages
So here is how it will work:
I logged into the site, redirected to the dashboard page. On that page, I have 3 options to start a chat as described above.
Notes:
1) If there is a previous chat between the users it should be shown as soon as I start a chat (pretty similar to Facebook) - This applies to all the three types of chats
2) I want to have a feature which says that when a specific user read a message.
3) I want to keep it scalable as much as possible for the future enhancement
Thanks
Yes this DB structure is workable for make alpha version.
you can make some small changes according to your requirement.

MySQL relationships. User roles

I have 3 type of user roles: Patient, Doctor, Pharmasist
And Tables:
Users
id | name | surname | username | password | etc..
Roles
id | name
Patient
Doctor
Pharmasist
users_roles
id | user_id | role_id
And I want to implement tables such as: doctor_info, patient_info, pharmasist_info.
For example:
doctor_info
id | experience | qualification | user_id
What relationship should I use to tie users with doctor_info, patient_info, pharmasist_info and how to implement it correctly?
Assuming all id column from each table is primary key.
users:
id, name, ...
roles:
id, name
users_roles:
id, user_id, role_id (make user_id UNIQUE key, so 1 user can only have 1 role)
doctor_info:
id, user_id, ... (make user_id UNIQUE key as well, so 1 user can only be 1 doctor)
patient_info:
similar to doctor_info
pharmasist_info:
similar to doctor_info
(OPTIONAL) If 1 user has 1 role and 1 role is belonged to many users, you could remove users_roles table completely, and just add role_id in users table.
One issue is that you can have: 1 user can be a doctor, a patient and a pharmasist altogether with your table structure. You'll have to add some validation in your code to make sure it won't happen.

Extending a table (one to one relationship)

I have a Users table that belongs to a Role, and has one Server or no one (depends on role), but should to have a Server table with user_id field or should I put all Server info in Users table and when the role hasn't Servers, the fields will be null?
I just think that if a User have one server (or not), this shouldn't be a new row in Servers table, maybe if the user_id field be unique, then it will be correct, I don't know.. I'm confused.
Just explain to me which is the best way to build this thing.
-- edit
This is my tables actually
Roles
id (PK) | name
1 | Administrator
Users
id (PK) | role_id | name
1 | 1 | Juliano
Servers
id (PK) | user_id (UNIQUE) | name
1 | 1 | Test
I don't know.. in servers, user_id should be UNIQUE or PK?
ONE TO ONE Relation , Then put the server in the user table.
Users Table:
ID(Pk)
RoleID
Name
ServerID