You've discovered the tip of a very big iceberg. I think it's a right of passage to come to grips with everything that isn't present as much as what we have available to work with.
There's nothing SQL-like. To implement that sort of thing, you take ownership of every single byte. That means things like the generalized nosql collections, b-tree system I'm working on have to be coded.
Upgradability is a hidden challenge, because Smart Contracts store data inside compiled contracts. Upgrading the software appears to mean abandoning the accumulated data. There are solutions that take some time to understand. It's very different from server-centric structures.
Looping over storage in Smart Contracts is, IMHO, an anti-pattern. It's seldom, if ever, a good idea to work with more than one record at a time in the contract. You can have privileged users and clients that handle loopy stuff offchain.
There are new and strange structures to learn about so you can make informed decisions about which to use. Contract factories and tokenization, for example.
Given the costs, performance and other factors, one should generally look to onchain storage for the minimal facts that must be true at all times and look into offchain storage for supplementary storage that should be fast and flexible. We get into some architectures that approach things from that perspective.
Having said those things, I would turn your attention to a simple candidate pattern I've used with success. One answer to "Okay, so this is reality, I still need to store some data, so how?"
The pattern uses an iterable mapping. "Iterable" meaning access the data by row number. Mapping meaning random access by primary key in one move. The contract maintains the structure through insert, update and delete operations.
Query multiple smart contracts' public data
Have a look at how the "Hub" in the example maintains a list of created records through the create and delete operations. It's only tracking primary keys, so there's no update operation in the example, but it's a simple matter to extend it laterally.
If you send me a list of a few (few) field attributes for one entity, I'll be happy to crank out an adaptation that might be more immediately cognitively accessible. You'd be able to compile it in the web compiler and play around to see what the operations are doing.