In the game I'm making, which is not pure ECS, but something between it and common design (object oriented), I have two main types of components: 'standard' and 'extended'.
Standard are for example position, speed, health... which are common to almost all the entities and so are stored in simple arrays: there will be few gaps and can easily be iterated. Components of the same entity share the same index in the arrays and so is easy to retrieve them and create interactions.
Extended components are instead stored in arrays at the first slot available: there will be few "teleport_on_collision" entities and I can't afford to have one component at 1° slot, one at 10° and one at 23°, it would be a pain for the cache, while iterating them. So they are stored in the first free slots and each owner entity keeps in a vector (actually a linked list allocated into an array shared between all the entities) the list of extend components it has (pairs of 'type', 'slot'). Lookup is slightly slower because you have to search in this array if a component exists and in that case, get its index, its type and then get it. I'm implementing a message system to communicate between standard and extended components to avoid dependences: extended components are generally implemented after basics one which, so, can't know they existence and implementation: you just propagate messages such as "on_hit" to them and they will react on their own.
I decided to use this approach because, generally, you don't fire many messages each frame, but usually you need to update each component each frame, so linear lookup into a continuous array is what you have to aim for.
I hope I've been clear, English is not my main languages.
I'm just testing this approach and I'm not sure it's the best way, but I think this text is too long to be a simple comment. (I would like to have comments and criticisms)