diff --git a/postgres-stub/README.org b/postgres-stub/README.org
index 88e8fd4..37cc56d 100644
--- a/postgres-stub/README.org
+++ b/postgres-stub/README.org
@@ -44,3 +44,20 @@ myservice:
 #+end_src
 
 
+** database name and user automatic assignation
+
+It can be useful, if you have several services in the same ~compose.yml~
+to assign database names and user automatically to avoid repeating them.
+
+#+begin_src yaml
+my-postgres-stub:
+  charm: postgres-stub
+  options:
+    host: my-host.mydomain.fr:20432
+    service-dbname-map:
+      service1: u_foo
+      ## Leveraging regex replacement for all other services
+      .*: xyz_$0
+    service-user-map:
+      .*: u_$0
+#+end_src
diff --git a/postgres-stub/hooks/postgres_database-relation-joined b/postgres-stub/hooks/postgres_database-relation-joined
index dbbb96e..04ae610 100755
--- a/postgres-stub/hooks/postgres_database-relation-joined
+++ b/postgres-stub/hooks/postgres_database-relation-joined
@@ -7,14 +7,19 @@
 ##  - the target of the link is launched first, and get a chance to ``relation-set``
 ##  - both side of the scripts get to use ``relation-get``.
 
+. lib/common
+
+set -e
 
 DBNAME=$(relation-get dbname) || {
-    DBNAME="$BASE_SERVICE_NAME"
+    DBNAME=$(service:map:get_one "dbname") || exit 1
+    DBNAME="${DBNAME:-$BASE_SERVICE_NAME}"
     relation-set dbname "$DBNAME"
 }
 
 USER=$(relation-get user) || {
-    USER="$BASE_SERVICE_NAME"
+    USER=$(service:map:get_one "user") || exit 1
+    USER="${USER:-$BASE_SERVICE_NAME}"
     relation-set user "$USER"
 }
 
@@ -41,8 +46,6 @@ PORT=${PORT:-5432}
 relation-set host "$HOST"
 relation-set port "$PORT"
 
-. lib/common
-
 set -e
 
 if ! PASSWORD="$(relation-get password 2>/dev/null)"; then
diff --git a/postgres-stub/lib/common b/postgres-stub/lib/common
index 73c2af2..93af1ee 100644
--- a/postgres-stub/lib/common
+++ b/postgres-stub/lib/common
@@ -3,6 +3,92 @@
 POSTGRES_IMAGE=docker.0k.io/postgres:12.15.0-myc
 
 
+## Mappings
+
+replace_by_rematch_pattern() {
+    local input="$1" output="" char next_char i
+    # Loop through each character in the string
+    for (( i=0; i<${#input}; i++ )); do
+        char="${input:$i:1}"
+
+        # If a dollar sign is found
+        if [[ "$char" == '$' ]]; then
+            next_char="${input:$((i+1)):1}"
+            # Check if next character is a digit
+            if [[ "$next_char" =~ [0-9] ]]; then
+                # Replace $N with ${rematch[N]}
+                output+='${rematch['"$next_char"']}'
+                ((i++)) # Skip next character as it's already processed
+                continue
+            fi
+        fi
+
+        output+="$char"
+    done
+
+    echo "$output"
+}
+export -f replace_by_rematch_pattern
+
+
+service:map:get_one() {
+    local map_label="$1"
+    res=()
+    if service_map=$(options-get "service-${map_label}-map" 2>/dev/null) &&
+            [ -n "$service_map" ]; then
+        while read-0 regex map; do
+            if [[ "$BASE_SERVICE_NAME" =~ ^$regex$ ]]; then
+                rematch=("${BASH_REMATCH[@]}")
+                maps=()
+                type=$(e "$map" | shyaml -q get-type 2>/dev/null) || true
+                value=$(e "$map" | shyaml -q get-value -y 2>/dev/null) || true
+                case "$type" in
+                    sequence)
+                        while read-0 m; do
+                            if [[ "$m" != "None" ]] && [ -n "$m" ]; then
+                                maps+=("$m")
+                            fi
+                        done < <(e "$value" | shyaml get-values-0)
+                        ;;
+                    str)
+                        if ! m=$(e "$value" | shyaml get-value 2>/dev/null); then
+                            err "Failed to get mapping value from config."
+                            return 1
+                        fi
+                        [ -z "$m" ] && continue
+                        maps+=("$m")
+                        ;;
+                    NoneType|"")
+                        :
+                        ;;
+                esac
+                for map in "${maps[@]}"; do 
+                    if ! [[ "$map" =~ ^([a-zA-Z0-9_*\{\}\ \,.-]|\$[0-9])+$ ]]; then
+                        err "Invalid mapping value '$map' in ${WHITE}service-${map_label}-map$NORMAL option."
+                        return 1
+                    fi
+
+                    map="${map//\*/\\*}"  ## protect star from eval
+                    map=$(replace_by_rematch_pattern "$map")
+
+                    res+=($(set -- "${BASH_REMATCH[@]}"; eval echo "${map//\*/\\*}"))
+                done
+                break
+            fi
+        done < <(e "$service_map" | yq e -0 'to_entries | .[] | [.key, .value] |.[]')
+    fi
+    if [ "${#res[@]}" -gt 1 ]; then
+        err "Multiple databases found for service '$BASE_SERVICE_NAME': ${dbnames[*]}." \
+            "Please specify a single database in the service-${map_label}-map option."
+        return 1
+    fi
+    echo "${res[0]}"
+}
+
+##
+## DB
+##
+
 ddb () {
     docker run --rm -i \
            -e PGPASSWORD="$PASSWORD" \