trunk for development, and a branch (production) for the production stuff.
On my local machine, I have a VirtualHost that points to the trunk branch, to test my changes.
Any commit to trunk triggers a commit hook that does an svn export and sync to the online server's dev URL - so if the site is stackoverflow.com then this hook automatically updates dev.stackoverflow.com
Then I use svnmerge to merge selected patches from trunk to production in my local checkouts. I have a VirtualHost again on my local machine pointing to the production branch.
When I commit the merged changes to the production branch, again an SVN export hook updates the production (live) export and the site is live!
Trunk contains the current "primary" development codebase.
A developer will often create an individual branch for any medium to long-term project that could hose the trunk codebase and get in the way of the other devs. When he's complete he'll merge back into trunk.
We create a tagged-release every time we push code to production. The folder in /tags is simply the version number.
To deploy to production we're doing an SVN Export to Staging. When that's satisfactory we use a simple rsync to roll out to the production clusters.
I highly recommend the book (currently in rough cuts) Continuous Delivery, which describes a full process for managing software delivery, based on continuous integration principles (among others).
I strongly dislike the branch and merge approach, as it can get very messy, and is pretty wasteful since you end up spending time on activities which don't actually deliver any new value. You've already developed, tested, and fixed your code once, why create a situation (copying the code to another branch) which requires you to redo this work?
Anyway, the way to avoid branching and merging is to build your deployable artefacts from trunk, and promote the built artefacts (rather than source) as it passes test, staging, etc. This way you are 100% sure that the thing you're putting into production is the same thing you've tested.
If you've got different features which may need to be released on different schedules, changing your approach to how you implement (make functionality configurable, or better yet modular) can help you keep a single development trunk.