Reputation: 16993
I am using MySQL for my database and have the following Message
model in my Django app:
class Message(models.Model):
sender = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='sender_notification')
recipient = models.ForeignKey(User, on_delete=models.CASCADE, related_name='recipient_notification')
message = models.TextField()
read = models.BooleanField(default=False)
recieved_date = models.DateTimeField(auto_now_add=True)
If I am not mistaken, this way the relationship between recipient
/User
and Message
is one-to-many, since a single Message
record can only have one recipient
, but a User
might have many records in the Message
table. However, there will be situations where I want to send the same Message
to multiple Users
. With my current schema, I can just add multiple Message
records, one for each recipient, with the same message
text. However, this seems like a lot of duplication. In this case, would my relationship make more sense as a many-to-many one?
Initially I thought the duplication (multiple Messages
with the same message
field but different recipient
fields) was a bad idea, but the more I think about it, it seems like modeling the many-to-many relationship would actually be more difficult, and require more data. Each Message
record has a read
field to indicate whether the recipient has read the message or not. If I have a single Message
record with multiple recipients
then it seems like I will need another table to keep track of the recipients who have and have not read the message. This means that if I want to send a message to every user, I will need to add one row to the Message
table, but will have to add one row to a "read record" table for each recipient. So not only am I creating more rows total (1 Message
, and one read record each for n users, as opposed to n Message
s for n users), I am also adding an additional table to the mix.
I have done many searches trying to determine whether it is better to have a single table with many rows, or multiple tables with fewer rows, and it seems like there is no definitive answer; instead, it depends on your data and requirements. I am just looking for some insight into the best direction to go in my particular case, but am also interested in any general rules that I might be able to follow in the future, if such rules exist for this kind of situation.
I am very open to having more work for myself up front in order to do things the "right" way (if there is such a thing in this case), if that happens to be necessary. Thank you!
Upvotes: 0
Views: 279
Reputation: 599630
A way of solving the issue with the "read" flag for multiple users is to use a many-to-many with a custom through model, and put that flag there:
class UserMessage(models.Model):
read = models.BooleanField()
user = models.ForeignKey(User...)
message = models.ForeignKey(Message...)
class Message(models.Model):
user = models.ManyToManyField(User, through=UserMessage)
Now each user has an individual "read" field for each message, no matter how many users also read that message. Given the user and the message, you can get the intermediate model with UserMessage.objects.get(user=user, message=message)
.
Upvotes: 3