MySQL基础03 - 建表语句、CRUD、非空约束、唯一约束、主键约束、外键约束

建表语句

/*
6、创建表

建表语句的语法格式:
	creage table 表名(
		字段名1 数据类型,
		字段名2 数据类型,
		字段名3 数据类型,
		...
	);

关于MySQL当中字段的数据类型?以下只说常见的
	int     整数型(java中的int)
	bigint  长整型(java中的long)
	float   浮点型(java中的float double)
	char    定长字符串(String)
	varchar 可变长字符串(StringBuilder/StringBuffer)
	date    日期类型(对应java中的java.sql.Date类型)
	BLOB    二进制大对象(存储图片、视频等流媒体信息) Binary Large OBject(对应java中的Object)
	CLOB    字符大对象(存储较大文本,比如,可以存储4G的字符串。) Character Large OBject(对应java中的Object)

char和varchar怎么选择?
	在实际的开发中,当某个字段的数据长度不发生改变的时候,是定长的,例如:性别、生日等都是采用char。
	当一个字段的数据长度不确定,例如:简介、姓名等都是采用varchar。

BLOB和CLOB类型的使用?
	电影表:t_movie
	id(int)    name(varchar)    playtime(date/char)   haibao(BLOB)    history(CLOB)
	-------------------------------------------------------------------------------------------
	1           蜘蛛侠
	2
	3

表名在数据库当中一般建议以:t_或者tbl_开始。

创建学生表:
	学生信息包括:
		学号、姓名、性别、班级编号、生日
		学号:bigint
		姓名:varchar
		性别:char
		班级编号:varchar
		生日:char
	
	create table t_student(
		no bigint,
		name varchar(255),
		sex char(1),
		classno varchar(255),
		birth char(10)
	);

7、insert语句插入数据

	语法格式:
		insert into 表名(字段名1, 字段名2, 字段名3,...) values(值1, 值2, 值3, ...)
		要求:字段的数量和值的数量相同,并且数据类似要对应相同。
		
	insert into t_student(no,name,sex,classno,birth) values(1,'zhangsan','1','gaosan1ban');
	ERROR 1136 (21S01): Column count doesn't match value count at row 1
	
	insert into t_student(no,name,sex,classno,birth) values(1,'zhangsan','1','gaosan1ban','2000-03-21');
	
	mysql> select * from t_student;
	+------+----------+------+------------+------------+
	| no   | name     | sex  | classno    | birth      |
	+------+----------+------+------------+------------+
	|    1 | zhangsan | 1    | gaosan1ban | 2000-03-21 |
	+------+----------+------+------------+------------+

	insert into t_student(name,sex,classno,birth,no) values('lisi','1','gaosan1ban','2001-05-15',2); // 可以颠倒字段顺序
	mysql> select * from t_student;
	+------+----------+------+------------+------------+
	| no   | name     | sex  | classno    | birth      |
	+------+----------+------+------------+------------+
	|    1 | zhangsan | 1    | gaosan1ban | 2000-03-21 |
	|    2 | lisi     | 1    | gaosan1ban | 2001-05-15 |
	+------+----------+------+------------+------------+

	insert into t_student(name) values('wangwu'); // 除name字段之外,剩下的所有字段自动插入NULL。
	mysql> select * from t_student;
	+------+----------+------+------------+------------+
	| no   | name     | sex  | classno    | birth      |
	+------+----------+------+------------+------------+
	|    1 | zhangsan | 1    | gaosan1ban | 2000-03-21 |
	|    2 | lisi     | 1    | gaosan1ban | 2001-05-15 |
	| NULL | wangwu   | NULL | NULL       | NULL       |
	+------+----------+------+------------+------------+

	insert into t_student(no) values(3);
	mysql> select * from t_student;
	+------+----------+------+------------+------------+
	| no   | name     | sex  | classno    | birth      |
	+------+----------+------+------------+------------+
	|    1 | zhangsan | 1    | gaosan1ban | 2000-03-21 |
	|    2 | lisi     | 1    | gaosan1ban | 2001-05-15 |
	| NULL | wangwu   | NULL | NULL       | NULL       |
	|    3 | NULL     | NULL | NULL       | NULL       |
	+------+----------+------+------------+------------+

	drop table if exists t_student; // 当这个表存在的话删除。
	create table t_student(
		no bigint,
		name varchar(255),
		sex char(1) default 1,
		classno varchar(255),
		birth char(10)
	);
	mysql> desc t_student;
	+---------+--------------+------+-----+---------+-------+
	| Field   | Type         | Null | Key | Default | Extra |
	+---------+--------------+------+-----+---------+-------+
	| no      | bigint(20)   | YES  |     | NULL    |       |
	| name    | varchar(255) | YES  |     | NULL    |       |
	| sex     | char(1)      | YES  |     | 1       |       |
	| classno | varchar(255) | YES  |     | NULL    |       |
	| birth   | char(10)     | YES  |     | NULL    |       |
	+---------+--------------+------+-----+---------+-------+
	
	insert into t_student(name) values('zhangsan');
	mysql> select * from t_student;
	+------+----------+------+---------+-------+
	| no   | name     | sex  | classno | birth |
	+------+----------+------+---------+-------+
	| NULL | zhangsan | 1    | NULL    | NULL  |
	+------+----------+------+---------+-------+

	需要注意的地方:
		当一条insert语句执行成功之后,表格当中必然会多一行记录。
		即使多的这一行记录当中某些字段是NULL,后期也没有办法再执行insert语句插入数据了,只能使用update进行更新。
	
	// 字段可以省略不写,但是后面的value对数量和顺序都有要求。
	insert into t_student values(4, 'jack', '0', 'gaosan2ban', '1999-09-19');
	+------+------+------+------------+------------+
	| no   | name | sex  | classno    | birth      |
	+------+------+------+------------+------------+
	|    4 | jack | 0    | gaosan2ban | 1999-09-19 |
	+------+------+------+------------+------------+

	insert into t_student values(4, 'jack', '0', 'gaosan2ban');
	ERROR 1136 (21S01): Column count doesn't match value count at row 1
	
	// 一次插入多行数据
	insert into t_student
		(no, name, sex, classno, birth) 
	values
		(3, 'rose', '1', 'gaosi2ban', '1952-12-14'),
		(4, 'laotie', '1', 'gaosi2ban', '1995-12-14');
	+------+--------+------+------------+------------+
	| no   | name   | sex  | classno    | birth      |
	+------+--------+------+------------+------------+
	|    4 | jack   | 0    | gaosan2ban | 1999-09-19 |
	|    3 | rose   | 1    | gaosi2ban  | 1952-12-14 |
	|    4 | laotie | 1    | gaosi2ban  | 1995-12-14 |
	+------+--------+------+------------+------------+
	
8、表的复制
	语法:
		create table 表名 as select语句;
		将查询结果当做表创建出来。
		create table emp1 as select * from emp;

9、将查询结果插入到一张表中
	create talbe dept1 as select * from dept;
	insert into dept1 select * from dept;
	+--------+------------+----------+
	| DEPTNO | DNAME      | LOC      |
	+--------+------------+----------+
	|     10 | ACCOUNTING | NEW YORK |
	|     20 | RESEARCH   | DALLAS   |
	|     30 | SALES      | CHICAGO  |
	|     40 | OPERATIONS | BOSTON   |
	|     10 | ACCOUNTING | NEW YORK |
	|     20 | RESEARCH   | DALLAS   |
	|     30 | SALES      | CHICAGO  |
	|     40 | OPERATIONS | BOSTON   |
	+--------+------------+----------+

10、修改数据:update

	语法格式:
		update 表名 set 字段名1=值1, 字段名2=值2... where 条件;
	注意:没有条件整张表数据全部更新。
	
	案例:将部门10的LOC修改为SHAGNHAI,将部门名称修改为RENSHIBU
		update dept1 set loc = 'SHANGHAI', dname='RENSHIBU' where deptno = 10;
		+--------+------------+----------+
		| DEPTNO | DNAME      | LOC      |
		+--------+------------+----------+
		|     10 | RENSHIBU   | SHANGHAI |
		|     20 | RESEARCH   | DALLAS   |
		|     30 | SALES      | CHICAGO  |
		|     40 | OPERATIONS | BOSTON   |
		|     10 | RENSHIBU   | SHANGHAI |
		|     20 | RESEARCH   | DALLAS   |
		|     30 | SALES      | CHICAGO  |
		|     40 | OPERATIONS | BOSTON   |
		+--------+------------+----------+
	
	更新所有记录
		update dept1 set loc='x', dname='y';
		+--------+-------+------+
		| DEPTNO | DNAME | LOC  |
		+--------+-------+------+
		|     10 | y     | x    |
		|     20 | y     | x    |
		|     30 | y     | x    |
		|     40 | y     | x    |
		|     10 | y     | x    |
		|     20 | y     | x    |
		|     30 | y     | x    |
		|     40 | y     | x    |
		+--------+-------+------+
	
11、删除数据

	语法格式:
		delete from 表名 where 条件;
	注意:没有条件全部删除。
	
	删除10部门数据
		delete from dept1 where deptno = 10;
		+--------+-------+------+
		| DEPTNO | DNAME | LOC  |
		+--------+-------+------+
		|     20 | y     | x    |
		|     30 | y     | x    |
		|     40 | y     | x    |
		|     20 | y     | x    |
		|     30 | y     | x    |
		|     40 | y     | x    |
		+--------+-------+------+
		
	删除所有记录
		delete from dept1;
		Empty set (0.00 sec)
	
	怎么删除大表?(重点)
		truncate table 表名;// 表被截断,不可回滚。永久丢失。

12、对于表结构的修改,这里不讲了,大家使用工具完成即可,因为在实际开发中表一旦
设计好之后,对表结构的修改是很少的,修改表结构就是对之前的设计进行了否定,即使
需要修改表结构,我们也可以直接使用工具操作。修改表结构的语句不会出现在java代码当中。
出现在java代码当中的sql包括:insert delete update  select (这些都是表中的数据操作。)

增删改查有一个术语:CRUD操作
Create(增) Retrieve(检索) Update(修改) Delete(删除)

13、约束(Constraint)

13.1、什么是约束?常见的约束有哪些呢?
	在创建表的时候,可以给表的字段添加相应的约束,添加约束的目的是为了保证表中数据的
合法性、有效性、完整性。
	常见的约束有哪些呢?
		非空约束(not null):约束的字段不能为NULL
		唯一约束(unique):约束的字段不能重复
		主键约束(primary key):约束的字段既不能为NULL,也不能重复(简称PK)
		外键约束(foreign key):...(简称FK)
		检查约束(check):注意Oracle数据库有check约束,但是mysql没有,目前mysql不支持该约束。
	
13.2、非空约束 not null

	drop table if exists t_user;
	create table t_user(
		id int,
		username varchar(255) not null,
		password varchar(255)
	);
	
	insert into t_user(id,password) values(1,'123');
	ERROR 1364 (HY000): Field 'username' doesn't have a default value
	
	修改:
	insert into t_user(id,username,password) values(1,'lisi','123');
	
13.3、唯一性约束(unique)
	唯一约束修饰的字段具有唯一性,不能重复。但可以为NULL。NULL可以重复,因为NULL不是值。
	案例:给某一列添加unique 【列级约束】
		drop table if exists t_user;
		create table t_user(
			id int,
			username varchar(255) unique
		);
		insert into t_user values(1, 'zhangsan');
		insert into t_user values(2, 'zhangsan');
		ERROR 1062 (23000): Duplicate entry 'zhangsan' for key 'username'

		insert into t_user(id) values(2);
		insert into t_user(id) values(3);
		insert into t_user(id) values(4);
		+------+----------+
		| id   | username |
		+------+----------+
		|    1 | zhangsan |
		|    2 | NULL     |
		|    3 | NULL     |
		|    4 | NULL     |
		+------+----------+
		
	案例:给两个列或者多个列添加unique
		// unique(usercode, username) 多个字段联合起来添加1个约束unique【表级约束】
		drop table if exists t_user;
		create table t_user(
			id int,
			usercode varchar(255),
			username varchar(255),
			unique(usercode, username) 
		);
		insert  into t_user values(1, '111', 'zhangsan');
		insert  into t_user values(2, '111', 'lisi');
		insert  into t_user values(3, '111', 'zs');
		select * from t_user;
		+------+----------+----------+
		| id   | usercode | username |
		+------+----------+----------+
		|    1 | 111      | zhangsan |
		|    2 | 111      | lisi     |
		|    3 | 111      | zs       |
		+------+----------+----------+
		insert  into t_user values(4, '111', 'zs'); 
		ERROR 1062 (23000): Duplicate entry '111-zs' for key 'usercode
		
		区别上面联合添加约束unique:为【列级约束】
		drop table if exists t_user;
		create table t_user(
			id int,
			usercode varchar(255) unique,
			username varchar(255) unique
		);
		insert  into t_user values(1, '111', 'zhangsan');
		insert  into t_user values(2, '111', 'lisi');
		ERROR 1062 (23000): Duplicate entry '111' for key 'usercode'
		
		表级约束可以转换为列级约束:
			...
			usercode varchar(255),
			username varchar(255),
			unique(usercode),
			unique(username)
			...
		
		注意:not null约束只有列级约束,没有表级约束。

13.4、主键约束
	
	怎么给一张表添加主键约束呢?
		// id int primary key 【列级约束】
		drop table if exists t_user;
		create table t_user(
			id int primary key,
			username varchar(255),
			email varchar(255)
		);
		insert into t_user(id, username, email)   values(1, 'zs', '[email protected]');
		insert into t_user(id, username, email)   values(2, 'ls', '[email protected]');
		insert into t_user(id, username, email)   values(3, 'wu', '[email protected]');
		
		mysql> select * from t_user;
		+----+----------+------------+
		| id | username | email      |
		+----+----------+------------+
		|  1 | zs       | [email protected] |
		|  2 | ls       | [email protected] |
		|  3 | wu       | [email protected] |
		+----+----------+------------+
		
		insert into t_user(id, username, email)   values(1, 'jk', '[email protected]');
		ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
		
		insert into t_user(username, email)   values('jk', '[email protected]');
		ERROR 1364 (HY000): Field 'id' doesn't have a default value

		根据以上的测试得出:id是主键,因为添加了主键约束,主键字段中的数据不能为NULL,也不能重复。
		
	主键相关的术语?
		主键约束:primary key
		主键字段:id字段添加primary key之后,id叫做主键字段
		主键值:id字段中的每一个值都是主键值
	
	主键有什么用?
		表的设计三范式中有要求,第一范式就要求任何一张表都应该有主键。
		主键的作用:主键值是这行记录在这张表当中的唯一标识。(这就相当于一个人的身份证号码一样)
	
	主键的分类?
		根据主键字段的字段数量来划分:
			单一主键:推荐的,常用的。
			复合主键:多个字段联合起来添加一主键约束(不建议使用,违背三范式。)
		根据主键性质来划分:
			自然主键:主键值最好就是一个和业务没有任何关系的自然数。(推荐的)
			业务主键:主键值和系统的业务挂钩。例如:拿着银行卡的卡号做主键,拿着身份证号作为主键。(不推荐的)
				     最好不要拿着和业务挂钩的字段作为主键。因为以后的业务一旦发生改变的时候,主键值可能也
				     随着发生变化,但有的时候没有办法变化,因为变化的可能会导致主键值重复。
			
	一张表的主键约束只能由1个。(必须记住)
	使用表级约束方式定义主键:
		drop table if exists t_user;
		create table t_user(
			id int,
			username varchar(255),
			primary key(id)
		);
		insert into t_user(id, username) values(1, 'zs'); 
		insert into t_user(id, username) values(2, 'ls'); 
		insert into t_user(id, username) values(3, 'ws'); 
		insert into t_user(id, username) values(4, 'cs'); 
		select * from t_user;
		
		insert into t_user(id, username) values(4, 'cs'); 
		ERROR 1062 (23000): Duplicate entry '4' for key 'PRIMARY'
	
	以下内容是演示复合主键,不需要掌握
		drop table if exists t_user;
		create table t_user(
			id int,
			username varchar(255),
			password varchar(255),
			primary key(id,username)
		);
		insert ......
	
	mysql提供主键值自增:(非常重要。)
		drop table if exists t_user;
		create table t_user(
			id int primary key auto_increment, // id字段自动维护一个自增的数字,从1开始,以1递增。
			username varchar(255)
		);
		insert into t_user(username) values('a');
		insert into t_user(username) values('b');
		insert into t_user(username) values('c');
		insert into t_user(username) values('d');
		insert into t_user(username) values('e');
		insert into t_user(username) values('f');
		select * from t_user;
		+----+----------+
		| id | username |
		+----+----------+
		|  1 | a        |
		|  2 | b        |
		|  3 | c        |
		|  4 | d        |
		|  5 | e        |
		|  6 | f        |
		+----+----------+
		6 rows in set (0.00 sec)
	提示:Oracle当中也提供了一个自增机制,叫做:序列(sequence)对象。
	
13.5、外键约束
	关于外键约束的相关术语:
		外键约束:foreign key
		外键字段:添加有外键约束的字段
		外键值:外键字段中的每一个值。
	
	业务背景:
		请设计数据库表:用来维护学生和班级的信息?
		第一种方案:一张表存储所有数据
		no(pk)     name     classno     classname
		--------------------------------------------------------------------
		1          zs1      101         北京大兴区经济技术开发区亦庄二中高三1班
		2          zs2      101         北京大兴区经济技术开发区亦庄二中高三1班
		3          zs3      102         北京大兴区经济技术开发区亦庄二中高三2班
		4          zs4      102         北京大兴区经济技术开发区亦庄二中高三2班
		5          zs5      102         北京大兴区经济技术开发区亦庄二中高三2班
		缺点:冗余。【不推荐】
		
		第二种方案:两张表(班级表和学生表)
		t_class 班级表
		cno(pk)     cname
		---------------------------------------------------------------------
		101         北京大兴区经济技术开发区亦庄二中高三1班
		102         北京大兴区经济技术开发区亦庄二中高三2班
	
		t_student 学生表
		sno(pk)     sname      classsno(该字段添加外键约束fk)
		--------------------------------------------------------------------
		1           zs1        101
		2           zs2        101
		3           zs3        102
		4           zs4        102
		5           zs5        102
	
		将以上表的建表语句写出来;
		t_student中的classno字段引用t_class表中的cno字段,此时t_student表叫做子表,t_class叫做父表。
		顺序要求:
			删除数据的时候,先删除子表,再删除父表。
			添加数据的时候,先添加父表,再添加子表。
			删除表的时候,先删除子表,再删除父表。
			创建表的时候,先创建父表,再创建子表。
		
		drop table if exists t_student;
		drop table if exists t_class;
		create table t_class(
			cno int,
			cname varchar(255),
			primary key(cno)
		);
		create table t_student(
			sno int,
			sname varchar(255),
			classno int,
			primary key(sno),
			foreign key(classno) references t_class(cno) // references 引用
		);
		insert into t_class(cno, cname) values(101, 'xxxxxxxxxxxxxxxxxxx');
		insert into t_class(cno, cname) values(102, 'yyyyyyyyyyyyyyyyyyy');
		insert into t_student(sno, sname, classno) values(1, 'zs1', 101);
		insert into t_student(sno, sname, classno) values(2, 'zs2', 101);
		insert into t_student(sno, sname, classno) values(3, 'zs3', 101);
		insert into t_student(sno, sname, classno) values(4, 'zs4', 102);
		insert into t_student(sno, sname, classno) values(5, 'zs5', 102);
		insert into t_student(sno, sname, classno) values(6, 'zs6', 102);
		select * from t_class;
		select * from t_student;
		
		insert into t_student(sno, sname, classno) values(7, 'zs7', 103);
		ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails 
		(`bjpowernode`.`t_student`, CONSTRAINT `t_student_ibfk_1` FOREIGN KEY (`classno`) REFERENCES `t_class` (`cno`))

		外键值可以为NULL吗?
			外键值可以为NULL。
		insert into t_student(sno,sname) values(7, 'zs7');
		mysql> select * from t_student;
		+------+-------+---------+
		| sno  | sname | classno |
		+------+-------+---------+
		|    1 | zs1   |     101 |
		|    2 | zs2   |     101 |
		|    3 | zs3   |     101 |
		|    4 | zs4   |     102 |
		|    5 | zs5   |     102 |
		|    6 | zs6   |     102 |
		|    7 | zs7   |    NULL |
		+------+-------+---------+
	
		外键字段引用其他表的某个字段时候,被引用的字段必须是主键吗?
			注意: 被引用的字段不一定是主键,但至少具有unique约束。
*/

猜你喜欢

转载自blog.csdn.net/weixin_43636084/article/details/128222350