It is conceptually the same, but when you are dealing with production you you have to think about how to reliably and cheaply duplicate this for hundreds of devices. The device serial number is useless unless you have a way to _automatically_ map it to a physical location.
About PCI: you don't use the bus number at all. The sequence of PCI device:function id-s starting from the root bridge through all downstream bridges and ending at the device gives you a guaranteed unique mapping for that hardware regardless of BIOS, kernel, etc. You only need to define a mapping once for a motherboard/CompactPCI chassis and you get a reliable physical slot identification. That is how it is supposed to work and incidentally that is how Windows identifies its PCI devices.
udev and sysfs provide the same information, so it is technically possible to get the same functionality in Linux.
In a previous life I had to do stuff like hack an embedded PC BIOS and Windows bus driver to support huge numbers of PCI devices. The BIOS code was so bad it was scary (to this day I am impressed that PCs can boot at all), but the PCI bus itself at the logical level was a joy.
So purely as a user of USB, I naively believed that it was similar to PCI.
And I am surprised you commented on i2c. It is fundamentally different from USB - the device ids are fixed, or you can choose a bit at most (in hardware). There is no plug and play. Often you can't even have two devices of the same kind on the same bus. It takes half an hour to implement I2C from scratch via bit banging :-)
And ISA. Oh, ISA... It didn't have slot id-s, but it did have jumpers :-) Not to mention you could actually build an ISA board from scratch and do the decoding manually with wires... Good times.