mySQL__DDL课堂笔记和练习

#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;

猜你喜欢

转载自www.cnblogs.com/deer-cen/p/12749549.html