A subspace is really just a convenience wrapper around a key prefix. From the database’s perspective, there’s nothing special about it and there‘s no record that you’re using it that way.
If you aren’t using arbitrary raw prefixes in your subspaces (i.e. you are using tuple based prefixes with an optional known raw prefix), then you could conceivably construct a hierarchy of tuple elements by reading the keys that are present and decoding the tuples. Depending on how deep you want to go, this may require reading a lot or even all of the keys.
The directory layer adds some extra functionality to help you manage subspaces by providing an indirection from arbitrary path strings to subspaces that you can write to. Because this data about the hierarchy is stored in the database, it makes it easier to list members of the hierarchy.
When you create or open a directory in the directory layer, the object you get back is typically named something like
DirectorySubspace. This is because it allows you to manipulate the directory in the hierarchy and also provides access to the contents (the subspace) of that directory. It can sometimes be helpful to think of a directory as a subspace that is indexed in the directory layer.