Is the complexity of the *nix IDs completely warranted or can it be mostly attributed to historical precedents? Would there be a way to significantly simplify it without really reducing flexibility (I'm not necessarily looking for a backwards-compatible way)?
The problem is not so much of user IDs, but rather how UNIX implements security. "root" can do privileged things, everyone else can't. For example, only the root user can listen on port 80. These rules are hard-coded in the depths of the OS, meaning you have to work around them.
The problem is that you don't want your process-that-listens-on-port-80 to have all the other permissions that "root" does. So you have to drop your privileges after binding port 80, resulting in the complexity of effective and real UIDs (and GIDs).
The solution is fine-grained access control. You don't want to say "run this app as nobody", you want to say "let this app connect to the MySQL server, write to /tmp/my-app, and load shared library foo". Could you implement a system like this? Yes. (SELinux is a start.)
But really, it is time for UNIX to die. "Worse is better" is getting old, and UNIX can't be fixed. Someone needs to implement a real OS (and provide UNIX compatibility so users can easily migrate).