Being able to partial index into JSON has made this much more straight forwards now than ever before, but historically pre-creating empty indexed custom columns was somewhat common (leading to hard limits like max 20 custom tags), as was EAV (which arguably is inner-platform).
There are more solutions than these, but until you're at truly custom DB scale with a specific problem here, these will solve it for you.