views:

54

answers:

2

i wanna create a 2 level status message system. Which is the best way to create a tables ?

Scope:

  1. User sets a Status Message
  2. Users Reply to the status message

this is a picture showing it

alt text

Tables i have created

users (id, name .... ) status_messages (id, message, time, user_id) status_message_replies (id, message, time, status_message_id, user_d)

Some one suggested this can be done in a single table format

status_messages (id, pid, message, time, user_id)

where pid = selfId or ParentId of the status.

I wanna know which is the best method to create the system ?

+1  A: 

A classical IS-A relationship: every reply is a message with an extra attribute (the message it is a reply to). This is probably not the best way to model it. You'll be running the risk of having to write a lot of UNION queries over those two tables.

Alternatives:

  • just one table: status_messages (id, message, time, status_message_id, user_id), and allowing status_message_id to be NULL
  • use a HAS-A: one table status_messages (id, message, time, user_id) and one table replies (reply_id, replies_to_id

The former has the disadvantage that working with NULL is tricky in SQL. The latter will necessitate joins when you want to query replies specifically.

BTW it's much clearer (IMO) to name columns after the relationship they stand for, not the table they refer to.

reinierpost
so can i use this status_messages (id, pid, message, time, user_id) where pid for the status will be the self id and if its a reply it will be a parent id ?
Harsha M V
If you do that, how will you identify a reply?
reinierpost
Reiner: you don't use NULLs for the original messages, you set the parent message id equal to the message id of the message. Messages that "point" to themselves as parents are originals, messages with different values in parent and "self" id are replies. No NULLs needed, and no question about which is which.
Larry Lustig
@Larry, on the scale of Facepage, those extra values will add up to a shedload of extra storage. If someone thinks working with NULLS is tricky, Databases might not be the best career choice.
Stephanie Page
Yes, that is why I don't advise storing them.
Larry Lustig
@Larry Lustig: nice idea, provided of course that all calling code uses an equality check to recognize non-replies.
reinierpost
@Stephanie Page: will it really require more storage? I don't think so. Queries involving the distinction between replies and nonreplies will be a little more expensive though.
reinierpost
If you fill a column with a self-referential key value vs a null. Yes the data in that column will be larger than a null, therefore the row will be longer, therefore you'll fit fewer on a block, therefore you'll need more blocks, therefore you'll require more storage. So yes.
Stephanie Page
Stephanie Page
@Dtephanie Page: the column may be fixed width ... but I agree with your main point that no single solution will always be the best.
reinierpost
+2  A: 

As long as the original messages and the responses have the same structure (set of attributes, or columns) then you can use the single table approach. It has the advantage that you can search over original messages and responses with a single query.

The set of original messages can be found where pid = selfid and the responses where pid <> selfid. If it's important to be able to see the original and response messages separately (without knowledge of the storage mechanism) you can encapsulate the above conditions in two VIEWs: OriginalMessages and Responses.

If the originals and responses have different attributes (for instance, if you want the original to allow links to URLs, photos, etc) you might consider using two separate tables. But even there, I'd probably argue for the one table structure with a separate, extender table for the additional attributes. That means you don't have to store often-empty columns for those original messages that don't use the extended attributes, and you can later easily add the extended attributes to the response messages as well (if desired).

Larry Lustig
as long as the "empty" columns are at the end of the table, why would you care?
Stephanie Page
Common sense argues that a model of something should not contain attributes that don't apply to a thing. One of the normal forms states that you should have no cells in a table that contain NULL under normal processing. And performance consideration indicate that you don't want to store columns (even NULLs) that you don't have to. In the example above, you could easily OUTER JOIN the extender table into the OriginalMessages view to provide a single-query source of original messages with all the columns present, without the extra storage.
Larry Lustig
when inserting the first record. i mean the original message. how do i insert the pid ? since we wont know the id of the record. do we need two queries here ? can u give an example of the sql query if not so
Harsha M V
@Harsha, you have a variety of options but in MySQL your best bet is probably to issue SELECT LAST_INSERT_ID(); and then perform an update: UPDATE table SET pid = id WHERE id = %ValueFromLast_Insert_ID%;. You may be able to use LAST_INSERT_ID() directly in the UPDATE statement, I'm not sure.
Larry Lustig
cool thanks ..:D
Harsha M V
i am having troble pulling the content out of db. when i set i want StatusMessages of user_id = 1. i need only the main messages with a subarray of the replies. How can i make sure that Status message have id = pid and replies dont contain records that have id = pid
Harsha M V