I'm totally fine with using any other approach that prevents MySQL from raising an IntegrityError once a tag gets added that already exists in another case variation. That's the major blocker for me.

The root of all the evil here seems to be MySQL's implementation of a string comparison, which is case insensitive. Therefore tags like _awesome_ and _AWESOME_ are equal and considered a duplicate, resulting in an IntegrityError due to the index that forces uniqueness. Case sensitive comparisons are possible, but require at least one of the two strings to be stored as binary, e.g. as a varbinary. A CharField however maps to a varchar, and there is no Django Field that maps to a varbinary at the moment (see creation.py in django.db.backends.mysql).

My approach, to use the existing tag _awesome_ instead of creating a new one _AWESOME_ makes sense to me and is my preferred behavior in this particular situation (... tagging things ...). In comparison, databases like SQLite3 and probably PostgreSQL, that do proper string comparisons, will create a new tag with the name `AWESOME` and the slug `awesome-1` (or any other number that is not used yet). But is something _AWESOME_ really not _awesome_ and vice verca?