Why should I create an ID column when I can use others as key fields?
1 - It's faster.  A JOIN on an integer is much quicker than a JOIN on a string field or combination of fields.  It's more efficient to compare integers than strings.

2 - It's simpler.  It's much easier to map relations based on a single numeric field than on a combination of other fields of varying data types.

3 - It's data-independent.  If you match on the ID you don't need to worry about the relation changing.  If you match on a name, what do you do if their name changes (i.e. marriage)?  If you match on an address, what if someone moves?

4 - It's more efficient  If you cluster on an (auto incrementing) int field, you reduce fragmentation and reduce overall size of the data set.  This also simplifies indexes needed to cover your relations.

EDIT

To the specific points you just added:

1 and 2 - It's still much quicker to compare an int than a string, space considerations aside.  You are also conveniently ignoring overhead needed to store length of variable length fields (normally 2 bytes per field per row).

3 - If you cluster on the ID field then it doesn't add anything extra.  It SAVES space since you are using a more efficient row id.

4 - And then when that person changes their username your links all break.

5 - You really don't know what you are talking about here.  You do have to store the data, that's correct, but it's much more efficient to index and JOIN on the int than on a combination of other fields.