I think for the sizes of things you’re talking about it’s going to be hard to “get it wrong”. ~100 records, candidate keys of ~100 characters… none of this is big in a way that you’re going to impact your run time performance such that you’d worry about it.
When I do this, I have a preference for typed data in the storage of the configuration values, but I’ve seen simple configurations handled as text in the database to keep the table simple and then cast in the application as needed… again not my style, but I’ve certainly seen it in practice more than once.
Here’s some abbreviated code from something similar I do in my current application:
CREATE TABLE ms_syst_data.syst_settings
(
id
uuid
NOT NULL DEFAULT uuid_generate_v4( )
CONSTRAINT syst_settings_pk PRIMARY KEY
,internal_name
text
NOT NULL
CONSTRAINT syst_settings_internal_name_udx UNIQUE
,display_name
text
NOT NULL
CONSTRAINT syst_settings_display_name_udx UNIQUE
,description
text
NOT NULL
,setting_flag
boolean
,setting_integer
bigint
,setting_decimal
numeric
,setting_interval
interval
,setting_date
date
,setting_timestamp
timestamptz
,setting_json
jsonb
,setting_text
text
,setting_blob
bytea
);
COMMENT ON
TABLE ms_syst_data.syst_settings IS
$DOC$Configuration data which establishes application behaviors, defaults, and
provides a reference center to interested application functionality.$DOC$;
COMMENT ON
COLUMN ms_syst_data.syst_settings.id IS
$DOC$The record's primary key. The definitive identifier of the record in the
system.$DOC$;
COMMENT ON
COLUMN ms_syst_data.syst_settings.internal_name IS
$DOC$A candidate key useful for programmatic references to individual records.$DOC$;
COMMENT ON
COLUMN ms_syst_data.syst_settings.display_name IS
$DOC$A friendly name and candidate key for the record suitable for use in user
interfaces.$DOC$;
In this example, I’m completely ignoring certain costs related to the extra indexing and having so many typed fields (the actual table has more than I show here). But I feel I can get away with not worrying about that because, like in your scenario, I’m unlikely to have more than 1000 records in the table, update rates will be low, and again, I’d rather have more strongly expressed data in the database even though I could be much more space and probably time efficient by not typing the actual configuration data: at this size I just won’t worry about it until I have reason to start to compromise for performance.
The short of it is, I don’t see a real problem with your handling ideas and I’d shoot for some good combination of simplicity and clarity without the burden of worrying about performance related issues at this point.