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 …… |
|
|
drop 和alter 后也需要添加类似的关键字来表示删除、修改哪种数据库对象。 |
|
|
创建表的语法
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) |
精确小数类型,相对于float 和double 不会产生精度丢失的问题. |
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
|
可以发现两个表中的数据一模一样,使用子查询可以在创建表的同时插入了其他表中的数据.