When I wondered it myself years ago and I found a good explanation in a mailing list archive. I think it was [this one][1], by Frances C. Bernstein:

> The problem with numbering started when people wanted to compare the
> 'same' proteins from different species.  They found that there were
> the following possibilities that gave rise to differences:
> 
> 1. More or fewer residues at either end.
> 2. Extra residues at various places within the chain.
> 3. Fewer residues at various places within the chain.
> 4. Different amino acids at the same place.
> 
> Now imagine that residue PHE 195 is very important for the activity of
> the protein in species A.  But in species B it is residue PHE 197 and
> in species C it is PHE 212, because species B and C are not the same
> length as species A.
> 
>   Because people felt it was important to preserve the amino acid numbering for 'important' residues and to be able to readily discuss
> and compare the structures from different species, various people
> decided to try to number the proteins from species B, C, etc. to match
> the numbering used for species A.  In doing this, one must have gaps
> (missing numbers) where a sequence is shorter.  But what should one do
> when a sequence is longer?  This is the case where it is necessary to
> insert extra numbers and this is done by using insertion codes.
> 
>   Thus the insertion code is an integral part of the residue number and it is improper to ignore that field when using a PDB entry.  You
> must also allow for 'missing' numbers when using a PDB entry.

In the PDB format the insertion code is in column 27, following sequence number (columns 23-26):

```
                      nnnnI
ATOM  11918  CZ  PHE D 100      -6.852  76.356 -23.289  1.00107.94           C
ATOM  11919  N   ARG D 100A     -9.676  74.726 -19.958  1.00105.71           N
...
ATOM  11970  CE  MET D 100H     -8.264  83.348 -19.494  1.00107.93           C
ATOM  11971  N   ASP D 101     -11.329  81.237 -14.804  1.00107.41           N
```
Together, columns 23-27 make a sequence ID, which is a mostly-numeric ID of the
residue position.

Note: It's not a full ID of a residue. When you have a point
mutation (a.k.a. microheterogeneity) you have 2+ residues with partial occupancy at the same position. To fully identify a residue both sequence ID and residue name are needed.


[1]: https://lists.sdsc.edu/pipermail/pdb-l/2004-March/001513.html