Split brain your password storage.
Another table, another database or another storage system in general.
If an attacker SQL injections your database don’t go spilling every hashed or unhashed password you’ve got.
I tend to store passwords in a separate keyvalue store from where my authentication identifier is (email, “username”).
If someone gets into my network they need to get into my servers with the email addresses and then get into a secondary system where the passwords are stored.
I like my password systems to be a k/v store because there is no need to “query” it. I usually store the password under a key that isnt the identifier. Instead using something like a database surrogate key.
Have a secondary system (microservice, private subnet) that simply returns a boolean representing if the provided non-email (key) and password (value) match.
Have that secondary system take the plain text password so it can do the hashing without letting the dependent service know what algorithm, salt or stretches you’re doing. This will also allow you to easily roll over to new hashing algorithms over time without affecting the service that is doing th authenticating.
Edit: I’m not trying to be a know it all or a crabby old tinfoil hat a-hole. But it’s passwords, man. When you leak them you ruin people’s days/year/life. Building that system above takes a middle of the road engineer a day or two. Put the effort in. Every password leak makes all of our jobs harder. It’s your companies responsibility to keep that safe. If you know that already, be the annoying guy that brings it up in every stand up. Make that debt known.