views:

100

answers:

6

Hey,

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?

Grt, Nick

A: 

What I would do is create some sort of "Notification" entity (a table). Then you can either let your database-client code insert a new notification when someone adds a new project. Or you could do it automatically using triggers in the database itself.

Exactly how you design the notifications (which tables and which attributes are needed) is really up to the design of your application.

kigurai
A: 

Perhaps something like

users_viewed_projects
+--------+-----------+
+ userId | projectId |

Add an entry to this table for the userId/projectId once its been viewed by that user.

bobobobo
+3  A: 

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).

Alex Martelli
I say go for it, more information can never be a bad thing
Anthony Forloney
thanks! SQL would be nice but I think I can handle it :)
Bundy
+1  A: 

You need a table that shows when (if ever) each user has last seen each project.

create table user_seen_project
(
user_id int, 
project_id int, 
last_seen datetime
);

For each project you need last change time.

create table project
(
    project_id int
    ...
    last_changed datetime
);

Then you can do right outer join for the current user, like this

select project_id, /* other fields*/ last_changed, last_seen 
 from project p outer join user_seen_project up
 on p.project_id=up.project_id
 where up.user_id=$currentUser

In the result set:

  • when last_seen is null - user has not seen this project (new project)
  • when last_seen < last_changed - updated project
  • when last_seen > last_changed - 'old' project
yu_sha
A: 

You want to add a version column to your project table. Then, wherever you reference which projects a user has access to, add a column to show the last version of the project the user made use of.

Now, whenever you are populating information about users and their projects you can check the users last version number of the projects current version number and if there has been a change in the project you will know it.

Of course, this does create some overhead. You will have to update a users version number for a project once they note the update, and each time anything changes to your project you would need to increment the version number. As mentioned by kigurai you can use triggers to automate some of this.

Justin C
+1  A: 

alt text

Damir Sudarevic
thanks! great post!
Bundy