Bundy Bundy - 3 months ago 9
MySQL Question

Badging/marking content that has changed since the user last saw it

I was wondering if there is a general database structure for the following situation.

In my web app, there are users and projects.

Now, whenever a project is created or modified, all users who have not seen that new / modified project yet have to be notified in some way (e.g. an icon in front of the project title or something)

Is there a general method for this? If so, what's the method and how do I do this the most efficient way?

Answer

Looks like a many-many relationship for "what users have seen what projects", best implemented with a table with exactly two columns -- a foreign key into the users table and one into the projects table. When a project is created you don't yet add entries to this table (unless you can identify a certain user as the creator who's deemed to have seen the project, in which case you do add that one entry) -- you add an entry (U, P) each time the "user U has seen project P" occurs. When a project is modified you remove all entries in the table regarding that project (again, except maybe the one for the user who is doing the modification, if you know who).

Need the SQL for this table's schema and the operations I've outlined in words?

Edit: a commenter requested the SQL, so (assuming InnoDb, in the case of mysql), assuming tables user and project have int primary keys uid and pid respectively:

create table Seen (uid int, pid int, 
                   foreign key uid references user(uid) on delete cascade,
                   foreign key pid references project(pid) on delete cascade,
                   primary key (uid, pid))

When an existing project with a pid of P is modified, so no user is now deemed to have "seen" it, delete from Seen where pid=P (i.e., remove all entries for P from this table); if the modification is made by user U, so user U is actually deemed to have seen it, you can add and uid!=U to the where clause of the delete.

To mark the fact that a certain user U has now seen project P, insert ignore into Seen(uid, pid) values (U, P) (the ignore part means "do nothing if the row was already there", so that recording the "seen" conditions more than once is innocuous, although of course redundant).