Can a primary key be empty? If yes why did this alter cause this result?

Cratylus picture Cratylus · Mar 31, 2013 · Viewed 7.1k times · Source

I have the following table:

mysql> DESC my_contacts;  
+----------+-------------+------+-----+---------+-------+  
| Field    | Type        | Null | Key | Default | Extra |  
+----------+-------------+------+-----+---------+-------+  
| id       | varchar(20) | NO   | PRI |         |       |  
| location | varchar(20) | YES  |     | NULL    |       |  
| city     | varchar(20) | YES  |     | NULL    |       |  
| state    | varchar(2)  | YES  |     | NULL    |       |  
+----------+-------------+------+-----+---------+-------+  
4 rows in set (0.01 sec)   

If I do a select all I get:

mysql> SELECT * FROM my_contacts;  
+----+--------------+------+-------+  
| id | location     | city | state |  
+----+--------------+------+-------+  
| 1  | Chester,NJ   | NULL | NULL  |  
| 2  | Katy,TX      | NULL | NULL  |  
| 3  | San Mateo,CA | NULL | NULL  |  
+----+--------------+------+-------+  
3 rows in set (0.00 sec)  

I run the following command:

INSERT INTO my_contacts (city,state)  
VALUES  
(SUBSTRING_INDEX(location,',',1),RIGHT(location,2));  

My purpose was to populate the columns city and state with the part before the comma and the part after the comma from the location column.
But the following happened to my table:

mysql> INSERT INTO my_contacts (city,state)  
    -> VALUES  
    -> (SUBSTRING_INDEX(location,',',1),RIGHT(location,2));  
Query OK, 1 row affected (0.02 sec)   

mysql> SELECT * FROM my_contacts;  
+----+--------------+------+-------+  
| id | location     | city | state |  
+----+--------------+------+-------+  
|    | NULL         | NULL | NULL  |  
| 1  | Chester,NJ   | NULL | NULL  |  
| 2  | Katy,TX      | NULL | NULL  |  
| 3  | San Mateo,CA | NULL | NULL  |  
+----+--------------+------+-------+  
4 rows in set (0.00 sec)  

I get a record and the id which is the primary key is empty. How is this possible?
I mean it is not NULL but a primary key is not supposed to be empty either right?

Answer

Marc B picture Marc B · Mar 31, 2013

You defined your id field as a varchar, which is a dumb idea when you're using it to store integers. an empty field is NOT null. a zero-length string is still a valid string, and therefore a valid id value as far as your table is concerned. Try inserting ANOTHER blank string and you'll get a primary key violation:

INSERT INTO yourtable (id) VALUES (''); // will not work

The id field should be an int type. That'd disallow "empty" values.