As a CS student, I've learned a decent number of programming languages over the years, most of which have had some concept of a "nullable" or "optional" type. Note that I'm not talking about null pointers or references, or weakly-typed languages like JavaScript where anything can be null
. Examples of what I'm talking about include boost::optional
(C++), java.util.Optional
(Java 8.0), prelude.Maybe
(Haskell), and all of the '?' types (e.g. int?
, float?
, C# and Kotlin). These are constructs that add nullability to a previously non-nullable type within a strict, static type system.
SQL has a similar concept: a type such as INTEGER
can be made nullable or non-nullable--but there's a twist. In SQL, INTEGER
is nullable by default, and must be explicitly written as INTEGER NOT NULL
in order to be non-nullable.
It strikes me as extremely counter-intuitive and potentially dangerous for allowing NULL's to be the default behavior. Obviously SQL's been around for so long at this point that (most) SQL developers have developed a healthy awareness of the pitfalls of NULL. But I can't help but imagine that in the early days NULL's often crept up in unexpected and problematic places.
SQL does predate all the examples I've provided, so it's possible that this is simply a matter for historical evolution. Still, I have to ask, is there any good reason for the language to be designed this way, with types being nullable by default?
If so, is it just a historical reason, or does the logic hold up for database design today?
Edit: I am not asking why NULL is a part of SQL or why nullable columns are useful. I am just asking why column are nullable by default. For example, why do we write:
column1 FLOAT,
column2 FLOAT NOT NULL
Rather than:
column1 FLOAT NULLABLE,
column2 FLOAT