DEFAULT is the value that will be inserted in the absence of an explicit value in an insert / update statement. Lets assume, your DDL did not have the NOT NULL constraint:

ALTER TABLE tbl ADD COLUMN col VARCHAR(20) DEFAULT 'MyDefault'

Then you could issue these statements

-- 1. This will insert 'MyDefault' into tbl.col
INSERT INTO tbl (A, B) VALUES (NULL, NULL);

-- 2. This will insert 'MyDefault' into tbl.col
INSERT INTO tbl (A, B, col) VALUES (NULL, NULL, DEFAULT);

-- 3. This will insert 'MyDefault' into tbl.col
INSERT INTO tbl (A, B, col) DEFAULT VALUES;

-- 4. This will insert NULL into tbl.col
INSERT INTO tbl (A, B, col) VALUES (NULL, NULL, NULL);

Alternatively, you can also use DEFAULT in UPDATE statements, according to the SQL-1992 standard:

-- 5. This will update 'MyDefault' into tbl.col
UPDATE tbl SET col = DEFAULT;

-- 6. This will update NULL into tbl.col
UPDATE tbl SET col = NULL;

Note, not all databases support all of these SQL standard syntaxes. Adding the NOT NULL constraint will cause an error with statements 4, 6, while 1-3, 5 are still valid statements. So to answer your question: No, they're not redundant.

Answer from Lukas Eder on Stack Overflow
🌐
W3Schools
w3schools.com › sql › sql_notnull.asp
SQL NOT NULL Constraint
This enforces a field to always contain a value, which means that you cannot insert a new record, or update a record without adding a value to this field. By default, a column can hold NULL values.
Discussions

sql server - Why is adding a NOT NULL column with a default constraint instantaneous? - Database Administrators Stack Exchange
CREATE TABLE TestTab (ID INT IDENTITY(1,1), st nvarchar(100)) INSERT INTO TestTab (st) values ('a') INSERT INTO TestTab (st) values ('b') INSERT INTO TestTab (st) values ('c') INSERT INTO TestTab ... More on dba.stackexchange.com
🌐 dba.stackexchange.com
Behavior of NOT NULL DEFAULT
However, the column does have a default value; it’s defined like: `foo` tinyint(1) NOT NULL DEFAULT 0 When inserting, the following error is returned: NULL supplied to NOT NULL column 'foo' at row 122058 Shouldn’t it default to 0 instead of erroring out? I have also had this occur when ... More on singlestore.com
🌐 singlestore.com
0
0
May 20, 2022
sql - Why do we use default along with not null in database columns? - Stack Overflow
Isn't it extra overhead? When we mention default x (for example, alter table users add column id default 0 it is not gonna allow null at database level ) . So why use not null along with default in More on stackoverflow.com
🌐 stackoverflow.com
mysql - Field both NOT NULL and DEFAULT NULL - Database Administrators Stack Exchange
This MySQL table had me perplexed for a moment: mysql> desc quux; +---------------------------+-----------------------+------+-----+---------+----------------+ | Field | Typ... More on dba.stackexchange.com
🌐 dba.stackexchange.com
November 23, 2016
🌐
JetBrains
jetbrains.com › help › inspectopedia › SqlAddNotNullColumn.html
Adding not null column without default value | Inspectopedia Documentation
1 month ago - By default, a column holds NULL values. In the example, we use the NOT NULL constraint that enforces a column not to accept NULL values.
Top answer
1 of 1
23

Yes, adding a column with NOT NULL and a default doesn't actually write the values to all the rows at the time of the alter, so it is no longer a size-of-data operation. When you select from the table, the columns are actually materialized from sys.system_internals_partition_columns, which prevents all the values from having to be written (until they are changed). Note that this doesn't work for all data types and requires Enterprise Edition.

Remus Rusanu explains this in more detail here:

  • Online non-NULL with values column add in SQL Server 2012

Also, for an ALTER at least, we still can't show you a plan because SQL Server doesn't produce one, but to see I/O, you can use SQL Sentry Plan Explorer.* This screen shot shows adding a column, c5, "online" as described above, and then another column, c6, "offline" because LOB types are not supported. You can see the I/O is mostly expressed as reads rather than writes, but what's more telling is the (invalid!) UPDATE associated with the offline alter.

If you don't have Enterprise Edition, both statements will have the secondary UPDATE attached (and the associated reads). (And if you use the free version of Plan Explorer, which doesn't get the full query call stack, you won't see the above - you will just see an empty statement tree. A paid version is required to see the full query call stack.)

Note that SQL Server will produce an estimated plan, but it's not very useful. At all. And the estimated plan for an online alter is identical to the estimated plan for an offline alter.

*Disclaimer: I work for SQL Sentry.

🌐
SingleStore
singlestore.com › help
Behavior of NOT NULL DEFAULT - Help - SingleStore Forums
May 20, 2022 - However, the column does have a default value; it’s defined like: `foo` tinyint(1) NOT NULL DEFAULT 0 When inserting, the following error is returned: NULL supplied to NOT NULL column 'foo' at row 122058 Shouldn’t it default to 0 instead of erroring out? I have also had this occur when ...
Find elsewhere
🌐
Quora
quora.com › How-do-I-set-the-default-value-while-inserting-a-null-value-into-a-not-null-column-SQL-server
How to set the default value while inserting a null value into a not null column SQL server - Quora
Answer (1 of 4): You cannot assign a NULL values to a column that has been specified NOT NULL. You can set a default value on a column either when you create the table or if you modify the table.
🌐
jOOQ
blog.jooq.org › have-you-ever-wondered-about-the-difference-between-not-null-and-default
Have You Ever Wondered About the Difference Between NOT NULL and DEFAULT? – Java, SQL and jOOQ.
November 11, 2014 - Yes, you should still specify that NOT NULL constraint. And no, the two constraints are not redundant. The answer I gave here on Stack Overflow wraps it up by example, which I’m going to repeat here on our blog: DEFAULT is the value that will be inserted in the absence of an explicit value in an insert / update statement.
🌐
GitHub
github.com › Sequel-Ace › Sequel-Ace › issues › 1419
VARCHAR/CHAR.. column NOT NULLABLE but DEFAULT NULL may should show Default NULL(not blank) in table structure view · Issue #1419 · Sequel-Ace/Sequel-Ace
March 14, 2022 - DEFAULT INSERT can be used in dynamic SQL(if column null use DEFAULT). INSERT NULL name cause ERROR, but INSERT "" type success silently(cause dirty data). No "string not empty" constraints before MYSQL 8.0.16, I use "DEFAULT NULL NOT NULL" to prevent forget to set the required column.
Author   mrrao
🌐
IBM
ibm.com › docs › en › informix-servers › 14.10.0
DEFAULT clause of CREATE TABLE - Informix
Use the DEFAULT clause in the CREATE TABLE statement to specify the default value for the database server to insert into a column when no explicit value for the column is specified.
Top answer
1 of 7
38

NULLs have special behavior: comparing anything with a NULL gives you back a NULL, which is something else than false or 0. It means "unknown".

For example, take this table:

 user_id | gender
------------------
 1       | NULL
 2       | 'M'
 3       | 'F'
 4       | 'F'

SELECT * FROM mytable WHERE gender = 'M' will return 1 row, as expected

SELECT * FROM mytable WHERE gender != 'M' will return 2 rows, NOT 3 rows.

SELECT * FROM mytable WHERE gender != 'M' OR gender IS NULL will return the expected 3 rows.


Edit: For some applications, using 0 (or, God forbid, another "magic number") instead of NULL is not even advisable (units or exact values are not relevant in this example):

 Date       | Temperature 
--------------------------
 2010-01-01 | 10          
 2010-01-02 | 4
 2010-01-03 | 0
 2010-01-04 | -22
 2010-01-05 | -45
 2010-01-06 | NULL
 2010-01-07 | -34

Here, the NULL on Jan 6th means "value unknown" - maybe because the temperature was so low that the thermometer probe stopped responding. However, it's a completely different meaning than Jan 3rd, when the temperature was 0, that is, 0 degrees.

Also, as @Bill Karwin mentions, NULLs behave specially in aggregate functions (COUNT,SUM,AVG etc.): calculating AVG(Temperature) on the above data would give you -14.5, as the NULL row is ignored.

2 of 7
11

null and "" are not the same thing, so there is no contradiction here.

What the semantic meaning of null/"" is depends on the individual and is often a "religious" issue. To some people in some schemas, of course, they may be the same, but they don't have to be. For example, a "" might mean "I explicitly asked the user for input, and they chose to enter nothing" while a null might mean "I never even asked for input".

🌐
SQL Authority
blog.sqlauthority.com › home › how default value and nullable column works? – interview question of the week #129
How Default Value and Nullable Column Works? - Interview Question of the Week #129 - SQL Authority with Pinal Dave
July 2, 2017 - If the column is nullable then ... default value, however, if column is not nullable and there is a default value, SQL Server has to apply that value to column to avoid violating not null constraint....
🌐
IBM Mainframes
ibmmainframes.com › about11461.html
What does NOT NULL WITH DEFAULT both in a same field -IBM Mainframes
DB2: Hi all, I have a doubt in the following case: I have seen a table like this . i cannot understand what does NOT...
🌐
Reddit
reddit.com › r/postgresql › when a field has a default and not null is the default only set if the incoming field is null?
r/PostgreSQL on Reddit: When a field has a DEFAULT and NOT NULL is the DEFAULT only set if the incoming field is NULL?
September 16, 2024 -

When a field has a DEFAULT and NOT NULL specification is the DEFAULT set automatically when the record is created, or is it set only if the new incoming field is NULL?

I want the database to use the DEFAULT only when the incoming field is NULL as generation on the client side has creates some side effects which need to be logged.

Top answer
1 of 8
26

At Uni I was taught that the opposite is true. It's much more dangerous to make something not null without reason. With a nullable field the worst thing that can happen is you trip over the application accessing the data. Oh dear, go back and fix the app...

With a not-null field you make it impossible to add record because some arbitrary field isn't available. Now you need to change the data model and potentially fix the result in a LOT of different places...

It's good to think of null as "unknown". If there's any plausible reason why you might want to enter a record without knowing something then it should be nullable.

One of my university lecturers described it like this:

Apocryphally I've heard of a sales system in the USA which required customer's social security number to make a sale. All the till operators did when a foreigner came to the till was enter 000-00-0000. But then others would enter 123-45-6789. This makes it impossible to identify junk. It's much better to allow a field to be blank than to force it to contain junk.

Or another story. I have genuinely been refused car insurance because I don't have two phone numbers. They absolutely would not give me insurance unless I gave them two. The sales guy suggested I just give a false one. In the end I refused to lie to an insurer and just went with another company.

In practice reserve not null for fields which are required to make sense of the record. For example:

A table of places with fields (ID, Place Name, Country, Longitude, Latitude) ... "longitude" "latitude" should be nullable so that you can store the existence of a place before you know where it is.

But if you have a table who's sole purpose is to store geographical coodinates with fields (Item_id, longitude, latitude) the entire record is meaningless if longitude and latitude are null. Therefore in this instance they should be not-null

In my professional experience since uni, there are far more fields which can optional than need to be mandatory.

2 of 8
8

It strikes me as extremely counter-intuitive...

Intuitive is in the eye of the beholder and your opinion on that is shaped by the things to which you've been exposed. I hail from a time when that kind of safety wasn't standard and the tools didn't point out when you goofed up. I've been using the chain saw without a blade guard long enough that my first instinct is to avoid intuition entirely, go back to the DDL and find out exactly what assumptions the schema will let me make about its data.

...and potentially dangerous for allowing NULL's to be the default behavior.

I think you're overstating the relative dangers. NOT NULL has its own set of pitfalls that can lead to equally-insidious bugs. (Enumerating them would be fodder for a different question.)

The designer of a table always has the option of constraining a column NULL or NOT NULL and will do one or the other to get around the default, whatever it is. Not constraining a column correctly is a developer's failure to follow the business rules. Not doing the right thing elsewhere based on the column's definition is a developer's failure to understand the data he's being handed. There's no technical fix for either.

Still, I have to ask, is there any good reason for the language to be designed this way, with types being nullable by default?

No, there isn't. Because both have hazards, there's also no good reason for the language to be designed the other way. It boils down to picking your poison.