OK imagine a "standard" web application. Some web server, some language like PHP, Ruby, whatever, some database Postgres, SQL server, MySQL, whatever.
How would you architect this to protect the database?
Would you have the database on a separate server?
Would you allow direct connections to the database from your web application code?
How would you defend your database in case hackers crack the web application server?
I know that isn't the answer you wanted, but it's the truth, so: don't lose your web server.
In certain regulated industries you'll be encouraged to do some theatre like separating the database from the server on a different network, putting a firewall between them, yadda yadda. Which is all great, but the web server has to be able to talk to the database in some fashion, and that's game over if the web server can say the right things. If you assume the ability of the attacker to coerce the web server into saying any of the range of things the web server is authorized to say, that's usually "pretty bad news" with regards to what you have in your DB.
Concrete example: suppose I have the web server connect to the DB with a relatively limited privileged user, which is one thing you should certainly do. That user only gets access to the proper database on the DB server (which after all might have many of them), which prevents e.g. someone from hopping from a WordPress compromise directly into the main application database... sorta. You'll probably also want to limit the actions the webserver can take to avoid e.g. creating users or changing schemas.
That still leaves the web server able to do CRUD operations, which is easily enough to do a lot of damage to your business and yourself. Rails can trivially execute "select * from patients;" That single line, or one isomorphic to it, is a catastrophe if you're in healthcare.
(Yeah yeah row-level ACLs, I know, I know. Aside from "Not widely supported in actual web application stacks" they're probably not sufficiently robust in the face of a server compromise because the server should be able to authenticate as every user somehow and at that point you're just a for-loop away from total compromise.)