#DDL
/*
数据定义语言
库和表的管理
一、库的管理
创建、修改、删除
二、表的管理
创建、修改、删除
创建:create
修改:alter
删除:drop
*/
#【一、库的管理】
#1、【库的创建】
/*
语法:
create database 【if not exists】库名 【character set 字符集名】;
*/
#创建库Books
CREATE DATABASE books;#默认字符集是utf8
#上述语句重复执行就会报错,下面添加容错性处理
CREATE DATABASE IF NOT EXISTS books;#如果库已经存在就不再创建
#2、【库的修改(库一般不修改)】
#以下语句不安全,会导致数据丢失,目前已经废弃
RENAME DATABASE books TO 新库名;
#但是可以修改字符集
ALTER DATABASE books CHARACTER SET gbk;
#3、【库的删除】
DROP DATABASE books;
#上述语句重复执行就会报错,下面添加容错性处理
DROP DATABASE IF EXISTS books;
#【二、表的管理】
#1、表的创建★
/*
语法:
create table 【if not exists】表名(
列名 列的类型【(长度) 约束】,
列名 列的类型【(长度) 约束】,
列名 列的类型【(长度) 约束】,
...
列名 列的类型【(长度) 约束】
)
*/
#创建表book
CREATE TABLE book(
id INT,#编号
bName VARCHAR(20),#图书名 20不能省,最低字符数
price DOUBLE,#价格
authorId INT,#作者编号
publishDate DATETIME#出版日期
)
DESC book;
#创建表author
#有容错性处理
CREATE TABLE IF NOT EXISTS author(
id INT,
au_name VARCHAR(20),
nation VARCHAR(10)
)
DESC author;
#2、表的修改
/*
语法:
alter table 表名 change|modify|add|drop column 列名 【类型 约束】;
alter table 表名 rename to ...
*/
#(1)修改列名
/*
alter table 表名 change column 旧列名 新列名 新/旧类型
*/
#【将旧列名publishdate修改为新列名pubDat,同时确定pubDate的类型为DATETIME】
#【column可以省略】
ALTER TABLE book CHANGE COLUMN publishdate pubDate DATETIME;
#(2)修改列的类型或约束
/*
alter table 表名 modify column 列名 【新类型】【新约束】
*/
#【将pubDate的类型改为TIMESTAMP】
ALTER TABLE book MODIFY COLUMN pubDate TIMESTAMP;
#(3)添加新列
/*
alter table 表名 add column 列名 类型【first|after 字段】
*/
#【为author表添加新列annual,类型为double】
ALTER TABLE author ADD COLUMN annual DOUBLE;
#将annual字段放在第一个
ALTER TABLE author ADD COLUMN annual DOUBLE FIRST;
#将annual字段放在au_name字段的后面
ALTER TABLE author ADD COLUMN annual DOUBLE AFTER au_name;
#(4)删除列
/*
alter table 表名 drop column 列名;
*/
#没有容错性处理exists
ALTER TABLE author DROP COLUMN annual;
#(5)修改表名
/*
alter table 表名 rename to book_author;
*/
ALTER TABLE author RENAME TO book_author;
#3、表的删除
/*
drop table 【if exists】表名;
*/
DROP TABLE book_author;
#容错性处理
DROP TABLE IF EXISTS book_author;
#查看当前库中的所有表
SHOW TABLES;
#容错性处理仅仅在库和表的【删除】和【创建】中有,在列的删除中是没有的
#对于创建数据库和数据表有一套通用的写法【先删再建】
DROP DATABASE IF EXISTS 旧库名;
CREATE DATABASE 新库名;
DROP TABLE IF EXISTS 旧表名;
CREATE TABLE 表名(...);
#4、表的复制
#在表author中插入数据
INSERT INTO author
VALUES (1,'村上春树','日本'),
(2,'莫言','中国'),
(3,'冯唐','中国'),
(4,'金庸','中国')
SELECT * FROM author;
#(1)仅仅复制表的结构【不复制数据】
/*
create table 表名 like 旧表
*/
CREATE TABLE copy LIKE author;
SELECT * FROM copy;
#(2)复制表的结构+数据
CREATE TABLE copy2
SELECT * FROM author;
SELECT * FROM copy2;
#(3)只复制部分数据
CREATE TABLE copy3
SELECT id,au_name
FROM author
WHERE nation='中国';
SELECT * FROM copy3;
#思考:仅仅仅仅复制表的部分结构【不复制数据】
#将where条件设置成谁都不满足,就没有数据
CREATE TABLE copy4
SELECT id,au_name
FROM author
WHERE 1=2;
SELECT * FROM copy4;
S
#练习:在test库中创建新表,将表departments中的数据插入到新表dept
CREATE TABLE dept
SELECT department_id,department_name
FROM myemployees.departments;
#常见数据类型
/*
数值型:
整数型
小数:
定点数
浮点数
字符型:
较短是文本:char、varchar
较长的文本:text、blob(较长的二进制)
日期型:
*/
#一、整型
/*
分类: tinyint smallint mediumint int\integer bigint
字节: 1 2 3 4 8
特点:
(1)默认有符号,若想设置无符号则追加unsigned
(2)若插入的数值超出了整型的范围,会报out of range异常,并且插入临界值
(3)如果不设置长度会有默认的长度,这个长度不是范围,而是显示结果中该列的宽度,
如果不够宽度,那么在有关键字ZEROFILL的情况下,就会用0填充。且加上ZEROFILL后就只支持无符号
UNSIGNED可以省略
*/
#1.如何设置无符号和有符号
DROP TABLE IF EXISTS tab_int;
CREATE TABLE tab_int(
t1 INT(7) ZEROFILL,
t2 INT ZEROFILL UNSIGNED #UNSIGNED已经没有意义,默认填充到10位
);
DESC tab_int
INSERT INTO tab_int VALUES(-1234,-2345);
INSERT INTO tab_int VALUES(123,123);
SELECT * FROM tab_int;
#二、小数
/*
分类:
1.浮点型
float(M,D) double(M,D)
4字节 8字节
2.定点型
dec(M,D)
decimal(M,D)
特点:
(1)M和D分别代表的意思是:
M:整数部分的位数+小数部分的位数(如果超出范围则插入临界值)
D:规定小数部分的位数(补0/四舍五入)
(2)M和D可以省略,如果是DECIMAL,则M=10,D=0;如果是float和double,则会根据插入的数值的精度来决定精度
(3)定点型的精度较高,如果要求插入的数值的精度较高如货币运输等则考虑使用
*/
#(1)测试:M和D的意思
CREATE TABLE tab_float(
f1 FLOAT(5,2),
f2 DOUBLE(5,2),
f3 DECIMAL(5,2)
);
SELECT * FROM tab_float;
INSERT INTO tab_float VALUES(123.45,123.45,123.45);#123.45
INSERT INTO tab_float VALUES(123.456,123.456,123.456);#123.46 四舍五入 保留2位
INSERT INTO tab_float VALUES(6123.45,6123.45,6123.45);#999.99 一共6位数>5 插入临界值
INSERT INTO tab_float VALUES(6123.4,6123.4,6123.4);#999.99 为了保证小数点后有两位数,那么总的数字个数就会大于5
#(2)若将M和D省略
CREATE TABLE tab_float1(
f1 FLOAT,
f2 DOUBLE,
f3 DECIMAL
);
INSERT INTO tab_float1 VALUES(1223.4567,1223.4567,1223.4567);#只有DECIMAL有警告
SELECT * FROM tab_float1;#1223.4567 1223.4567 1223 DECIMAL默认(10,0)
/*
原则:
所选的类型越简单越好,能保存的数值越小越好
*/
#三、字符型
/*
较短的文本:【重点】
char
varchar
其他:
binary和varbinary用于保存较短的二进制
enum用于保存枚举
set用于保存集合
较长的文本:
text
blob(较大的二进制)
特点:
写法 M的意思 特点 空间的耗费 效率
char char(M) 最大的字符数,可省,默认1 固定长度的字符 耗费 高
varchar varchar(M) 最大的字符数,不可省 可变长度的字符 节省 低
*/
#枚举型enum
#只能插入列表中枚举出来的数据,且不区分大小写
CREATE TABLE tab_char(
c1 ENUM('a','b','c')
);
INSERT INTO tab_char VALUES('a');
INSERT INTO tab_char VALUES('b');
INSERT INTO tab_char VALUES('c');
INSERT INTO tab_char VALUES('m');#插入失败
INSERT INTO tab_char VALUES('A');
SELECT * FROM tab_char;
#set集合
#可以同时插入多个(二enum每次只能插入一个),不区分大小写
CREATE TABLE tab_set(
s1 SET('a','b','c','d')
)
INSERT INTO tab_set VALUES('a');
INSERT INTO tab_set VALUES('a,b,c');
SELECT * FROM tab_set;
#四、日期型
/*
分类:
date只保存日期
time只保存时间
year只保存年
datetime保存日期+时间
timestamp保存日期+时间
特点:
字节 范围 时区等的影响
datetime 8 1000---9999 不受
timestamp 4 1970---2038 受
*/
CREATE TABLE tab_date(
t1 DATETIME,
t2 TIMESTAMP
);
INSERT INTO tab_date VALUES(NOW(),NOW());
#查看当前时区
SHOW VARIABLES LIKE 'time_zone';#system 【当前系统时区其实就是东八区】
SELECT * FROM tab_date;#插入的时间一样
#将当前时区改为东9区
SET time_zone='+9:00';
#查看当前时区
SHOW VARIABLES LIKE 'time_zone';#+9:00
#再去查询
SELECT * FROM tab_date;#这时候,刚刚插入的时间就不一样了【东9区比东8区块一个小时】
#常见约束
/*
含义:一种限制,用于限制表中的数据,为了保证表中的数据的准确和可靠性
分类:六大约束
not null:非空,用于保证该字段值不能为空
比如:姓名、学号
default:默认,用于保证该字段有默认值
比如:性别
primary key:主键,用于保证该字段的值具有唯一性,并且非空
比如:学号、员工编号、部门号等
unique:唯一,用于保证该字段的值具有唯一性,可以为空
比如:座位号
check:检查约束【mysql中不支持】
比如年龄、性别,只能在一定范围内,不可以随意输入
foreign key:外键,用于限制两个表的关系,用于保证该字段的值,必须来自主表关联列的值
比如:员工表、部门表。员工表含中有部门编号,部门表中的部门编号是1~100,那么foreign key
就可以限制员工表中的部门编号范围是1~100。foreign key是为员工表添加的约束。
添加约束的时机:
1.创建表时
2.修改表时
约束的添加分类:
列级约束
六大约束语法上都支持,但是外键约束没有效果
表级约束
除了非空、默认,其他都支持
*/
CREATE TABLE 表名(
字段名 字段类型 列级约束,
字段名 字段类型,
表级约束
)
#一、创建表时添加约束
#1.添加列级约束
/*
直接在字段名和类型后面直接添加 约束类型即可
只支持:默认、非空、主键、唯一
*/
CREATE DATABASE students;
USE students;
CREATE TABLE stuinfo(
id INT PRIMARY KEY,#主键
stuName VARCHAR(20) NOT NULL,#非空
gender CHAR(1) CHECK(gender='男' OR gender='女'),#检查
seat INT UNIQUE,#唯一
age INT DEFAULT 18,#默认约束
majorId INT REFERENCES major(id)#外键不支持列级约束 majorId INT FOREIGN KEY REFERENCES major(id)
);
CREATE TABLE major(
id INT PRIMARY KEY,
majorName VARCHAR(20)
);
#右击stuinfo,打开表
#2.添加表级约束
/*
语法:在各个字段的最下面
【constraint 约束名】 约束类型(被约束的字段名)
不支持:非空和默认
*/
DROP TABLE IF EXISTS stuinfo;
CREATE TABLE stuinfo(
id INT,
stuname VARCHAR(20),
gender CHAR(1),
seat INT,
age INT,
majorid INT,
PRIMARY KEY(id),#主键CONSTRAINT pk PRIMARY KEY(id)
CONSTRAINT uq UNIQUE(seat),#唯一
CONSTRAINT ck CHECK(gender='男' OR gender='女'),#检查
CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id)#外键
);
#查看结果
SHOW INDEX FROM stuinfo;
#通用写法
DROP TABLE IF EXISTS stuinfo;
CREATE TABLE IF NOT EXISTS stuinfo(
id INT PRIMARY KEY,
stuname VARCHAR(20) NOT NULL,
sex CHAR(1),
age INT DEFAULT 18,
seat INT UNIQUE,
majorid INT,
CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id)
);
/*
primary key <----> unique
主键和唯一大PK:
保证唯一性 是否允许为空 一个表中可以有多少个 是否允许组合
primary key √ × 最多1个 允许(不推荐)
unique √ √ 可以多个 允许(不推荐)
*/
#(1)5.6版本的unique,对于约束是unique的字段,插入数据时,只能有一组数据的该字段的值为null
INSERT INTO major VALUES(1,'java');
INSERT INTO major VALUES(2,'H5');
INSERT INTO stuinfo VALUES(1,'join','男',19,NULL,1);
INSERT INTO stuinfo VALUES(2,'lily','女',19,NULL,2);
SELECT * FROM stuinfo;
#(2)可以为多个字段设置unique,但是只能为一个字段设置primary key
#(3)可以设置联合主键
DROP TABLE IF EXISTS stuinfo;
CREATE TABLE stuinfo(
id INT,
stuname VARCHAR(20),
gender CHAR(1),
age INT,
seat INT,
majorid INT,
PRIMARY KEY(id,stuname),#不是设置两个主键,而是将这两个字段合并成一个字段成为一个主键
CONSTRAINT uq UNIQUE(seat),#唯一
CONSTRAINT ck CHECK(gender='男' OR gender='女'),#检查
CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id)#外键
);
#不报错
INSERT INTO stuinfo VALUES(1,'join','男',19,NULL,1);
INSERT INTO stuinfo VALUES(2,'join','男',19,NULL,2);
#也不报错
INSERT INTO stuinfo VALUES(1,'join','男',19,NULL,1);
INSERT INTO stuinfo VALUES(1,'lily','男',19,NULL,2);
#报错
INSERT INTO stuinfo VALUES(1,'join','男',19,NULL,1);
INSERT INTO stuinfo VALUES(1,'join','男',19,NULL,2);
/*
外键:
1.要求在从表上设置外键关系
2.从表的外键列的类型和主表的类型要求一致或兼容,名称无要求
3.主表的关联列必须是一个key(一般是主键或唯一键)
CREATE TABLE major(
id INT PRIMARY KEY,#或者id INT UNIQUE
majorName VARCHAR(20)
);
4.插入数据时,先插入主表major,再插入从表stuinfo
5.可以为一个字段加多个约束,往后追加就可以了
*/
#二、修改表时添加约束
/*
(1)添加列级约束
alter table 表名 modify column 字段名 字段类型 新约束;
(2)添加表级约束
alter table 表名 add 【constraint 约束名】 约束类型(字段名) 【外键的引用】;
*/
DROP TABLE IF EXISTS stuinfo;
CREATE TABLE stuinfo(
id INT,
stuname VARCHAR(20),
gender CHAR(1),
seat INT,
age INT,
majorid INT
);
DESC stuinfo;
#1.添加非空约束
ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20) NOT NULL;
#2.添加默认约束
ALTER TABLE stuinfo MODIFY COLUMN age INT DEFAULT 18;
#3.添加主键
#(1)列级约束
ALTER TABLE stuinfo MODIFY COLUMN id INT PRIMARY KEY;
#(2)表级约束
ALTER TABLE stuinfo ADD PRIMARY KEY(id);
#4.添加唯一约束
#(1)列级约束
ALTER TABLE stuinfo MODIFY COLUMN seat INT UNIQUE;
#(2)表级约束
ALTER TABLE stuinfo ADD UNIQUE(seat);
#5.添加外键
#仅表级约束
ALTER TABLE stuinfo ADD FOREIGN KEY(majorid) REFERENCES major(id);
#加名字也可以
ALTER TABLE stuinfo ADD CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id);
#三、修改表时删除约束
#1. 删除非空约束
ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20) NULL;
#或
ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20);
#2.删除默认约束
ALTER TABLE stuinfo MODIFY COLUMN age INT;
#3.删除主键
ALTER TABLE stuinfo MODIFY COLUMN id INT;
#或
ALTER TABLE stuinfo DROP PRIMARY KEY;
#4.删除唯一
ALTER TABLE stuinfo DROP INDEX seat;
ALTER TABLE stuinfo MODIFY COLUMN seat INT;
#5.删除外键
ALTER TABLE stuinfo DROP FOREIGN KEY majorid;
SHOW INDEX FROM stuinfo;