MySQL中的change,modify和自增列的關係(r12筆記第70天)
關於MySQL裡的change和modify,總是看到兩種不同的語法,在Oracle中語法有modify,如果修改表名有rename。
alter table change,modify的語法如下:
| ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
| CHANGE [COLUMN] old_col_name new_col_name column_definition
[FIRST|AFTER col_name]
| MODIFY [COLUMN] col_name column_definition
[FIRST | AFTER col_name]
看到一個很善於總結的外國友人總結了一張圖,直接搬過來。
大體來說,change可以修改列名,除了這一點和modify不同之外,其它功能都一樣。
我們做個簡單的小測試來說吧,我們建立一個表test_cm(change和modify合體的意思),然後順便測試一下auto_increment的對比情況。 create table test_cm
(id int(20) unsigned not null auto_increment,name varchar(30),address varchar(50),
primary key(id)
);
然後插入一行資料,讓自增列生效。
insert into test_cm(name,address) values('name1','address1');
select *from test_cm;
+----+-------+----------+
| id | name | address |
+----+-------+----------+
| 1 | name1 | address1 |
+----+-------+----------+
這個沒什麼多說的,自增列從1開始。
我們使用modify語句來修改列的屬性,把自增屬性去掉。
> alter table test_cm modify column id int(20) not null;
Query OK, 1 row affected (0.05 sec)
Records: 1 Duplicates: 0 Warnings: 0
如果使用change語句來做,就是下面的這樣,兩者在這方面是一樣的功能。
> alter table test_cm change column id id int(20) not null;
我們這個時候再嘗試插入一條資料,這個時候就充分呼叫了欄位的預設值,數值型為0.
> insert into test_cm(name,address) values('name1','address1');
Query OK, 1 row affected, 1 warning (0.00 sec)
所以查到的資料是下標為0,和自增列沒有關係了。
> select * from test_cm;
+----+-------+----------+
| id | name | address |
+----+-------+----------+
| 0 | name1 | address1 |
| 1 | name1 | address1 |
+----+-------+----------+
而這個時候繼續插入,就會報錯了,因為預設值還是0,就和已有的資料衝突了。
> insert into test_cm(name,address) values('name1','address1');
ERROR 1062 (23000): Duplicate entry '0' for key 'PRIMARY'
我們補充列名,分別插入兩條資料。
> insert into test_cm values(2,'name2','address2');
> insert into test_cm values(3,'name3','address3');
這個時候的資料情況如下:
> select *from test_cm;
+----+-------+----------+
| id | name | address |
+----+-------+----------+
| 0 | name1 | address1 |
| 1 | name1 | address1 |
| 2 | name2 | address2 |
| 3 | name3 | address3 |
+----+-------+----------+
我們這個時候再來看看change和modify修改列的屬性為自增。
> alter table test_cm change id id int(20) not null auto_increment;
ERROR 1062 (23000): ALTER TABLE causes auto_increment resequencing, resulting in duplicate entry '1' for key 'PRIMARY'
當然不光是change語句,modify語句也會中招。
> alter table test_cm modify id int(20) not null auto_increment;
ERROR 1062 (23000): ALTER TABLE causes auto_increment resequencing, resulting in duplicate entry '1' for key 'PRIMARY'
修改自增列還有一種用法,那就是直接表級設定,當然還是有場景的,在此只是為了對比說明。
> alter table test_cm auto_increment=4;
這種情況檢視欄位屬性是沒有auto_increment的。
> show create table test_cmG
*************************** 1. row ***************************
Table: test_cm
Create Table: CREATE TABLE `test_cm` (
`id` int(20) NOT NULL,
`name` varchar(30) DEFAULT NULL,
`address` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
我們繼續插入一條資料,還是會丟擲一個錯誤,說明自增列設定沒起作用。
> insert into test_cm(name,address) values('name3','address3');
ERROR 1062 (23000): Duplicate entry '0' for key 'PRIMARY'
繼續改進,那就是使用change,
> alter table test_cm modify id int(20) not null auto_increment ;
ERROR 1062 (23000): ALTER TABLE causes auto_increment resequencing, resulting in duplicate entry '1' for key 'PRIMARY'
這個問題該怎麼解,那就是數值衝突了,我們根據錯誤可以看出是主鍵值為1的,我們清理一下。
> delete from test_cm where id=1;
Query OK, 1 row affected (0.00 sec)
這個時候的資料如下。
> select * from test_cm;
+----+-------+----------+
| id | name | address |
+----+-------+----------+
| 0 | name1 | address1 |
| 2 | name2 | address2 |
| 3 | name3 | address3 |
+----+-------+----------+
最後關鍵的時候到來了。
> alter table test_cm modify id int(20) not null auto_increment ;
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
而資料竟然是這樣的。
> select *from test_cm;
+----+-------+----------+
| id | name | address |
+----+-------+----------+
| 1 | name1 | address1 |
| 2 | name2 | address2 |
| 3 | name3 | address3 |
+----+-------+----------+