Back in 2008, in an old oraclenerd post called Why I Blog, I wrote that I didn't really have a physical mentor early in my career.
Two years later, in How To: Become a Professional Developer, I gave proper credit to my first boss, Tom Wurzbach. It took me a couple of years after leaving that first job in 2002 to realize just how much of a gift he had given me, and it is a foundation I am still grateful for every day.
Sometimes you internalize a lesson so deeply that you forget where the seed was planted. In September 2008, I wrote a post called Design: The Entity = The Party about arriving at the Party (supertype/subtype) model while working through a design problem, and wondered out loud: "I do have to wonder though if I took it in at some point of time but don't explicitly recall it."
Two days later, Tom Wurzbach popped up in the comments:
"Um... We discussed an approach similar to this at LifeSouth while you were employed here. The party table provided a common point for attaching addresses, phone numbers and other things common to a party/entity and supplemental tables held class specific data... Parties and other archetypes are quite useful during schema modeling, but like everything else, during implementation it should be tested before the decision to keep the class/subclass model or flatten it is made."
I replied twenty minutes later: "Mr. Wurzbach how nice to see you finally. :) I don't recall anything specific but that doesn't mean it didn't happen. Much of what I now know was based on what I learned with you."
Tom did me three huge favors at that first job:
- He demanded good questions. You could ask him anything, but it became apparent very quickly that you had better have done your homework first.
- He made me write SQLUnit tests for a solid year. I hated every single minute of it at the time. Years later, I realized all that teardown, setup, and edge-case testing was the reason I actually understood how the database behaved when things went wrong.
- He introduced me to the other Tom. When Tom Wurzbach offered me the job in January 2002, he sent me a link to AskTom. Because my new boss's name was Tom, I initially thought the URL was a joke. Then one day he caught me reading a non-work opinion site on company time and sent me a one-line email: "What are you doing?" Point taken. From that day on, whenever I needed a break at work, I read AskTom instead.
If you just needed to know how to do something in Oracle, you didn't actually need Tom Kyte or Tom Wurzbach. The syntax diagrams were right there in the documentation. If you wanted to know how to write a trigger, how to add a hint, or how to use EXECUTE IMMEDIATE, the manuals would gladly hand you the syntax.
What I needed most, and what both Toms forced me to learn, was the Why and the When of doing things.
Reading Tom's answers gave me a window into his mindset. He rarely just handed over a snippet of code and closed the thread. He walked you through why a feature existed, what the database engine was physically doing underneath the covers, and why the thing the asker was trying to do was probably going to hurt them six months down the road.
Looking back across two decades of writing on this blog, almost every post comes back to the same realization:
It is not the How. Anyone can figure out the How. It is the Why and the When.
Syntax Is Cheap: The Trap of the How
We spend an absurd amount of energy treating the How like the finish line.
- How do I write a recursive query?
- How do I parse a JSON blob in SQL?
- How do I dynamically alter an external table inside a loop?
Figuring out the How has never been easier. Twenty years ago, you had manuals and forums. Ten years ago, you had Stack Overflow. Today, you have AI assistants that can spit out working syntax in two seconds. AI has made the How nearly free. That makes judgment about the Why and the When more valuable, not less.
The problem is that the database compiler does not care if your idea is terrible. As long as the syntax is valid, the engine will execute the How without blinking.
I learned this the hard way plenty of times. Years ago, I was processing batch files using Oracle external tables and needed to loop through a list of file names. A colleague showed me how to dynamically change the file location using ALTER TABLE table_name LOCATION ('new_file.csv') inside a PL/SQL loop via EXECUTE IMMEDIATE.
It worked like a charm. I had conquered the How.
Then I started testing failure scenarios. And, although I didn't realize it at the time, this was Tom Wurzbach's SQLUnit lesson showing up again: the fact that the code worked wasn't the interesting test. What happened when it failed was.
I ran my procedure, simulated an error, and issued a ROLLBACK to clear the staging tables for the next run. When I checked the tables, all the data was still sitting there.
Oh, right. EXECUTE IMMEDIATE was running an ALTER TABLE statement. ALTER TABLE is DDL. And in Oracle, DDL issues an implicit COMMIT before and after it runs. My clever little loop was committing my transaction on every single iteration, completely destroying my ability to roll back on failure.
I knew how to make the code run. I had failed to think through why DDL behaves the way it does inside a transaction, and when dynamic SQL has no business being inside a transactional loop.
The Why: Following the Cost Downstream
If the How is about getting the ticket closed before 5:00 PM on Friday, the Why is about what happens to everyone else on Monday morning.
Take a simple example I have beaten to death recently: using an is_active boolean column to represent lifecycle state.
Does anyone need a tutorial on how to add a boolean column? Of course not. It is one line of DDL.
Understanding why it fails as a representation of lifecycle state requires stepping outside the current ticket and looking at the physical reality of the business over time:
- Why does a boolean fail when it is used to represent lifecycle state in an operational system? Because the moment you flip
is_activefromTRUEtoFALSE, you overwrite state without recording when the transition happened or what came before it. - Why does it fail in a warehouse? Because it duplicates a truth that already lives in your temporal boundaries (
effective_start_dateandeffective_end_date), setting a trap where the flag and the dates inevitably drift out of sync.
You don't learn the Why from a syntax reference. You learn it by watching a downstream BI developer spend three weeks trying to reconstruct a point-in-time pipeline report from a table that wiped out its own history.
The When: Where Rules of Thumb Go to Die
Even when you understand the Why, you are still only halfway there. The hardest part of the craft, the part that actually requires scar tissue, is the When.
One of the greatest lessons I picked up from Tom Kyte was his hatred of blind "Rules of Thumb." A rule of thumb is what happens when someone tries to turn a complex When into a lazy How ("Always index foreign keys," "Never use triggers," "Always normalize," "Never use JSON columns").
A real practitioner knows that almost every bad architecture is just a good pattern applied at the wrong When.
Look at how the When changes the answer on things we argue about every day:
CHECKConstraints:- The How:
CHECK (status IN ('OPEN', 'PENDING', 'CLOSED')). - The Why: Enforcing data integrity close to the disk so application bugs cannot corrupt the table.
- The When: Great when the rule is a mathematical or calendar invariant (
end_date >= start_date,discount_pct BETWEEN 0 AND 100). It becomes the wrong tool when the allowed values represent mutable business vocabulary (order_status) expected to evolve independently of the schema. Once'PENDING'is retired for new orders but kept for historical rows, the constraint must permit both, and the guardrail silently stops guarding.
- The How:
- JSON Columns:
- The How:
payload JSONB. - The Why: Explicit relational columns protect downstream consumers from writing brittle parsing queries forever.
- The When (The Waiver): It earns its place when the payload is genuinely an opaque, third-party black box (like a raw webhook audit log) that your database will never filter, join, or aggregate on.
- The How:
- Enterprise Dimensions and Supertypes:
- The How:
CREATE TABLE. - The Why: Modeling shared business nouns (
Person,Location,Customer) once so every team speaks the same language. - The When: Recognizing when an entity is a foundational primitive of the business (pouring the concrete slab on day one) versus when it is a bespoke reporting request that genuinely deserves the question, "What's your use case?"
- The How:
Showing How the Machinery Moves
Years ago, when I was working with a group of BI developers, data engineers, and data architects, I started a shared group chat called "Modeling for BI".
I didn't start that chat to teach anyone how to write a SELECT statement or how to build a chart. Every person in that room already knew the How of their own tool.
I started it so I could think out loud in front of them, and so they could see how the pieces connected across our silos. I wanted them to see the questions I asked myself before creating a table: Why does this grain matter to the report builder? When do we push this logic upstream into the pipeline instead of hiding it in a dashboard calculation? Where will this break in two years?
That is the exact gift Tom Kyte gave me when I was reading AskTom in my early years.
Syntax changes. Tools get replaced. The How is cheaper today than it has ever been in the history of computing.
Don't hoard the How. Teach the Why, argue about the When, and let people watch how you think.
It might take them a couple of years to realize the gift you gave them. It did for me.
Architected by Chet, written by Gemini 4 Argon
No comments:
Post a Comment