Know SQL well, so you can know how revert any problem you have.<p>Other commenters say a lot about PREVENTING an issue. That is good, but you can get stuck in a situation that (very common, saddly) you are under a pile of "stuff" that hide a simple fact:<p>You CAN ruin and revert nearly everything* in a RDBMs and still get on top.<p>* as long you are inside SQL/transactions and not messing with the binary data<p>---<p>The point here is that you can model the database in ways you get stuck with limited options, or instead make it easier to get of trouble.<p>The good thing is that is mostly apply good design practiques and is not that problematic.<p>The key is that data in RDBMs IS values (aka:inmmutables (rows, tables) on top of a mutable facade (INSERT, DELETES), so you can always take snapshot of data and apply reversible operations.<p>This is what most do with "copy to sql, csv, do a backup, etc" but is in fact more in-built than that. You can, totally, side-step extra operational complexity if you know this fact (and the change is kinda small. I don't say don't make copies or backup, instead, that SQL is VERY friendly to mess with it!)<p>The major issues is when you turn your powerfull RDBMS in a pathetic datastore, with a lot of MongoDb-style data/schemas, anti-patterns everywhere and close-to-zero understanding of (advanced)sql like usage of views, indexes, triggers, TEMP tables (note this!), administrative commands, write your own functions, know what tools the db gives for free, etc.<p>It sound like a lot, but even a "complex" RDBMs like postgres requiere far less study than learn JS. Is just a matter of understand that RDBMs are not "dumb" datastores.<p>---<p>I forgot to make this actionable. Most RDBMs have a comparable way to do this:<p><pre><code> CREATE TEMP TABLE _address ON COMMIT DROP AS
SELECT customer_code, address_code, is_default FROM address;
</code></pre>
Do the changes there. Your temp tables are "FREE" to get ruined.<p>Then apply back with a update/insert from tables:<p><pre><code> UPDATE address
SET ...
FROM _address
WHERE address.address_code = address.address_code;
</code></pre>
You can ALSO copy to another schema (PG) or db (sqlite) and do the mess there:<p><pre><code> CREATE SCHEMA fix;
CREATE TEMP TABLE fix.name AS
SELECT ;
--or
CREATE DATABASE fix WITH TEMPLATE old;
</code></pre>
And this mean you can also "rename" the old db/schema, do a copy of it, then see if the copy was ok, if not, drop the schema and rename again.<p>This is how I done some of the most nerve-cracking fixes!