I have a table Users (UserID, FirstName, LastName...) and a table Messages. Table Messages stores messages, which are sent between users.
So, I can create this table like:
Messages (SenderID, ReceiverID...) and create 2 FK to Users, but this approach seems is incorrect and does not allow to make cascade delete/update for FK.
Multiple messages are not allowed.
Also, I can't set "Set Null" for both relationships. Why? It would be very good.
Which structure is correct in this case?
You have to look at the problem from the users perspective.
Do you think that the receiver wants it's message deleted when the sender deletes it's message from the outbox?
No. In other words: Create one copy of the message for each user.
Multiple messages are not allowed
Insane requirement. It IS two different messages.
Related
I'm working on some asp.net application, I got stuck in following business.
Suppose we have a person, and he can open both types of accounts and each account has some transaction history. Person table has some primary key say PPK, and customer table has some PK as PIN.
My question is how to solve/present this scenario in database, relation of person table to customer table is 1:2 as no person can have more than two account. and what about that transaction table? that holds all transaction history for some specific account? shall I make two transaction table (which is really a bad idea because as account type exceeds transaction tables exceeds).
Can I build their relation as 1:* (then I may need another table for that. it holds Fk of both table. )
or Can make pin as unique key and always open database for like checking limit of accounts (i.e. two).
I really need some suggestions.
All suggestions are welcome.
Thanks!
P.S: If you dont understand the question please ask me before reporting it away please!
You can either do something like this:
Or something like this:
The first model allows adding more accounts by just changing the CHECK (in case requirements change in the future), while the second would require adding another column in such case.
NOTE: The above assumes both account types are structurally identical, so they "fit" into same table. If that's not the case, you can use inheritance.
Ok you have a person table and an account table with a foreign key relationship between the two which is 1 person to many accounts. Then you have a transaction table that is related to the account id in the account table which is also 1 account to many transacations.
Now to enforce the limit of only two accounts being allowed, for that you want a trigger that checks when a record is being inserted or updated to amek sure the person currently has no more than one other record.
I need a suggestion about sql table schema. I've opened a table and named it Chats, would it be better for me to add two columns(like ID and Messages) or one that will contain the IDs and the messages? And which one of them will work faster
Personally I'd model this as two tables:
Chats
- ID
- Name
Messages
- ID
- ChatID
- Message
- SentDate
There should be a foreign key from Messages.ChatID to Chats.ID.
Otherwise you're going to have to create duplicate chats each time someone sends a message.
I would strongly recommend against keeping IDs and Values in the same column, it makes it near impossible to join on and will create all sorts of problems later on.
There is no reason to use a single column. Add as many columns as possible, each with its own data type because you will be able to filter and sort the table by each column later. You will also be able to add constraints, indexes, statistics, etc... if needed.
Any query performed on that table will work faster if you use separate columns.
I am designing a database for a social media website (uni assignment).
I have been struggling with the messages link to member. There will be a need for two foreign keys from the same primary key in messages. One for the sending member and one for the receiving member. I was unsure if this was possible or a good idea so i was thinking of assign a member to a inbox (Many Members - One Inbox). Then assign all messages to the inbox (One Inbox - Many Messages).
Member Many------1 Inbox 1------Many Messages
Tables look like....
##################
Member Profiles
Member ID (PK)
Name
Gender
Inbox ID (FK)
##################
Inbox
Inbox ID
##################
Message
Message ID (PK)
Inbox ID (FK)
Message Direction .... either to or from (then the members name)
Member ID (FK)
That's what Ive got so far id appreciate some pointers if ive gone off the right path. Because the more i look at my design the less i like it.
The draft model may helps you:
Message creation:
Message consumption: (after send message process)
No don't do that
Messages can belong to multiple members and members can have mulitple messages, so you need what is called a Join table.
MemberMessage
Memberid
Message id
Have you considered changing the MemberID field on the Message table to something like SendingMemberID, and then adding another field called ReceivingMemberID? This would allow you to avoid the somewhat confusing Message Direction field.
Sure you'd need to join to it twice to get all incoming and outgoing messages for a user, but that's really not a bad thing. The alternative option of having two records for each message (one for sender, one for receiver) has its own drawbacks.
Good luck!
I've been dissecting Skype database main.db for a couple of days, and this is something which I haven't yet figured out. Naturally, this question will be very specifically for Skype main.db structure.(disclaimer)
It seems that all the necessary information that I need are in tables Conversations, Messages, Participants.
Message table contains actual log that has been said, the recipient(s), timestamp, and the convo_id foreign key(although not enforced) to connect to a Conversation which the message belongs to.
Conversation exists to hold the aggregates of Message and the Contacts that participate in.
Participants table works to a many-to-many connector table between the Conversations table and Contacts table.
What gets me are Chats and Chatmembers table. Chatmembers works to Chats what Participants table works to Conversations table; connecting Contacts and the conversations-or 'chats'.
What's in Chats is similar to Conversations except that it does not have any aggregate to Message table. It is impossible to map from Messages table to Chats table to which the message log(row of Messages table) belongs.
Chats and Conversations share a foreign key, Conversations table has a column named chat_dbid which joins to the Chats table. But there are rows in Conversations table which have a null chat_dbid field, and not all rows in Chats have id field which corresponds to chat_dbid field in Chats table.
The Chats table is still being updated and I recognize some of the chats-or conversations- I've had recently based on the timestamp and the members in it.
Does anyone know exactly what Chats table does? Or rather, what's the difference and justification for Chats table and Conversations table?
When I looked frantically for this I could find only one like that talked about main.db structure, and it wasn't very helpful.
According to the link Chats
Provides the chats in which the user participated.
and Conversations
Provides a list of the conversations in which the user participated.
What's their terminology about Chats and Conversations? How are they different?
It's been driving me crazy.
Yesterday I was also going through main.db table in skype. Below are my findings.
Conversations table uniquely identifies conversation with a particular contact(or a group contact you have created). Conversation entails all communication: chat messages, voice message, file transfers, calls that you do with a particular contact. Most of the tables have references to the entry in this table.
Messages table has convo__id,
Chats table has conv_dbid,
Transfers has convo_id and likewise.
Messages table: messages entry are not always chats. If an entry is chat then its chatname field is populated.
It seems that chats and messages has one to many relations. chat is a collection of messages maintained per some identifier(most probably day not sure.). "type=61" seems to be normal message: message typed by user. Other types seem to be auto generated messages for eg. msg you get if a call is disconnected.
Hope this helps.
It looks like Chats are redundant. Messages are grouped into chats as an after-thought, you can have several Chats inside one Conversation and then some messages outside any Chat. The rules for grouping are unclear, perhaps by time.
Grouping is done by setting chatname field of a bunch of messages to the same value. Chat names look like #SenderId/$TargetId;ChatId or #SenderId/ChatId for Chats over groupchat.
ChatIds don't seem to hold any particular meaning and can be different on different PCs.
Not every Chat gets an entry in Chats table: SELECT DISTINCT(chatname) FROM Messages gives a great many more entries than SELECT * FROM Chats. Not everything that goes into chatname is a name of chat from Chats. Sometimes it's a conversation id (== groupchat id or skypename).
Different Skype instances also group the same synchronized messages into Chats differently.
So basically Chats are not important, they group messages arbitrarily, they don't contain any key data about who sent what to whom.
This is how I understand other tables work:
Contacts - this is everyone whose skypename is mentioned in the database, even people you never knew about (which said something in the groupchat you were listening to at the time). is_permanent marks those in your contact list.
Conversations - this is a union of your actual contacts and groupchats you have ever had joined. This is what one should see as "contact list". If you need contacts you've never messages, add Contacts WHERE is_permanent=1. If you only want present contacts, filter by is_bookmarked or something like that.
There seems to be no duplicates and splits. One contact = one conversation, one groupchat = one conversation. If you're talking with a contact one on one and you add another party, previous messages remain in that contact's Conversation, and the following ones get their own Conversation.
Messages - this is all messages and events ever sent or received:
convo_id - always set, always references a conversation. This is how you identify to what contact / groupchat the messages was sent.
chatname - always set, sometimes references a chat from Chats, sometimes a chat which is not in Chats, sometimes a groupchat id or skypename from Conversations. Mostly this can be ignored, or you can group messages by this field visually.
author, from_name - who sent this message and their nick at the time, always set properly.
dialog_partner - very unreliable, different values for the same message on different PCs
participant_count - sometimes set, sometimes not, same as with dialog_partner: unreliable.
identities - mentions all skypenames related to the event, or sometimes doesn't. Rules are unclear, unreliable.
I'm creating a simple private message system and I'm no sure which database design is better.
The first design is a table for messages, and a table for message comments:
Message
---------------
id
recipientId
senderId
title
body
created_at
MessageComment
---------------
id
messageId
senderId
body
created_at
the second design, is one table for both messages and comments, and an addition field messageId so i'll be able to chain messages as comments.
Message
---------------
id
recipientId
senderId
messageId
title
body
created_at
I'd like to hear your opinion!
In this case, I'd vote for one table.
In general, whenever the data in two tables is the same or very similar and the logical concepts they represent are closely related, I'd put them in a single table. If there are lots of differences in the data or the concepts are really different, I'd make them two tables.
If you make two tables and you find yourself regularly writing queries that do a union of the two, that's an indication that they should be combined.
If you make one table but you find there are many fields that are always null for case A and other fields that are always null for case B, or if you're giving awkward double-meanings to fields, like "for type A this field is the zip code but for type B it's the product serial number", that's an indication they should be broken out.
Using a single table is the most advantageous.
It allows better message threading possibilities and it reduces duplication of effort, i.e. what happens when you want to add a column.
I would rather use the first one and include an additional field del_code to both tables. So, you'll be able to hide deleted messages and still have them in your database.