【问题标题】:Can a primary key be empty? If yes why did this alter cause this result?主键可以为空吗?如果是,为什么这个改变会导致这个结果?
【发布时间】:2013-03-31 19:47:39
【问题描述】:

我有下表:

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)   

如果我选择所有我得到:

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)  

我运行以下命令:

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

我的目的是用location 列中逗号之前的部分和逗号之后的部分填充citystate 列。
但是我的桌子发生了以下情况:

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)  

我得到一条记录,主键 id 为空。这怎么可能?
我的意思是它不是NULL,但主键也不应该为空,对吧?

【问题讨论】:

    标签: mysql sql primary-key alter


    【解决方案1】:

    您将 id 字段定义为 varchar,当您使用它来存储整数时,这是一个愚蠢的想法。空字段 NOT 为空。零长度字符串仍然是有效字符串,因此就您的表而言,它是一个有效的 id 值。尝试插入 ANOTHER 空白字符串,您将得到主键违规:

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

    id 字段应该是 int 类型。那将不允许“空”值。

    【讨论】:

    • 数字0不认为是int类型的空值吗?
    【解决方案2】:

    主键是唯一的,因此如果您更改表,那么第二行将尝试添加一个空值并失败。结果,它将尝试下一个可能的值。如果希望第一个值不为空,可以设置一个默认值。

    【讨论】:

      【解决方案3】:

      它不是空的。它可能是一个空字符串。请注意,数据类型是 varchar(20)。

      【讨论】:

        【解决方案4】:

        好吧,您没有为主键字段分配值,因此默认值为 NULL。 . 您要修改表,使主键为auto_increment

        【讨论】:

        • defaultNULL 还是 Primary key?这怎么可能?不是不允许吗?
        【解决方案5】:

        您可以将varchar 用作与另一个数据库表相关的外键,但如果您希望将其用作数字键,则应使用数字数据类型,例如int

        【讨论】:

          【解决方案6】:

          我知道这不能回答有关主键的确切问题,但正如您的问题确实指出了您在从您的位置列解析城市和州时也遇到问题的事实,这是您想要的查询使用(注意你想要一个 UPDATE 来修改现有的行,而不是一个将添加新行而不是列的 INSERT):

          UPDATE my_contacts
          SET
              city = substr(location, 1, locate(',', location) - 1),
              state = substr(location, locate(',', location) + 1);
          

          【讨论】:

            猜你喜欢
            • 2013-07-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多