The point of a salt is to prevent attackers from amortizing the cost of a brute force attack across sites (or better yet, when using a different salt for each user: all users of a site) through precomputed rainbow tables.
With plain hashing, an attacker can compute such a table once (a very long, costly operation) and then use it to quickly find passwords for any site. When a site uses one fixed salt, the attacker has to compute a new table specifically for that site. When a site uses a different salt for each user, the attacker can stop bothering with rainbow tables – he’ll have to brute-force each single password separately.
Storing the salts separately is not necessary to gain this advantage. In theory it would be even more secure because it would neutralize the weakness of dictionary or short passwords. In practice, it’s not worth bothering with because at the end of the day, you need access to the salts somewhere to check passwords. Also, trying to separate them would lead to more complex systems – and the more complex a system is, the more opportunities for security holes there are.
Edit: My concrete recommendations:
- Generate long pseudorandom salt for each user and store in in the DB
- Use a bcrypt-based hash
- ideally, don’t implement it yourself, use an existing library instead