Ok, let's get one thing straight: Salting has nothing to do with rainbow tables. Yes. Say that again. Salting has nothing to do with rainbow tables.
Well, that's not entirely true. Salts are used to prevent time and memory tradeoffs by amortizing the cost of attacking one hash against the cost of other hashes.
In the case of a rainbow table, using a salt means that the entire table is invalidated.
But there are other ways of invalidating an entire table. You could append a static string to each password (which is not a salt). That would defeat rainbow tables...
The Real Enemy
The real enemy here is not rainbow tables. The real enemy is brute forcing. Modern day machines are so fast at brute forcing that it's cheaper to build a gigantic GPU cluster and do advanced brute-forcing than it is to store enough rainbow table to make it worth the slow disk access.
A salt helps defeat bruteforcing because it's unique. Not per password. Not per user, but unique in the universe (statistically at least). This is why you want to use a random number, and not the username, email or anything predictable.
Again, not because we don't want predictability. But because we want statistical uniqueness. If an attacker attacks two sites that both use usernames as salts, he can amortize his attacks against both hashes at the same time (even though both may be using different passwords).
Salts should be random, and per user.