There are a multitude of solutions that each have their associated cost in performance, maintainability and complexity.
This is my favorite solution for entities which consist of multiple sprites, like tanks with their turret. I use this in a 2.5D isometric RTS for the aforementioned use case.
You create an entity per sub-sprite and parent them to your main entity which holds the absolute position from which the sub-entities are offset. The "Parent-System" solves the absolute positions and rotations of the child sprites in a bottom (first child) to top (last child of child of ...) order.
Pros:
- Rendering-System remains untouched.
- Sub-Sprites can have individual modifications (shaders, particle-spawner, etc) to their behavior.
- In line with ECS philosophy and design, which may give you some peace of mind.
- Simplified/Unified rendering process is easier to optimize.
- Parenting overhead is small since it only applies to visible entities.
Cons:
- The overhead because of increased entity count may actually be significant if you abuse this solution, since having more entities always cause more overhead when managing entities.
- The Parenting-System (position solving) needs to execute before the Rending-System and after any system that changes the parents position. This may create a conflict but is unlikely to actually affect you, since it's the natural order anyway.
- You need to handle deleting stuff very competently, otherwise some entities might be left dangling around or worse
You might see how you can apply this to other problems as well, but it's not the only solution.
It's equally valid to create a special multi-data component if it saves you lot's of overhead and/or makes the whole thing cleaner overall. For example: You probably shouldn't create an entity per particle unless each particle needs some kind of special behavior and even then it's debatable. Having a component that holds an array of particle-data will have less overhead and fits the concept of particles always being in a group. You also probably want an rendering system that does only particle rendering (or treat particles differently), so it's not that bad to not reuse the sprite component.
A third solution would be to actually have ECS-level support for components being present more than once per entity, this has serious performance and design implications though and shouldn't be taken lightly. What if your sprite component needs an offset or a special shader? How do you associate multiple offset components to the multiple sprite components, with their order of creation? Do you group this data then? Is this better than having a component which stores multiple sprites in the first place?