1a) Strength of encryption - requirement in the range of 4..31. See http://php.net/manual/en/function.crypt.php
1b) See 1a
1c) See 1a. 'salt' should not be random, or you would not be able to regenerate the same hash for a given input - see 3.
2a) Strictly speaking, everything except the hash (in case database is compromised). Also, store your salt in a file not accessible beneath the web server's document root and include it. Set it with the strictest permissions possible; ideally read only to web host service (e.g. apache), no write or execute privileges. Less strictly speaking, depends how defensive you wish to be against hackers. Not storing the salt just makes life more difficult; they still have to get the data being input to the algorithm right - but why make it easier?
2b) VARCHAR(32) should be fine for blowfish, if not storing the hash
3) Assuming you've already run the proper injection prevention code, etc.. so please don't just copy the below blindly (and ideally use PDO instead of mysql extension). The below is specific to blowfish, SHA-256 and SHA-512 which all return the salt within the hash. Would need modification for other algorithms...
//store this in another file outside web directory and include it
$salt = '$2a$07$somevalidbutrandomchars$'
...
//combine username + password to give algorithm more chars to work with
$password_hash = crypt($valid_username . $valid_password, $salt)
//Anything less than 13 chars is a failure (see manual)
if (strlen($password_hash) < 13 || $password_hash == $salt)
then die('Invalid blowfish result');
//Drop the salt from beginning of the hash result.
//Note, irrespective of number of chars provided, algorithm will always
//use the number defined in constant CRYPT_SALT_LENGTH
$trimmed_password_hash = substring($password_hash, CRYPT_SALT_LENGTH);
mysql_query("INSERT INTO `users` (username,p assword_hash) VALUES '$valid_username', '$trimmed_password_hash'");
...
$dbRes = mysql_query("SELECT password_hash FROM `users` WHERE username = '$user_input_username' LIMIT 1");
//re-apply salt to output of database and re-run algorithm testing for match
if (substring($salt, CRYPT_SALT_LENGTH) . mysql_result($dbRes, 0, 'password_hash') ) ===
crypt($user_input_username . $user_input_password, $salt) ) {
//... do stuff for validated user
}