Mysql高手系列 – 第4天:DDL常見操作匯總

  • 2019 年 10 月 3 日
  • 筆記

這是Mysql系列第4篇。

環境:mysql5.7.25,cmd命令中進行演示。

DDL:Data Define Language數據定義語言,主要用來對資料庫、表進行一些管理操作。

如:建庫、刪庫、建表、修改表、刪除表、對列的增刪改等等。

文中涉及到的語法用[]包含的內容屬於可選項,下面做詳細說明。

庫的管理

創建庫

create database [if not exists] 庫名;

刪除庫

drop databases [if exists] 庫名;

建庫通用的寫法

drop database if exists 舊庫名;  create database 新庫名;

示例

mysql> show databases like 'javacode2018';  +-------------------------+  | Database (javacode2018) |  +-------------------------+  | javacode2018            |  +-------------------------+  1 row in set (0.00 sec)    mysql> drop database if exists javacode2018;  Query OK, 0 rows affected (0.00 sec)    mysql> show databases like 'javacode2018';  Empty set (0.00 sec)    mysql> create database javacode2018;  Query OK, 1 row affected (0.00 sec)

show databases like 'javacode2018';列出javacode2018庫資訊。

表管理

創建表

create table 表名(      欄位名1 類型[(寬度)] [約束條件] [comment '欄位說明'],      欄位名2 類型[(寬度)] [約束條件] [comment '欄位說明'],      欄位名3 類型[(寬度)] [約束條件] [comment '欄位說明']  )[表的一些設置];

注意:

  1. 在同一張表中,欄位名不能相同
  2. 寬度和約束條件為可選參數,欄位名和類型是必須的
  3. 最後一個欄位後不能加逗號
  4. 類型是用來限制 欄位 必須以何種數據類型來存儲記錄
  5. 類型其實也是對欄位的約束(約束欄位下的記錄必須為XX類型)
  6. 類型後寫的 約束條件 是在類型之外的 額外添加的約束

約束說明

not null:標識該欄位不能為空

mysql> create table test1(a int not null comment '欄位a');  Query OK, 0 rows affected (0.01 sec)    mysql> insert into test1 values (null);  ERROR 1048 (23000): Column 'a' cannot be null  mysql> insert into test1 values (1);  Query OK, 1 row affected (0.00 sec)    mysql> select * from test1;  +---+  | a |  +---+  | 1 |  +---+  1 row in set (0.00 sec)

default value:為該欄位設置默認值,默認值為value

mysql> drop table IF EXISTS test2;  Query OK, 0 rows affected (0.01 sec)    mysql> create table test2(      ->   a int not null comment '欄位a',      ->   b int not null default 0 comment '欄位b'      -> );  Query OK, 0 rows affected (0.02 sec)    mysql> insert into test2(a) values (1);  Query OK, 1 row affected (0.00 sec)    mysql> select *from test2;  +---+---+  | a | b |  +---+---+  | 1 | 0 |  +---+---+  1 row in set (0.00 sec)

上面插入時未設置b的值,自動取默認值0

primary key:標識該欄位為該表的主鍵,可以唯一的標識記錄,插入重複的會報錯

兩種寫法,如下:

方式1:跟在列後,如下:

mysql> drop table IF EXISTS test3;  Query OK, 0 rows affected, 1 warning (0.00 sec)    mysql> create table test3(      ->   a int not null comment '欄位a' primary key      -> );  Query OK, 0 rows affected (0.01 sec)    mysql> insert into test3 (a) values (1);  Query OK, 1 row affected (0.01 sec)    mysql> insert into test3 (a) values (1);  ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'

方式2:在所有列定義之後定義,如下:

mysql> drop table IF EXISTS test4;  Query OK, 0 rows affected, 1 warning (0.00 sec)    mysql> create table test4(      ->   a int not null comment '欄位a',      ->   b int not null default 0 comment '欄位b',      ->   primary key(a)      -> );  Query OK, 0 rows affected (0.02 sec)    mysql> insert into test4(a,b) values (1,1);  Query OK, 1 row affected (0.00 sec)    mysql> insert into test4(a,b) values (1,2);  ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'

插入重複的值,會報違法主鍵約束

方式2支援多欄位作為主鍵,多個之間用逗號隔開,語法:primary key(欄位1,欄位2,欄位n),示例:

mysql> drop table IF EXISTS test7;  Query OK, 0 rows affected, 1 warning (0.00 sec)    mysql>  mysql> create table test7(      ->    a int not null comment '欄位a',      ->    b int not null comment '欄位b',      ->   PRIMARY KEY (a,b)      ->  );  Query OK, 0 rows affected (0.02 sec)    mysql>  mysql> insert into test7(a,b) VALUES (1,1);  Query OK, 1 row affected (0.00 sec)    mysql> insert into test7(a,b) VALUES (1,1);  ERROR 1062 (23000): Duplicate entry '1-1' for key 'PRIMARY'

foreign key:為表中的欄位設置外鍵

語法:foreign key(當前表的列名) references 引用的外鍵表(外鍵表中欄位名稱)

mysql> drop table IF EXISTS test6;  Query OK, 0 rows affected (0.01 sec)    mysql> drop table IF EXISTS test5;  Query OK, 0 rows affected (0.01 sec)    mysql>  mysql> create table test5(      ->   a int not null comment '欄位a' primary key      -> );  Query OK, 0 rows affected (0.02 sec)    mysql>  mysql> create table test6(      ->   b int not null comment '欄位b',      ->   ts5_a int not null,      ->   foreign key(ts5_a) references test5(a)      -> );  Query OK, 0 rows affected (0.01 sec)    mysql> insert into test5 (a) values (1);  Query OK, 1 row affected (0.00 sec)    mysql> insert into test6 (b,test6.ts5_a) values (1,1);  Query OK, 1 row affected (0.00 sec)    mysql> insert into test6 (b,test6.ts5_a) values (2,2);  ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`javacode2018`.`test6`, CONSTRAINT `test6_ibfk_1` FOREIGN KEY (`ts5_a`) REFERENCES `test5` (`a`))

說明:表示test6中ts5_a欄位的值來源於表test5中的欄位a。

注意幾點:

  • 兩張表中需要建立外鍵關係的欄位類型需要一致
  • 要設置外鍵的欄位不能為主鍵
  • 被引用的欄位需要為主鍵
  • 被插入的值在外鍵表必須存在,如上面向test6中插入ts5_a為2的時候報錯了,原因:2的值在test5表中不存在

unique key(uq):標識該欄位的值是唯一的

支援一個到多個欄位,插入重複的值會報違反唯一約束,會插入失敗。

定義有2種方式。

方式1:跟在欄位後,如下:

mysql> drop table IF EXISTS test8;  Query OK, 0 rows affected, 1 warning (0.00 sec)    mysql>  mysql> create table test8(      ->    a int not null comment '欄位a' unique key      ->  );  Query OK, 0 rows affected (0.01 sec)    mysql>  mysql> insert into test8(a) VALUES (1);  Query OK, 1 row affected (0.00 sec)    mysql> insert into test8(a) VALUES (1);  ERROR 1062 (23000): Duplicate entry '1' for key 'a'

方式2:所有列定義之後定義,如下:

mysql> drop table IF EXISTS test9;  Query OK, 0 rows affected, 1 warning (0.00 sec)    mysql>  mysql> create table test9(      ->    a int not null comment '欄位a',      ->   unique key(a)      ->  );  Query OK, 0 rows affected (0.01 sec)    mysql>  mysql> insert into test9(a) VALUES (1);  Query OK, 1 row affected (0.00 sec)    mysql> insert into test9(a) VALUES (1);  ERROR 1062 (23000): Duplicate entry '1' for key 'a'

方式2支援多欄位,多個之間用逗號隔開,語法:primary key(欄位1,欄位2,欄位n),示例:

mysql> drop table IF EXISTS test10;  Query OK, 0 rows affected, 1 warning (0.00 sec)    mysql>  mysql> create table test10(      ->   a int not null comment '欄位a',      ->   b int not null comment '欄位b',      ->   unique key(a,b)      -> );  Query OK, 0 rows affected (0.01 sec)    mysql>  mysql> insert into test10(a,b) VALUES (1,1);  Query OK, 1 row affected (0.00 sec)    mysql> insert into test10(a,b) VALUES (1,1);  ERROR 1062 (23000): Duplicate entry '1-1' for key 'a'

auto_increment:標識該欄位的值自動增長(整數類型,而且為主鍵)

mysql> drop table IF EXISTS test11;  Query OK, 0 rows affected, 1 warning (0.00 sec)    mysql>  mysql> create table test11(      ->   a int not null AUTO_INCREMENT PRIMARY KEY comment '欄位a',      ->   b int not null comment '欄位b'      -> );  Query OK, 0 rows affected (0.01 sec)    mysql>  mysql> insert into test11(b) VALUES (10);  Query OK, 1 row affected (0.00 sec)    mysql> insert into test11(b) VALUES (20);  Query OK, 1 row affected (0.00 sec)    mysql> select * from test11;  +---+----+  | a | b  |  +---+----+  | 1 | 10 |  | 2 | 20 |  +---+----+  2 rows in set (0.00 sec)

欄位a為自動增長,默認值從1開始,每次+1

關於自動增長欄位的初始值、步長可以在mysql中進行設置,比如設置初始值為1萬,每次增長10

注意:

自增長列當前值存儲在記憶體中,資料庫每次重啟之後,會查詢當前表中自增列的最大值作為當前值,如果表數據被清空之後,資料庫重啟了,自增列的值將從初始值開始

我們來演示一下:

mysql> delete from test11;  Query OK, 2 rows affected (0.00 sec)    mysql> insert into test11(b) VALUES (10);  Query OK, 1 row affected (0.00 sec)    mysql> select * from test11;  +---+----+  | a | b  |  +---+----+  | 3 | 10 |  +---+----+  1 row in set (0.00 sec)

上面刪除了test11數據,然後插入了一條,a的值為3,執行下面操作:

刪除test11數據,重啟mysql,插入數據,然後看a的值是不是被初始化了?如下:

mysql> delete from test11;  Query OK, 1 row affected (0.00 sec)    mysql> select * from test11;  Empty set (0.00 sec)    mysql> exit  Bye    C:Windowssystem32>net stop mysql  mysql 服務正在停止..  mysql 服務已成功停止。      C:Windowssystem32>net start mysql  mysql 服務正在啟動 .  mysql 服務已經啟動成功。      C:Windowssystem32>mysql -uroot -p  Enter password: *******  Welcome to the MySQL monitor.  Commands end with ; or g.  Your MySQL connection id is 2  Server version: 5.7.25-log MySQL Community Server (GPL)    Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.    Oracle is a registered trademark of Oracle Corporation and/or its  affiliates. Other names may be trademarks of their respective  owners.    Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.    mysql> use javacode2018;  Database changed  mysql> select * from test11;  Empty set (0.01 sec)    mysql> insert into test11 (b) value (100);  Query OK, 1 row affected (0.00 sec)    mysql> select * from test11;  +---+-----+  | a | b   |  +---+-----+  | 1 | 100 |  +---+-----+  1 row in set (0.00 sec)

刪除表

drop table [if exists] 表名;

修改表名

alter table 表名 rename [to] 新表名;

表設置備註

alter table 表名 comment '備註資訊';

複製表

只複製表結構
create table 表名 like 被複制的表名;

如:

mysql> create table test12 like test11;  Query OK, 0 rows affected (0.01 sec)    mysql> select * from test12;  Empty set (0.00 sec)    mysql> show create table test12;  +--------+-------+  | Table  | Create Table  +--------+-------+  | test12 | CREATE TABLE `test12` (    `a` int(11) NOT NULL AUTO_INCREMENT COMMENT '欄位a',    `b` int(11) NOT NULL COMMENT '欄位b',    PRIMARY KEY (`a`)  ) ENGINE=InnoDB DEFAULT CHARSET=utf8     |  +--------+-------+  1 row in set (0.00 sec)
複製表結構+數據
create table 表名 [as] select 欄位,... from 被複制的表 [where 條件];

如:

mysql> create table test13 as select * from test11;  Query OK, 1 row affected (0.02 sec)  Records: 1  Duplicates: 0  Warnings: 0    mysql> select * from test13;  +---+-----+  | a | b   |  +---+-----+  | 1 | 100 |  +---+-----+  1 row in set (0.00 sec)

表結構和數據都過來了。

表中列的管理

添加列

alter table 表名 add column 列名 類型 [列約束];

示例:

mysql> drop table IF EXISTS test14;  Query OK, 0 rows affected, 1 warning (0.00 sec)    mysql>  mysql> create table test14(      ->   a int not null AUTO_INCREMENT PRIMARY KEY comment '欄位a'      -> );  Query OK, 0 rows affected (0.02 sec)    mysql> alter table test14 add column b int not null default 0 comment '欄位b';  Query OK, 0 rows affected (0.03 sec)  Records: 0  Duplicates: 0  Warnings: 0    mysql> alter table test14 add column c int not null default 0 comment '欄位c';  Query OK, 0 rows affected (0.05 sec)  Records: 0  Duplicates: 0  Warnings: 0    mysql> insert into test14(b) values (10);  Query OK, 1 row affected (0.00 sec)    mysql> select * from test14;                                                 c  +---+----+---+  | a | b  | c |  +---+----+---+  | 1 | 10 | 0 |  +---+----+---+  1 row in set (0.00 sec)

修改列

alter table 表名 modify column 列名 新類型 [約束];  或者  alter table 表名 change column 列名 新列名 新類型 [約束];

2種方式區別:modify不能修改列名,change可以修改列名

我們看一下test14的表結構:

mysql> show create table test14;  +--------+--------+  | Table  | Create Table |  +--------+--------+  | test14 | CREATE TABLE `test14` (    `a` int(11) NOT NULL AUTO_INCREMENT COMMENT '欄位a',    `b` int(11) NOT NULL DEFAULT '0' COMMENT '欄位b',    `c` int(11) NOT NULL DEFAULT '0' COMMENT '欄位c',    PRIMARY KEY (`a`)  ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8       |  +--------+--------+  1 row in set (0.00 sec)

我們將欄位c名字及類型修改一下,如下:

mysql> alter table test14 change column c d varchar(10) not null default '' comment '欄位d';  Query OK, 0 rows affected (0.01 sec)  Records: 0  Duplicates: 0  Warnings: 0    mysql> show create table test14;                                                          ;;  +--------+--------+  | Table  | Create Table |  +--------+--------+  | test14 | CREATE TABLE `test14` (    `a` int(11) NOT NULL AUTO_INCREMENT COMMENT '欄位a',    `b` int(11) NOT NULL DEFAULT '0' COMMENT '欄位b',    `d` varchar(10) NOT NULL DEFAULT '' COMMENT '欄位d',    PRIMARY KEY (`a`)  ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8       |  +--------+--------+  1 row in set (0.00 sec)

刪除列

alter table 表名 drop column 列名;

示例:

mysql> alter table test14 drop column d;  Query OK, 0 rows affected (0.05 sec)  Records: 0  Duplicates: 0  Warnings: 0    mysql> show create table test14;  +--------+--------+  | Table  | Create Table |  +--------+--------+  | test14 | CREATE TABLE `test14` (    `a` int(11) NOT NULL AUTO_INCREMENT COMMENT '欄位a',    `b` int(11) NOT NULL DEFAULT '0' COMMENT '欄位b',    PRIMARY KEY (`a`)  ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8     |  +--------+--------+  1 row in set (0.00 sec)

Mysql系列目錄

  1. 第1天:mysql基礎知識
  2. 第2天:詳解mysql數據類型(重點)
  3. 第3天:管理員必備技能(必須掌握)

對mysql感興趣的,加一下我的微信itsoku,拉你入群交流技術。

mysql系列大概有20多篇,喜歡的請關注一下!