Store custom messages displayed by \Drupal::messenger()->addMessage() in the database
The first thing to determine is whether you need your messages to be content or configuration. Content is (usually not) migrated between environments. It is created on an environment, and is unique to that environment. So your development environment may have one set of messages used for testing, and your production environment has another set of messages, used live.

Configuration on the other hand is migrated between environments. So you would create the messages on one environment, and when configuration is exported from that environment, the existing messages would be included in that export.

You probably want content entities.

How to create a new content entity type: https://www.drupal.org/docs/8/api/entity-api/creating-a-content-entity-type-in-drupal-8

How to create a new configuration entity type: https://www.drupal.org/docs/8/api/configuration-api/creating-a-configuration-entity-type-in-drupal-8

If you create a new content entity type, give the entity two fields, message_key and message_value. You will then load the entity as follows:

$entity = \Drupal::entityTypeManager()-&gt;getStorage('my_entity_type_id')-&gt;loadByProperties([
  'message_key' =&gt; $message_key,
]);

$message_value = NULL;
if ($entity) {
  $message_value = $entity-&gt;get('message_value')-&gt;value;
}


If you create a configuration entity, the ID of the entity will be the message key, and the entity only needs one more field for message value. The code above would be adjusted slightly:

$entity = \Drupal::entityTypeManager()-&gt;getStorage('my_entity_type_id')-&gt;loadByProperties([
  'id' =&gt; $message_key,
]);

$message_value = NULL;
if ($entity) {
  $message_value = $entity-&gt;get('message_value')-&gt;value;
}


The entity type you choose will become the storage mechanism for your messages, which you can then recover with the above methodology. Don't run $message_value through the t() function, as variables should not be run through that function, and translations of the message values are handled as translations of the entity, rather than the t() function.