A few times now, I’ve been wanting to write this down. I know: a lot of people will go *shrug*. Others may find me pedantic. Some of will say I’m being a smart-ass. Whatever…but I just got to write down a few of these common misconceptions that keep floating around.
None of these misconceptions are really harmful - in most cases, they do not lead to misunderstanding or miscommunication. However, when you are writing about these subjects, you’ll often find that a sloppy definition you used in some place will bite you in the tail, and make it harder to explain something later on. So, that is why I from time to time get kind of obsessed with finding just the right words.
I’m not pretending I have the right words though. But there are a few informal ways of saying things that at a glance look right but are in fact wrong. Here’s a random list of some of them:
UNIQUEconstraints are unique indexes
Wrong - an index is just a convenient implementation to detect duplicate entries, and this is used by all RDBMS-es I am familiar with to implement
UNIQUEconstraints. However, the fact that there is a distinction is evident in for example the Oracle SQL syntax. For example, in
ALTER TABLE ... DROP CONSTRAINTyou can specify whether the associated index should be kept or also discarded.
Some people argue that it does not make sense to make the distinction in case the RDBMS does not maintain the constraint and index as separate objects. (This is the case in for example MySQL.)
Well, maybe…but I disagree. When I think about constraints, I’m thinking about business rules and guarding them to maintain database integrity. When talking about indexes, I’m thinking about performance and access paths. Quite different things, and in my opinion a shame to throw away the words to express the difference in my opinion.
- A table consists of rows and columns
No - there is nothing wrong with an empty table. In other words, it does not consist of rows. It may or may not contain rows, but that is a different story.
- A scalar subquery returns one column and one row
Wrong - first of all, a scalar subquery may return zero rows, in which case it evaluates to null, which is perfectly valid. But there is more to it.
Whether something is or is not a subquery is matter of syntaxis. The SQL grammer is defined so that if you encounter a query between parenthesis where a scalar value is appropriate, then that query (including the parentheses) will be parsed as a scalar subquery. In other words, the text satisfies the production rule for the non-terminal symbol “scalar subquery”.
The parser will usually be smart enough to verify whether the subquery yields one column, but the number of rows returned is a runtime affair.
Suppose the query that makes up the scalar subquery would in fact return more than one row…would it suddenly not be a scalar subquery anymore? Of course not. It is still a scalar subquery - it just happens to be impossible to execute it. In other words, it violates the semantics of a scalar subquery and is therefore invalid. But the mere fact that we can conlcude that must imply that it is a scalar subquery.
- A subquery is a
SELECTstatement that appears as a part of another
Wrong - For the same reasons as the previous issue. A statement is a syntactical construct. It has to do with discovering a pattern in a piece of text so that it satisfies a particular rule in the SQL grammer. That grammar does not have a rule that allows statements to be nested - not in pure SQL anyway (Of course, in stored procedures, one can have statement blocks like
IF...END IFetc that really can contain other statements)
Of course, if we would take the
SELECTthat makes up the subquery and run it in isolation, it would be a
SELECT-statement. Bit that is exactly the heart of the matter: because we are regarging it as part of another statement, it cannnot be a statement itself. This is simply a matter of definition of course - most people will immediately understand what is meant.
What would be better to say though is that a subquery is a query or query expression that appears as part of another SQL statement. However, this is also not correct:
CREATE VIEWfor example does contain a query expression, but this would most likely not be called a subquery. For this particular case, you can argue that there is nothing sub-ish about the query expression, because it is simply an essential part of the
But what to think of
CREATE TABLE...AS SELECT...and
INSERT INTO...SELECT? The query expression is certainly not an essential part of
INSERT INTO, and in that sense, the query does look like it is subordinate to the statement it is part of.
You could argue that a query is a subquery if it appears inside another query. That seems sound, but what to think of
UPDATE ... SET = (SELECT ...)? Personally I am reluctant to call an
UPDATEstatement a query - I tend to think of a query as a
SELECTstatement or sometimes a
I can think of only one thing that really is a defining characteristic of a subquery though - that is that the query expression must appear within parentheses. So, again, a matter of syntax more than a matter of semantics. I must admit I’m still not very satisfied with this though…What do you think?
NULLis the absence of a value
Variants of this statement go like “
NULLis a missing value” or “
NULLis not a value”.
With slight doubt, I say: wrong. It certainly is true that many people use
NULLto convey that something is not there or that something is not applicable. But this is a matter of choice, it does not change the meaning of
NULLitself. If we use the same line of reasoning as we used for the subquery myth, we must conclude that
NULLis certainly a valid value expression. It can legally appear anywhere where we can put a value. It is IMO also perfectly ok to say things like “…that expression evaluates to
So what does the SQL standard say? Well, here’s a quote:
…the null value is neither equal to any other value nor not equal to any other value — it is unknown
whether or not it is equal to any given value….
So, I’m in that camp too:
NULLis a value, and if we have a
NULLin say, the integer domain, we just don’t know which of all possible integers it is.
- Foreign keys must reference a primary key
Wrong - a Unique constraint is mostly just as acceptable.
In MySQLs InnoDB it is even more relaxed - the foreign key only needs to reference the prefix of an index in the parent table, although this is so exotic, it should probably be ignored.
- This table is not normalized - it still contains redundancy
Wrong - a table is normalized when it is in the first Normal form. There are a few different opinions what that means exactly, but it usually works to say that a table is not normalized when it contains repeating groups.
A slightly stronger statement is to say that a table is not normalized when it contains data that is not atomic. This is stronger because it does not cover only repeating groups, but also columns that, for a single row, do not contain a single value. For example, a first name/last name combination in one column is not atomic, and therefore, a table that contains such values is not normalized. (There are opinions that require even more than this, but for practical purposes the sense of atomic values works pretty well.)
The source of confusion is in what happens beyond the first normal form. Although a table maybe normalized, it can still contain redundancy. By removing redundancy, you can progressively achieve a higher normal form. In many cases, one would require at least third normal form or the Boyce-Codd normal form for building database schemas. Many people say “normalized” when they actually mean “in at least the third normal form”.
So - what do you think? Pedantic? Have other myths? Maybe you have a good, satisfactory definition for subqueries? Or maybe you find an error in my debunkings?
Just drop me a comment on this post - thanks in advance.