You can use the user.data and registration.data fields to store arbitrary key value data.

If the metadata is associated with the user, use user.data. If it is associated with the user's account for a given application, use registration.data.

Note that this field is read/write via the API, but only readable via the administrative UI.

Here are some notes about the limits of these fields: https://fusionauth.io/community/forum/topic/89/how-large-can-the-data-field-be-for-any-of-the-fusionauth-resources

And for the latter option, should I use a webhook for registration events

If you want a separate database, that's the way to do it. Listen for a webhook and create the records then.

Whether you should use the data fields or a separate database depends on what you are trying to do. The data fields are simpler and more tightly tied to the user records. You can also query them, but you'll be writing elasticsearch queries.

If you'd rather write straight SQL or will be storing lots and lots of data about a user (for example, their entire login history for analytics), then a separate database might work better. Of course, that's another system to maintain, so more complexity is the tradeoff.