views:

230

answers:

2

While I can find the answer to almost any specific question I have concerning PHP + MySQL development, one resource I haven't been able to find is good solutions to advanced problems.

I want to implement a minor messageboard type system that can be queried by AJAX, but it I have too many specifications for it to be filled by a prebuilt library, and I don't need a tutorial about how to implement and use a database.

What I'm looking for is a resource that provides good solutions to advanced users for more complicated problems than "store a message and print the last 10 messages"-style tutorials.

For example: My website will have group pages each with any number of users, and the private group page will have a small "wall"-like message board. What should I take into consideration when designing this particular table? How should I implement locking? Etc.

Of course, I don't expect there to be a tutorial for my exact problem, but I would like perhaps a complete solution to a db-driven website that can be comprehended (unlike WordPress - a little too spread out) and that actually works (unlike the full-solutions you sometimes find at the back of a reference book).

+1  A: 

You'll find that all of the things you mentioned (presumably as "advanced issues") are all a series of rather simple approaches and technologies built together in a thoughtful way.

Locking a table to keep multiple users from editing simultaneously is a rather simple issue. The issue of locking has been addressed here numerous times.

As for assigning members to groups, that's just a man-to-many relationship between a few tables. You'll have your Users Table, a Groups Table, and a Users-to-Groups table. That's assuming a user can belong to multiple groups.

By doing a couple small joins in your query, you can get posts for a specific group from various different users - and thus fill your group-specific board. Furthermore, you can privatize that board by requring your user exist in that group in order to read that board - this is just a quick query of the Users-to-Groups table to see if that UserID exists alongside that GroupID.

Jonathan Sampson
And I realize that, but as I'm combining approaches, the possibilities branch exponentially. I can be thoughtful, but I don't have enough experience to always make the right decision, and I'm building an application that requires stability and quality of design that I think I can provide if I make certain decisions properly for which I'm looking for a resource. And sorry for the run-on sentence!Also your link translated weird - the %20s->+s need to be changed back in Google. Don't know if you need to fix it.
Patrick Lucas
Sorry 'bout that. The link should work now.
Jonathan Sampson
Ahh, concurrent editing - sorry Jonathan :)
Andy Mikula
Hehe. No problem. I did a rollback. The link had to be disguised to work - likely a formatting issue with how SOFlow handle's URLs. I took it through tinyurl, and it works.
Jonathan Sampson
Actually you touch on something I've wanted to ask about: I have a users table ([user_id], [username] etc.) and a groups table ([group_id], [group]). Are you suggesting I give their relationship as another table u2g ([user_id], [group_id])? Is that the best way, or would it be better to have an attribute of a user the groups he can belong to? ([groups] => '23,56,99')
Patrick Lucas
By creating the third table, a member can now join practically infinite groups. If you add a groupid-field to the user table, the user is limited to however many groups you have in their table. Ideally, you should normalize your data, meaning create the third table, and handle as many group memberships as you want without limits in the future.
Jonathan Sampson
With the groups table, you can have ({"user": "1", "group": "2"},{"user": "1", "group": "5"}), etc. One member can join 1, 2, or 100 groups without requiring any changes to any tables.
Jonathan Sampson
+3  A: 

I am a .net guy so I will stay generic is my solution. I don't think the solution you need is language specific any ways. What you need to look into is design patterns and enterprise methods for doing certain things. The key for your success doesn't come (entirely) via database implementation but what and how you use the data. To scale you need to be able to write quickly (write to a queue instead of to the db) and read quickly (read from a cache layer when possible instead of the db) and search quickly (search from a Lucene index instead of the db). Many people get hung up on the db and they are generally correct in doing so. It is the central part of your applications data storage and querying. But it is also usually one of the single biggest bottle necks in any system. Sure, store all your data to the db, just don't do it directly. Sure, read and query your data from the db...but only when absolutely necessary (use an index to locate the data, then just read the data from the database).

The same goes when having your application speak with external services. Take the sending of an email for example. Rather than sending the email by connecting to the SMTP server and packaging and sending the email...stick the message into a queue and create a queue reader to connect to and send the email via SMTP. This way your web app continues running smoothly.

The key to your success is performance oriented research and good architectural design. Look up things such as domain driven design, inversion of control, test driven development, repository pattern, model view controller, memcached, velocity, queue, MSMQ, database mail queue, etc.

Andrew Siemer
Great response, thanks for the ideas.I understand the issue of provided queues and caches to make it run smoother and make the db less of a bottleneck, but since my primary language here is PHP, things are by default asynchronous. Are you suggesting I write a server-side daemon sort of thing that handles the queues? I could do that, but that would hamper my rate of production.I might make things abstract enough though to allow me to implement that once the project has gotten off the ground.
Patrick Lucas
If everything is programmed with enough abstraction you should be able to "insert" a new layer of functionality at any time! If you are doing everything asynchronously then this "shouldn't" be an issue for you. However, however...how do you read in an async manner? Either the data is there when the page opens or it isn't! {GRIN} Sending email through a queue is best...queueing each insert to the db and then doing a mass write to the db is generally faster. I am sure PHP has some form of an offline queue...I just don't know it.
Andrew Siemer