First glaring issue: ssh root@
Don't do that. Don't ssh as root. Ever. SSH as root is bad practice, is worse than
sudo su -. If your password or key is compromised somehow, the entire DB server is gone. Privilege separation, tight permissions, full disk encryption... all useless.
If someone gets a shell on the application server, he can connect to the database service (service, not server) without needing the SSH keys. Why? It's a TCP tunnel! They can connect straight to the database using the local port. They don't even need to find you are running a tunnel, just looking at the open ports with
netstat is enough. Or looking at your config files. And what else will be at the config files? The database credentials.
If you SSH keys aren't password-protected, they can access the entire server, as root. They already had the database credentials, now hey have root access too.
I would use Wireguard or another VPN service to tunnel requests, and configure the firewall on the database server to only allow connections from the VPN to the database port.
And I would change SSH default port 22 to something else, and put a honeypot on port 22, something like SSH-Pot: An ssh server that never authenticates. That makes random scan bots to miss your server.
And as Mark said, hardening and least privilege. Disable as much as you can. If you don't need email, disable email. Disable every and any service you can, until the service stops working. Configure the firewall on the database server to not allow any incoming connection, except the VPN service itself and the DB port inside the VPN, and not allow outgoing connections. Do the same on the application server: allow ports 22, 80, 443, and the new ssh port (you changed it, right?), and don't allow outgoing connections except the VPN service on the DB server, and the DB service.