In my engine/editor, each resource has a ResourceID object associated with it that contains information such as:
- Name - a human-readable string
- URL - the path to the file where the resource is located. This may be used if a resource is external (i.e. not embedded in the file). Can be absolute or relative path.
- Type - a const pointer to a statically-defined ResourceType, which is itself a name+UUID.
- 128-bit UUID which is used to identify/reference resource objects uniquely across all files. This is generated when a new resource is created (including when duplicating another resource), and then never changed.
- Lists of parent/child resources which are used to represent the ownership hierarchy.
- Flags - is the resource externally located (in which case use the URL to load it), is it locked for writing, is it hidden, is it copyable.
- Creation/modification date timestamps.
This information is stored in the header of my container format, which can store or reference any number of resources. When the format gets loaded, it can either read each resource data directly from the file (if embedded), or from the URL (if external flag is set). Usually big resources are external (e.g. audio files), while the rest are all embedded directly as blobs of binary data. The result of loading the container format is a ResourceSet, which contains resources of any type (through some template magic). Then, I can request resources from the ResourceSet either by name, UUID, or URL (UUID is preferred), by calling resourceSet→getResource<T>(uuid). Resources are wrapped in something similar to a shared pointer to control lifetime, but mostly I work with either raw pointers or “references” (which are a raw pointer to resource data + pointer to ResourceID). This works pretty well for my purposes, though building the type system and serialization in C++ was a chore and took many iterations.
So my suggestion is to use both integer ID + URL in some kind of ResourceID class type. Use the URL for loading the files and use the ID for other referencing where strings would be slow. You might also want to later add extra information like I have, and such a design will make it easier to extend.