13.2.4 DDL语句 1.创建表的语法

13.2.4 DDL语句

DDL语句是操作数据库对象的语句,包括创建(create)、删除(drop)和修改(alter)数据库对象。
前面已经介绍过,最基本的数据库对象是数据表,数据表是存储数据的逻辑单元。但数据库里绝不仅包括数据表,数据库里可包含如表13.1所示的几种常见的数据库对象。

表13.1常见的数据库对象
对象名称 对象关键字 描述
表格 table 表示存储数据的逻辑单元,以行和列的形式存在,列就是字段,行就是记录.
约束 constraint 执行数据校验的规则,用于保证数据完整性的规则
视图 view 一个或者多个数据表里数据的逻辑显示,视图并不存储数据
索引 index 用于提高查询性能,相当于书的目录
函数 function 用于完成一次特定的计算,具有一个返回值
存储过程 procedure 用于完成一次完整的业务处理,没有返回值,但可以通过传出参数将多个值传给调用环境。
触发器 trigger 相当于一个事件监听器,当数据库发生特定事件后,触发器被触发,完成相应的处理。
因为存在上面几种数据库对象,所以create后可以紧跟不同的关键字。例如,建表应使用create table,建索引应使用create index,建视图应使用create view……
dropalter后也需要添加类似的关键字来表示删除、修改哪种数据库对象。

创建表的语法

1
2
3
4
5
6
create table [模式名.] 表名
(
#可以有多个列定义
columnName1 datatype [default expr],
...
)

上面语法中圆括号里可以包含多个列定义,每个列定义之间以英文逗号(,)隔开,最后一个列定义不需要使用英文逗号,而是直接以括号结束
前面已经讲过,建立数据表只是建立表结构,就是指定该数据表有多少列,每列的数据类型,所以建表语句的重点就是圆括号里的列定义,列定义由列名、列类型和可选的默认值组成
例如下面的建表语句:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
create table test
(
# 整形通常使用int
test_id int,
# 小数点数
test_price decimal,
# 普通长度文本,使用default指定默认值
test_name varchar(255) default 'xxxx',
# 大文本类型
test_desc text,
# 图片
test_img blob,
test_date datetime
);

建表时需要指定每列的数据类型,不同数据库所支持的列类型不同,这需要查阅不同数据库的相关文档。MySQL支持如表13.2所示的几种列类型。

列类型 说明
tinyint 1字节整数
smallint 2字节整数
mediumint 3字节整数
int(integer) 4字节整数
bigint 8字节整数,这些整数类型的区别仅仅是表数范围不同.又可以分为有符号和无符号两种.
float 单精度浮点数
double 双精度浮点数
decimal(dec) 精确小数类型,相对于floatdouble不会产生精度丢失的问题.
date 日期类型,不能保存时间,把java.util.Date对象保存到date列时,时间部分将会丢失.
time 时间类型,不能保存日期,把java.utilDate对象保存到time列时,日期部分将会丢失.
datetime 日期,时间类型
timestamp 时间戳类型
year 年类型,仅仅保存时间的年份
char 定常字符串类型
varchar 可变长度字符串类型
binary 定长二进制字符串类型,它以二进制形式保存字符串
varbinary 可变长度二进制字符串类型,它以二进制形式保存字符串
tinyblob 1字节的二进制大对象,可用于存储图片,音乐等二进制数据,可存储255B
blob 2字节的二进制大对象,可存储64KB
mediumblob 3字节的二进制大对象,可存储16MB
longblob 4字节的二进制大对象,可存储4GB
tinytext 1字节的文本对象,可用于存储超长长度的字符串,可存储255B大小的文本
text 2字节的文本对象,可用于存储超长长度的字符串,也存储64KB大小的文本
mediumtext 3字节的文本对象,16MB
longtext 4字节的文本对象,4GB
enum('value1',value2',...) 枚举类型,该列的值只能是enum后括号里多个值的其中之一
set('value1','value2',...) 集合类型,该列的值可以是set后括号里多个值的其中几
上面是比较常见的建表语句,这种建表语句只是创建一个空表,该表里没有任何数据。如果使用子查询建表语句,则可以在建表的同时插入数据。子查询建表语句的语法如下:
create table [模式名]表名 [column[, column...]] as subquery;
上面语法中新表的字段列表必须与子查询中的字段列表数量匹配,创建新表时的字段列表可以省略,如果省略了该字段列表,则新表的列名与选择结果完全相同。下面语句使用子查询来建表。
1
2
3
create table hehe
as
select * from user_inf;

因为上面语句是利用子查询来建立数据表,所以执行该SQL语句要求数据库中已存在user_inf数据表,通过如下SQL语句来创建和初始化user_inf:

1
2
3
4
5
6
7
8
DROP TABLE IF EXISTS `user_inf`;
CREATE TABLE `user_inf` (
`id` varchar(10) NOT NULL,
`name` varchar(30) CHARACTER SET utf8mb4 DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `user_inf` VALUES ('1', '小明');
INSERT INTO `user_inf` VALUES ('2', '小王');

下面查看两个表中的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mysql> select * from user_inf;
+----+------+
| id | name |
+----+------+
| 1 | 小明 |
| 2 | 小王 |
+----+------+
2 rows in set
mysql> select *from hehe;
+----+------+
| id | name |
+----+------+
| 1 | 小明 |
| 2 | 小王 |
+----+------+
2 rows in set

可以发现两个表中的数据一模一样,使用子查询可以在创建表的同时插入了其他表中的数据.