My understanding is that a salt is not intended to be secret, it is merely intended to be different from any centralized standard so that you can\'t develop a rainbow table or s
The salt, by definition, must be random to be effective. Don't use any deterministic value for this. This of course implies that you need to store it in the database along with the hashed password. UNIX systems traditionally even store the hash in the same field as the password (the salt is a fixed-length prefix of the password). In a database, you can have additional column in the users table.
Trying to keep the salt secret is pointless, because the entire practice of salting and hashing passwords exists only because we know from experience that we can't even keep our databases secret with complete reliability. You can at most store the salt separately and hope that an attacker who gets access to your DB does not find it, but if you used a good hashing algorithm and long enough individual salts, you should be safe either way.
The point of a salt is solely to ensure that you cannot amortize the cost of a brute force attack across an entire database or even multiple databases.
The first is to change the salt with every new version of the software, but this is no good because new versions of the software would no longer be able to test against old password hashes.
A variation of this that I have seen is to generate a random salt during installation (and of course keep this across versions) so that each running instance has a different one. Of course, having a different salt for each password (perhaps in addition to the above) is better yet.
update: use a competent library e.g. passlib for Python.
These take care of generating a per-password salt and they use a proper hashing algorithm (its not enough to just use a cryptographic hash such as SHA1; you have to apply it in a way that makes it very slow to reverse e.g. looping 1000 or more times over it etc. This is how password hash functions like bcrypt work. Password storing libraries do all this properly; they typically produce a string that is delimited so they can determine the hash system and work factor used; you just store the string without needing to know this.
You can store the salt in 'plain-text' in the table.
The salt does not need to be secret to be effective
it just needs to be random.
The salt strengthens a password by making the hashed value incomparable to the same password in the same or other database, and invalidating large pre-generated lists of common password to hash lookups (e.g. 'rainbow tables').
So it's critical that the salt is unique per user and is some random value stored with the password; the alternatives outlined in the question (using the username as the salt, using a single salt value for the whole application) each fail:
if systems use the user-name or other trivia, then the password can be compared to other users with the same name in other systems (imagine how often the 'administrator' or 'root' user account uses the same password in different systems...)
if the system uses a single random salt for all users in the same system, then two users who by chance have the same password would have the same hash, and guessing one user's password would trivially compromise the other.
Your second solution "Have a salt per password stored" is the right one and typically used.
The "Salt" is primarily there to make it difficult to detect when two users have the same password - so you mix a known "Salt" into the password. The salt needs to be gettable at password check time.
So typically either you generate a random salt and store it with the password OR you use some other identifier (user ID, username etc) as the salt.
It's perfectly normal to generate a unique salt for each password. The salt may be a product of existing material (such as a UserID, et-al.) or randomly generated. The advantage is that an attack against the encrypted information becomes more impractical as the strength of the salt grows.
Remember: Every cryptographic algorithm is breakable. Information may only be considered "safe" if cracking the protection (via a rainbow table or otherwise) is more costly than the information is worth.
edit:
Presuming you're very new to cryptography, here's a few more tips:
You actually already have a salt value stored in the user table: the pkey of the table.
You don't have to invent a new column for storing the salt. Just use the pkey. This idea of course presumes that you do have a pkey associated with a user name. e.g. the user name is not the pkey in the table.
This is a near dup wtb: Password hashing, salt and storage of hashed values