SQL - enhance schema to count unread messages - sql

I have a simple message schema where a "thread" ties 2 or more users to a stream of messages. Each message belongs to a single thread. It works just like SMS messages, or Facebook messages.
I only need to count how many threads have new messages for a given user. When a user opens a thread, I need to update the db (for that user only), indicating that they have looked at the thread. Given these 2 tables, how should I enhance my schema to store this "updated thread" data for each user in each thread?
MessageThreads:
threadID
lastUpdated
MessageThreadUsers:
threadFK
userFK
I'm thinking along the lines of adding this table (but is there a better way???)
UserThreads
userFK
threadFK
lastChecked

You should be able to just add a lastChecked column to your MessageThreadUsers table. Then you can compare that value to the lastUpdated field in MessageThreads to determine whether the user has new messages. Or something like below should give you the total number of new messages.
SELECT COUNT(mtu.*) FROM MessageThreadUsers mtu JOIN MessageThreads mt ON mt.threadID = mtu.threadFK WHERE mtu.lastChecked < mt.lastUpdated GROUP BY mtu.userFK

What about some kind of unread boolean value in MessageThreads? When a thread is updated, unread is set to true. When a user checks a thread, set it to false.
Just a thought.

Related

Kotlin+Room+Paging+LiveData for messaging app problem

I have 2 tables, first 'group' and second 'messages' and load messages from message table by group id and Paging library, My problem is every time new messages arrived from server and save in messages table Room notify LiveData data changed in table message and if for example I was open MessagesActivity for group 1, if new message arrive for group 2, because that added to messages table, room notify data updated (Which i don't want that).
So please help me:
Select * FROM messages WHERE groupId = 1
I need Room notify LiveData just if new message arrive for group which currently user open that

Can the target of a conversation receive messages from different initiators using the same conversation?

I like this article: http://technet.microsoft.com/en-us/library/dd576261(v=sql.100).aspx because of the receive top (10000) into a table variable. Processing a table variable with 10000 messages would give me a giant boost in performance.
receive top (10000) message_type_name, message_body, conversation_handle<br>
from MySSBLabTestQueue<br>
into #receive
From reading, the receive provides messages given a single conversation_handle. I have 200+ stores all sending messages with the same message type and contract to the same server. Can I implement the server to get all the messages from these stores on a single call to receive?
Thanks
A target can consolidate multiple conversations into few conversation groups, using the MOVE CONVERSATION. The RECEIVE restricts the result set to one single conversation group so moving many individual conversation into a single group can result in bigger result sets, as you desire.
For the records, initiators can also consolidate conversations using MOVE CONVERSATION, there is nothing role specific here. But initiators can also use the RELATED_CONVERSATION_GROUP clause of BEGIN DIALOG to start the conversation directly in the desired group, achieving consolidation and thus bigger result sets w/o having to use MOVE. This is useful because you can simply reverse the roles in the app, ie. instead of stores starting the dialogs with central server, have the central server start the dialogs with each store (thus reversing the roles) and the central server can start the dialogs in as few conversation groups as it likes, even 1. This removes the need to issue MOVE CONVERSATION.

How to know how many unread group messages I have

I'm designing a database. This is what I have to represent:
A user can have 0..n friends.
A user can send 0..n messages to a friend.
A user can be member of 0..n groups.
A group can have 1..n members.
A user can send 0..n messages to a group.
To manage conversations between users, and group I have a table (Talk) with these columns:
TalkId (NOT NULL, PK)
Type (NOT NULL, values: UserTalk or GroupTalk)
StarterUserId (NOT NULL, the user that has started the talk).
RecepientUserId: (NULL, the user that has received the first message. NULL if it is a GroupTalk).
DateStarted: (NOT NULL, when the talk has been started).
GroupId: (NULL, the group that owns the talk. NULL if it is a UserTalk)
I also have a Message table to store all the message for each Talk. This Message table has a column Read to indicate that the recipient has read or not the message.
If user 1 sends a message to a user 2, first I check if there is a Talk row with:
((StarterUserI == 1 and RecepientUserId == 2) OR
(StarterUserI == 2 and RecepientUserId == 1))
If there isn't, I create a new row on it. Then, I insert the message in Message table with Message.TalkId pointing to the row that I have created.
My problem is that I don't know how to know how many unread message a user has for a group talk.
For a user talk is easy checking if Message.Read column is false.
To know if a user has unread messages on a group's talk, I can insert the same message for each group member, changing the recipient. For example:
I have a group, with three members. Member 1 send a message to a group. I have to insert a message to user 2, and the same message to user 3:
But, this can make grow Message table very fast.
I've thought to add new two columns to Talk table, the date for the last message sent to that talk, and the id of user that has sent that last message. If I have the date and the ID for the last message in a talk, I can check if there are new messages, but I can't know how many.
I have also a UserGroup table to store the users that are members of a group, and the users' groups. I can add a new column to this table to store how many messages a user has for a group talk. Every time another user send a message to that group, I'm going to insert a new row on Message table, and increase the value on UserGroup.Unread by one. But I think I'm going to mess the design.
How can I know how many unread message a user has for a Group Talk?
You can add a new table MessageStatus with the columns UserID, MessageID and Read where you add one row for each recipient of a message (UserTalk or GroupTalk). This avoids the redundancies you would introduce when duplicating rows in the Message table.
For convenience you could introduce an INSERT-trigger on Message to create the rows in MessageStatus.

Get the first message of every conversation

I have one table to store all the messages sent inside of a xmpp service. I'm looking to create a query to get all the conversations and the first message of it (like whatsapp in chat logs).
Here is my table.
FromPersonId and ToPersonId are ids for people. What I do is, for example I want to see all the conversations of the personId = 643
SELECT DISTINCT MA.FromPersonId, MA.ToPersonId, MAX(MA.SENTDATE) AS [Date], Body
FROM MessageArchive AS MA
WHERE MA.FromPersonId = #personId OR MA.ToPersonId = #personId
GROUP BY MA.FromPersonId, MA.ToPersonId, Body
ORDER BY [Date] DESC
Above is what I have. And the result is
As you see, the result is for the same conversation. But cannot distinguish that is the same conversation because are the same people but in different position.
How can I fix this?
You miss the 644 to 643 message, supposing it exists, What I recommend is to put a ROW ID autoincremental, this columns can give you exact information about what records come first and what records come after, besides, How do you identify that the message is the same ?
You are missing a 'conversation' table, with a conversationID field being a foreign key in your MessageArchive table, as a manifestation of the 'one-to-many' relation existing between the conversation entity and the message entity: one conversation holds at least one message, and each message relates to one, and only one, conversation.
With such a database model, you would be able to collect the 'top 1' message of each conversation.

sql next entered record

I have the following table "users" (simplified for the purposes of this question) with non-incremental ids (not my design but I have to live with it)
userUUID email
----------------------------------------------------
44384582-11B1-4BB4-A41A-004DFF1C2C3 dabac#sdfsd.com
3C0036C2-04D8-40EE-BBFE-00A9A50A9D81 sddf#dgfg.com
20EBFAFE-47C5-4BF5-8505-013DA80FC979 sdfsd#ssdfs.com
...
We are running a program that loops through the table and sends emails to registered users. Using a try/catch block, I am recording the UUID of a failed record in a text file. The program then ceases and would need restarting.
When the program is restarted, I don't want to resend emails to those that were successful, but begin at the failed record. I assume this means, I need to process records that were created AFTER the failed record.
How do I do this?
Why not keep track somewhere (e.g. another table, or even in a BIT column of the original table, called "WelcomeEmailSent" or something) which UUIDs have already been mailed? Then no matter where your program dies or what state it was in, it can start up again and always know where it left off.
sort by a column (in this case I would recommend userUUID)
do a where userUUID > 'your-last-uuid'