On the Importance of Mental Models

Occasionally I'll get curious about how some feature of Oracle, or of some other software product, really works internally. When this happens, and I begin to ask questions about physical implementation, I'm often told that I shouldn't worry about the implementation details. I should simply be satisfied that the feature exists and that it works. But I disagree with that often patronizing advice! Sometimes it's important to understand what goes on "behind the scenes", because that understanding is important to the formation of a correct mental model.

What is a mental model?

mental model is a set of beliefs that you hold about how a piece of software, or a software feature, works. Part of my mental model for SQL statements, for example, says that executing SQL statements results in disk I/O. Another part of that mental model says that trips across the network are "expensive" in terms of time, and that given a choice it's consequently better to execute one SQL statement rather two. Without these understandings, without my mental model of how SQL works, I'd be likely to write some very inefficient programs indeed.

Where can a bad model lead?

I remember well many of my experiences when first becoming acquainted with Oracle. One of the first things my employer did was to send me to a five-day introductory course on SQL, PL/SQL, and SQL*Plus. Good as the course was, it failed to leave me with the correct mental model of what these three things were and how they played together. Figure 1 shows the model in my head at the end of that course.


Figure 1. My incorrect mental model

Figure 1. My incorrect mental model

If you have any experience at all with SQL, PL/SQL, and SQL*Plus, you'll immediately see how wrong Figure 1 is. But wrong as it is, that was my mental model of these three features after taking that first Oracle course. As a result, I went back to work and attempted to write PL/SQL code such as the following:

   user_response VARCHAR2(1);

   ACCEPT user_response CHAR PROMPT '1=Detail Report, 2=Summary Report: '
   IF user_response = '1' THEN

and when the above didn't work, I tried the following from SQL*Plus:

ACCEPT user_response CHAR PROMPT '1=Detail Report, 2=Summary Report: '
IF user_response = '1' THEN
   SELECT for detail report
   SELECT for summary report

But this second approach didn't work either! The first piece of code above won't work because ACCEPT is a SQL*Plus command, not a PL/SQL statement. The second piece of code won't work because IF is a PL/SQL statement, and not a SQL*Plus command. I know that now, but at the time I was frustrated, angry, not meeting my deadlines, and wishing I was back working with DEC/Rdb, because DEC/Rdb at least worked the way I expected it to.

Eventually, over a period of time, I came to realize that my problems writing SQL*Plus scripts were not the result of any design flaw on Oracle's part, but rather were the result of my flawed mental model. After realigning my mental model to that shown in Figure 2, things began to click into place. I not only got the scripts written that I needed done for my project, but I eventually learned enough to write an entire book on SQL*Plus (Oracle SQL*Plus: The Definitive Guide).


Figure 2. My new, and correct, mental model

Figure 2. My new, and correct, mental model

Clearly, having the correct mental model of SQL, PL/SQL, and SQL*Plus was (and still is) key to my success in using all three of those features. I have no doubt about that, and neither should you. Holding a correct mental model is important. But how does one develop such a model to begin with?

How do we develop a mental model?

I won't pretend to say that there's only one way to develop a good model of how things work, but my observation is that when learning new material we humans often need to work from the specific to the general. Take kids and money for instance. I have a six-year old boy, who is just learning about money, what it is, how it works, and why he should care. When it came time to teach Jeff—that's his name, Jeff—about money, do you think I handed him a checkbook and tried to explain that the digits represented money, and that money is simply an arbitrary concept that we use to keep track of how much we humans owe each other for various units of work? Wow! That's a lot for me to absorb, let alone someone who's never been exposed to money before.

Instead of trying explaining the concept of money to Jeff and telling him to ignore the underlying physical implementation, I began with the physical implementation. I gave him some paper dollars, took him to the store, and showed him how to exchange his paper for a toy. Now that got his attention, and it's something he could understand. After a few years, he'll get comfortable with the physical details of handling money, and he'll be ready to understand the concept of putting money in the bank and keeping track of it in a checkbook. And sometime after that he'll be ready to make the next leap, and understand that money has no inherent value, but is simply a way to "keep track" of the relative value of goods we buy and work we do. Who knows, perhaps there's yet another level of understanding that even you and I aren't ready for yet.

What does this mean for technologists?

Bringing this discussion back to the technical arena, I submit that a correct mental model is important for the work that we do as programmers and database administrators. I further submit that in many cases the path to that correct mental model lies in an understanding of implementation specifics.

Recently, this issue of mental models came up when a reader asked me a question about PL/SQL cursor handling. See Does PL/SQL Implicitly Close Cursors? and the follow-up article More on PL/SQL's Cursor Handling. The issues I discuss in those articles are directly related to the mental model one holds of what a cursor is in the context of PL/SQL. An incorrect model leads to confusion over why PL/SQL behaves the way that it does, while a correct model promotes understanding and peace of mind. The key to the correct model in this case lies in having some understanding of the specifics of cursors as implemented in PL/SQL.

Don't be afraid to pursue understanding in what you do. Dig into the underlying implementation details if that's what it takes for you to reach the level of understanding that you need. Ignore those who patronize you by telling you not to do that digging. Implementation details are not always important, but often they are crucial to developing the correct mental model that you need in order to be successful at what you do.