From an end-user perspective, single-click unsubscribe is excellent.
However, using hash(id + secret) is insecure because a clever attacker can very quickly "brute force" the secret, then proceed to unsubscribe every user in your DB simply by incrementing the user ID.
It is much more secure to keep the user ID "semi-secret" on the server and use the e-mail address to lookup the user upon unsubscribe. This way, a successful unsubscribe requires pairing an email address with the correct user ID.
You can make this even more secure by saving a truly secret key or nonce for each user and using that instead of the user ID. This is especially necessary if the email + user ID pairs are published.
So, for example, your unsubscribe link would look like this:
http://example.com/unsubscribe?email={$email}&hash={$hash}
And a server-side function to generate $hash would look like this in PHP:
<?php
function unsubscribeHash($id, $email) {
$hashSecret = 'Fz!Fx~36N66>io3B-vlPDshdRxos8JjCd4+Ld-s2^ca{19Q/5u';
return sha1($id . $email . $hashSecret);
}
?>
Then, to complete the unsubscribe, you will lookup the user by email, and verify
$_GET['hash'] == unsubscribeHash($user_id, $_GET['email'])