machinecat520 пре 2 година
родитељ
комит
eec5ac6b5b
3 измењених фајлова са 1523 додато и 1 уклоњено
  1. 605 0
      第十三章、约束.sql
  2. 867 0
      第十三章、练习题.sql
  3. 51 1
      第十二章、MySQL数据类型精讲.sql

+ 605 - 0
第十三章、约束.sql

@@ -0,0 +1,605 @@
+#第十三章、约束
+
+/*
+1、基础知识
+1.1、为什么需要约束?为了保证数据的完整性!
+
+1.2、什么叫约束?对表中字段的限制。
+
+1.3、约束的分类:
+
+角度1:约束的字段的个数
+单列约束 VS 多列约束
+
+角度2:约束的作用范围
+
+列级约束:将此约束声明在对应字段的后面
+表级约束:在表中所有字段都声明完,在所有字段的后面声明的约束
+
+角度3:约束的作用(或功能)
+
+(1)not null(非空约束)
+(2)unique(唯一性约束)
+(3)primary key(主键约束)
+(4)foreign key(外键约束)
+(5)check(检查约束)
+(6)default(默认值约束)
+
+1.4、如何添加/删除约束?
+
+CREATE TABLE 时添加约束
+
+ALTER TABLE 时增加约束、删除约束
+
+
+*/
+
+#2、如何查看表中的约束
+SELECT * FROM information_schema.TABLE_CONSTRAINTS
+WHERE table_name = '表名称';
+
+SELECT * FROM information_schema.TABLE_CONSTRAINTS
+WHERE table_name = 'employees';
+
+CREATE DATABASE dbtest13;
+
+USE dbtest13;
+
+#3、not null(非空约束)
+#3.1、在CREATE TABLE时添加约束
+CREATE TABLE test1(
+id INT NOT NULL,
+last_name VARCHAR(15) NOT NULL,
+email VARCHAR(25),
+salary DECIMAL(10,2)
+);
+
+DESC test1;
+
+SELECT * FROM information_schema.TABLE_CONSTRAINTS
+WHERE table_name = 'test1';
+
+INSERT INTO test1(id,last_name,email,salary)
+VALUES(1,'Tom','Tom@126.com',3400);
+
+#Column 'last_name' cannot be null
+INSERT INTO test1(id,last_name,email,salary)
+VALUES(2,NULL,'Tom@126.com',3400);
+
+#Column 'id' cannot be null
+INSERT INTO test1(id,last_name,email,salary)
+VALUES(NULL,'Jerry','Jerry@126.com',3400);
+
+INSERT INTO test1(id,email)
+VALUES(2,'abc@126.com');
+
+UPDATE test1
+SET email = NULL
+WHERE id = 1;
+
+UPDATE test1
+SET last_name = NULL
+WHERE id = 1;
+
+UPDATE test1
+SET email = 'Tom@126.com'
+WHERE id = 1;
+
+#3.2、在ALTER TABLE时添加约束
+ALTER TABLE test1
+MODIFY email VARCHAR(25) NOT NULL;
+
+DESC test1;
+
+#3.3、在ALTER TABLE时删除约束
+ALTER TABLE test1
+MODIFY email VARCHAR(25) NULL;
+
+#4、unique(唯一性约束)
+#4.1、在CREATE TABLE时添加约束
+CREATE TABLE test2(
+id INT UNIQUE,	#列级约束
+last_name VARCHAR(15),
+email VARCHAR(25),
+salary DECIMAL(10,2),
+#表级约束
+CONSTRAINT uk_test2_email UNIQUE(email)
+);
+
+DESC test2;
+
+SELECT * FROM information_schema.TABLE_CONSTRAINTS
+WHERE table_name = 'test2';
+
+#在创建唯一约束的时候,如果不给唯一约束命名,就默认和列名相同。
+
+INSERT INTO test2(id,last_name,email,salary)
+VALUES(1,'Tom','Tom@126.com',4500);
+
+#错误:Duplicate entry '1' for key 'test2.id'
+INSERT INTO test2(id,last_name,email,salary)
+VALUES(1,'Tom1','Tom1@126.com',4600);
+
+#错误:Duplicate entry 'Tom@126.com' for key 'test2.uk_test2_email'
+INSERT INTO test2(id,last_name,email,salary)
+VALUES(2,'Tom1','Tom@126.com',4600);
+
+#可以向声明为UNIQUE的字段上添加NULL值。
+INSERT INTO test2(id,last_name,email,salary)
+VALUES(2,'Tom1',NULL,4600);
+
+INSERT INTO test2(id,last_name,email,salary)
+VALUES(3,'Tom2',NULL,4600);
+
+SELECT * FROM test2;
+
+#4.2、在ALTER TABLE时添加约束
+DESC test2;
+
+UPDATE test2
+SET salary = 5000
+WHERE id = 3;
+
+#方式一
+ALTER TABLE test2
+ADD CONSTRAINT uk_test2_sal UNIQUE(salary);
+
+#方式二
+ALTER TABLE test2
+MODIFY last_name VARCHAR(15) UNIQUE;
+
+#4.3、复合的唯一性约束
+CREATE TABLE USER(
+id INT,
+`name` VARCHAR(15),
+`password` VARCHAR(25),
+CONSTRAINT uk_user_name_ped UNIQUE(`name`,`password`)
+);
+
+INSERT INTO USER
+VALUES(1,'Tom','abc');
+
+#可以添加成功
+INSERT INTO USER
+VALUES(1,'Tom1','abc');
+
+SELECT * FROM USER;
+
+#案例:复合的唯一性约束的案例
+#学生表
+CREATE TABLE student(
+sid INT,	#学号
+sname VARCHAR(20),	#姓名
+tel CHAR(11),	#电话
+cardid CHAR(18)	#身份证号
+);
+
+#课程表
+CREATE TABLE course(
+cid INT,	#课程编号
+cname VARCHAR(20)		#课程名称
+);
+
+#选课表
+CREATE TABLE student_course(
+id INT,
+sid INT,	#学号
+cid INT,	#课程编号
+score INT,
+UNIQUE KEY(sid,cid)		#复合唯一
+);
+
+INSERT INTO student
+VALUES(1,'张三','13710011002','101223199012015623');
+INSERT INTO student
+VALUES(2,'李四','13710011003','101223199012015624');
+
+INSERT INTO course
+VALUES(1001,'Java'),('1002','MySQL');
+
+SELECT * FROM student;
+SELECT * FROM course;
+
+INSERT INTO student_course VALUES
+(1,1,1001,89),
+(2,1,1002,90),
+(3,2,1001,88),
+(4,2,1002,56);
+
+SELECT * FROM student_course;
+
+#错误:Duplicate entry '2-1002' for key 'student_course.sid'
+INSERT INTO student_course VALUES
+(5,2,1002,67);
+
+#4.4、删除唯一性约束
+-- 	添加唯一性约束的列上也会自动创建唯一索引。
+-- 	删除唯一约束只能通过删除唯一索引的方式删除。
+-- 	删除时需要指定唯一索引名,唯一索引名就和唯一约束名一样。
+-- 	如果创建唯一约束时未指定名称,如果是单列,就默认和列名相同;如果是组合列,那么默认和()中排在第一个的列名相同。也可以自定义唯一性约束名。
+
+SELECT * FROM information_schema.TABLE_CONSTRAINTS
+WHERE table_name = 'test2';
+
+DESC test2;
+
+#如何删除唯一性索引
+ALTER TABLE test2
+DROP INDEX last_name;
+
+ALTER TABLE test2
+DROP INDEX uk_test2_sal;
+
+SHOW INDEX FROM test2;
+
+#5、primary key(主键约束)
+#5.1、在CREATE TABLE时添加约束
+#一个表中最多只能有一个主键约束
+
+#错误:Multiple primary key defined
+CREATE TABLE test3(
+id INT PRIMARY KEY,		#列级约束
+last_name VARCHAR(15) PRIMARY KEY,
+salary DECIMAL(10,2),
+email VARCHAR(25)
+);
+
+#主键约束特征:非空且唯一,用于唯一的标识表中的一条记录。
+CREATE TABLE test4(
+id INT PRIMARY KEY,		#列级约束
+last_name VARCHAR(15),
+salary DECIMAL(10,2),
+email VARCHAR(25)
+);
+
+#MySQL的主键名总是PRIMARY,就算自己命名了主键约束名也没用
+CREATE TABLE test5(
+id INT,
+last_name VARCHAR(15),
+salary DECIMAL(10,2),
+email VARCHAR(25),
+#表级约束
+CONSTRAINT pk_test5_id PRIMARY KEY(id)	#没有必要起名字
+);
+
+SELECT* FROM information_schema.TABLE_CONSTRAINTS
+WHERE table_name = 'test5';
+
+INSERT INTO test4(id,last_name,salary,email)
+VALUES(1,'Tom',4500,'Tom@126.com');
+
+INSERT INTO test4(id,last_name,salary,email)
+VALUES(1,'Tom1',4600,'Tom1@126.com');
+
+INSERT INTO test4(id,last_name,salary,email)
+VALUES(NULL,'Tom2',4700,'Tom2@126.com');
+
+#如果是多列组合的复合主键约束,那么这些列都不允许为空值,并且组合的值不允许重复
+CREATE TABLE user1(
+id INT,
+name VARCHAR(15),
+password VARCHAR(25),
+PRIMARY KEY(name,password)
+);
+
+INSERT INTO user1
+VALUES(1,'Tom','abc');
+
+INSERT INTO user1
+VALUES(1,'Tom1','abc');
+
+#错误:Column 'name' cannot be null
+INSERT INTO user1
+VALUES(1,NULL,'abc');
+
+SELECT * FROM user1;
+
+#5.2、在ALTER TABLE时添加约束
+CREATE TABLE test6(
+id INT,
+last_name VARCHAR(15),
+salary DECIMAL(10,2),
+email VARCHAR(25)
+);
+
+ALTER TABLE test6
+ADD PRIMARY KEY(id);
+
+DESC test6;
+
+#5.3、如何删除主键约束(实际开发中,不会去删除表中的主键约束!)
+ALTER TABLE test6
+DROP PRIMARY KEY;
+
+#6、自增长列:AUTO_INCREMENT
+#6.1、在CREATE TABLE时添加
+#错误情况一:
+CREATE TABLE test7(
+id INT AUTO_INCREMENT,
+last_name VARCHAR(15)
+);
+#错误情况二
+CREATE TABLE test7(
+id INT,
+last_name VARCHAR(15) UNIQUE AUTO_INCREMENT
+);
+
+#正确的
+CREATE TABLE test7(
+id INT PRIMARY KEY AUTO_INCREMENT,
+last_name VARCHAR(15)
+);
+
+#开发中,一旦主键作用的字段上声明有AUTO_INCREMENT,则我们在添加数据时,就不要给主键对应的字段去赋值了。
+INSERT INTO test7(last_name)
+VALUES('Tom');
+
+SELECT * FROM test7;
+
+#当我们向主键(含AUTO_INCREMENT)的字段上添加0或NULL时,实际上会自动的往上添加指定的字段的数值
+INSERT INTO test7(id,last_name)
+VALUES(0,'Tom');
+
+INSERT INTO test7(id,last_name)
+VALUES(NULL,'Tom');
+
+INSERT INTO test7(id,last_name)
+VALUES(10,'Tom');
+
+INSERT INTO test7(id,last_name)
+VALUES(-10,'Tom');
+
+#6.2、在ALTER TABLE时添加
+CREATE TABLE test8(
+id INT PRIMARY KEY,
+last_name VARCHAR(15)
+);
+
+DESC test8;
+
+ALTER TABLE test8
+MODIFY id INT AUTO_INCREMENT;
+
+#6.2、在ALTER TABLE时删除
+ALTER TABLE test8
+MODIFY id INT;
+
+#6.3、MySQL8.0新特性——自增变量的持久化
+CREATE TABLE test9(
+id INT PRIMARY KEY AUTO_INCREMENT
+);
+
+INSERT INTO test9
+VALUES(0),(0),(0),(0);
+
+SELECT * FROM test9;
+
+DELETE FROM test9
+WHERE id = 4;
+
+INSERT INTO test9
+VALUES(0);
+
+DELETE FROM test9
+WHERE id = 5;
+
+#重启服务器
+SELECT * FROM test9;
+
+INSERT INTO test9
+VALUES(0);
+
+INSERT INTO test9
+VALUES(5);
+
+#7、foreign key(外键约束)
+#7.1、在ALTER TABLE时添加
+
+#主表和从表:父表和子表
+
+#(1)先创建主表
+CREATE TABLE dept1(
+dept_id INT,
+dept_name VARCHAR(15)
+);
+
+#(2)再创建从表
+CREATE TABLE emp1(
+emp_id INT PRIMARY KEY AUTO_INCREMENT,
+emp_name VARCHAR(15),
+department_id INT,
+
+#表级约束
+CONSTRAINT fk_emp1_dept_id FOREIGN KEY(department_id) REFERENCES dept1(dept_id)
+);
+
+#上述操作报错,因为主表中的dept_id上没有主键约束或唯一性约束。
+#(3)添加
+ALTER TABLE dept1
+ADD PRIMARY KEY(dept_id);
+
+DESC dept1;
+
+#(4)再创建从表
+CREATE TABLE emp1(
+emp_id INT PRIMARY KEY AUTO_INCREMENT,
+emp_name VARCHAR(15),
+department_id INT,
+
+#表级约束
+CONSTRAINT fk_emp1_dept_id FOREIGN KEY(department_id) REFERENCES dept1(dept_id)
+);
+
+DESC emp1;
+
+SELECT * FROM information_schema.TABLE_CONSTRAINTS
+WHERE table_name = 'emp1';
+
+#7.2、演示外键的效果
+#添加失败
+INSERT INTO emp1
+VALUES(1001,'Tom',10);
+
+INSERT INTO dept1
+VALUES(10,'IT');
+
+#在主表dept1中添加了10号部门以后,我们就可以在从表在添加10号部门的员工
+INSERT INTO emp1
+VALUES(1001,'Tom',10);
+
+#删除失败
+DELETE FROM dept1
+WHERE dept_id = 10;
+
+#更新失败
+UPDATE dept1
+SET dept_id = 20
+WHERE dept_id = 10;
+
+#7.3、在ALTER TABLE时添加外键约束
+CREATE TABLE dept2(
+dept_id INT PRIMARY KEY,
+dept_name VARCHAR(15)
+);
+
+CREATE TABLE emp2(
+emp_id INT PRIMARY KEY AUTO_INCREMENT,
+emp_name VARCHAR(15),
+department_id INT
+);
+
+ALTER TABLE emp2
+ADD CONSTRAINT fk_emp2_dept_id FOREIGN KEY(department_id) REFERENCES dept2(dept_id);
+
+SELECT * FROM information_schema.TABLE_CONSTRAINTS
+WHERE table_name = 'emp2';
+
+#7.4、约束等级
+-- 	Cascade方式:在父表上update/delete记录时,同步update/delete掉子表的匹配记录
+-- Set null方式:在父表上update/delete记录时,将子表上匹配记录的列设为null,
+-- 但是要注意子表的外键列不能为not null
+-- No action方式:如果子表中有匹配的记录,则不允许对父表对应候选键
+-- 进行update/delete操作
+-- Restrict方式:同no action,都是立即检查外键约束
+-- Set default方式(在可视化工具SQLyog中可能显示空白):父表有变更时,
+-- 子表将外键列设置成一个默认的值,但InnoDB不能识别
+
+#演示:ON UPDATE CASCADE ON DELETE RESTRICT
+
+CREATE TABLE dept(
+did INT PRIMARY KEY,	#部门编号
+dname VARCHAR(50)			#部门名称
+);
+
+CREATE TABLE emp(
+eid INT PRIMARY KEY,	#员工编号
+ename VARCHAR(5),			#员工姓名
+deptid INT,						#员工所在部门
+FOREIGN KEY(deptid) REFERENCES dept(did) ON UPDATE CASCADE ON DELETE SET NULL
+#把修改操作设置为级联修改等级,把删除操作设置为set null等级
+);
+
+INSERT INTO dept VALUES(1001,'教学部');
+INSERT INTO dept VALUES(1002,'财务部');
+INSERT INTO dept VALUES(1003,'咨询部');
+
+INSERT INTO emp VALUES(1,'张三',1001);
+INSERT INTO emp VALUES(2,'李四',1001);
+INSERT INTO emp VALUES(3,'王五',1002);
+
+UPDATE dept
+SET did = 1004
+WHERE did = 1002;
+
+DELETE FROM dept
+WHERE did = 1004;
+
+SELECT * FROM dept;
+
+SELECT * FROM emp;
+
+#结论:对于外键约束,最好是采用:ON UPDATE CASCADE ON DELETE RESTRICT的方式。
+
+#7.5、删除外键约束
+#一个表中可以声明有多个外键约束
+SELECT * FROM information_schema.TABLE_CONSTRAINTS
+WHERE table_name = 'emp1';
+
+#删除外键约束
+ALTER TABLE emp1
+DROP FOREIGN KEY fk_emp1_dept_id;
+
+#再手动的删除外键约束对应的普通索引
+SHOW INDEX FROM emp1;
+
+ALTER TABLE emp1
+DROP INDEX fk_emp1_dept_id;
+
+#8、check约束
+#MySQL5.7 不支持CHECK约束,MySQL8.0 支持CHECK约束
+
+CREATE TABLE test10(
+id INT,
+last_name VARCHAR(15),
+salary DECIMAL(10,2) CHECK(salary > 2000)
+);
+
+INSERT INTO test10
+VALUES(1,'Tom',2500);
+
+#添加失败
+INSERT INTO test10
+VALUES(2,'Tom1',1500);
+
+SELECT * FROM test10;
+
+#9、DEFAULT约束
+#9.1、在CREATE TABLE添加约束
+CREATE TABLE test11(
+id INT,
+last_name VARCHAR(15),
+salary DECIMAL(10,2) DEFAULT 2000
+);
+
+DESC test11;
+
+INSERT INTO test11(id,last_name,salary)
+VALUES(1,'Tom',3000);
+
+INSERT INTO test11(id,last_name)
+VALUES(2,'Tom');
+
+SELECT * FROM test11;
+
+#9.2、在ALTER TABLE添加约束
+CREATE TABLE test12(
+id INT,
+last_name VARCHAR(15),
+salary DECIMAL(10,2)
+);
+
+DESC test12;
+
+ALTER TABLE test12
+MODIFY salary DECIMAL(8,2) DEFAULT 2500;
+
+#9.3、在ALTER TABLE删除约束
+ALTER TABLE test12
+MODIFY salary DECIMAL(8,2);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 867 - 0
第十三章、练习题.sql

@@ -0,0 +1,867 @@
+#第十三章、练习题
+
+#基础练习
+#练习1
+#已经存在数据库test04_emp,两张表emp2和dept2
+CREATE DATABASE test04_emp;
+
+USE test04_emp;
+
+CREATE TABLE emp2(
+id INT,
+emp_name VARCHAR(15)
+);
+
+CREATE TABLE dept2(
+id INT,
+dept_name VARCHAR(15)
+);
+
+#题目:
+#1、向表emp2的id列中添加PRIMARY KEY约束
+ALTER TABLE emp2
+ADD PRIMARY KEY(id);
+
+#2、向表dept2的id列中添加PRIMARY KEY约束
+ALTER TABLE dept2
+ADD PRIMARY KEY(id);
+
+#3、向表emp2中添加列dept_id,并在其中定义FOREIGN KEY约束,与之向关联的列是dept2表中的id列
+ALTER TABLE emp2
+ADD dept_id INT;
+
+DESC emp2;
+
+ALTER TABLE emp2
+ADD CONSTRAINT fk_emp2_deptid FOREIGN KEY (dept_id) REFERENCES dept2(id);
+
+######################################################################
+
+#练习2
+#承接《第11章_数据处理之增删改》的综合案例
+#1、创建数据库test01_library
+
+#2、创建表books,表结构如下:
+/*
+		字段名					字段说明				数据类型
+		id 							书编号					INT
+		name 						书名						VARCHAR(50)
+		authors 				作者						VARCHAR(100)
+		price 					价格						FLOAT
+		pubdate					出版日期				YEAR
+		note 						说明						VARCHAR(100)
+		num 						库存						INT
+*/
+#数据库在第11章时已经创建,第1题和第2题可直接使用
+USE test01_library;
+
+DESC books;
+
+#3、使用ALTER语句给books按如下要求增加相应的约束
+/*
+		字段名			字段说明		数据类型			主键	外键	非空	唯一	自增
+		id 					书编号			INT(11)				是		否		是		是		是
+		name 				书名				VARCHAR(50)		否		否		是		否		否
+		authors 		作者				VARCHAR(100)	否		否		是		否		否
+		price 			价格				FLOAT					否		否		是		否		否
+		pubdate			出版日期		YEAR					否		否		是		否		否
+		note 				说明				VARCHAR(100)	否		否		否		否		否
+		num 				库存				INT(11)				否		否		是		否		否
+*/
+#为id字段添加约束
+#方式一(我做的)
+ALTER TABLE books
+ADD PRIMARY KEY(id);
+ALTER TABLE books
+MODIFY id INT AUTO_INCREMENT;
+
+#方式二(老师讲的另一种方法)
+ALTER TABLE books
+MODIFY id INT PRIMARY KEY AUTO_INCREMENT;
+
+#为name字段添加约束
+ALTER TABLE books
+MODIFY name VARCHAR(50) NOT NULL;
+
+#为authors字段添加约束
+ALTER TABLE books
+MODIFY authors VARCHAR(100) NOT NULL;
+
+#为price字段添加约束
+ALTER TABLE books
+MODIFY price FLOAT NOT NULL;
+
+#为pubdate字段添加约束
+ALTER TABLE books
+MODIFY pubdate YEAR	NOT NULL;
+
+#为num字段添加约束
+ALTER TABLE books
+MODIFY num INT NOT NULL;
+
+DESC books;
+
+######################################################################
+
+#练习3
+#题目
+#1、创建数据库test04_company
+CREATE DATABASE IF NOT EXISTS test04_company;
+
+USE test04_company;
+
+#2、按照下表给出的表结构在test04_company数据库中创建两个数据表offices和employees
+#offices表:
+/*
+		字段名			数据类型			主键	外键	非空	唯一	自增
+		officeCode	INT(10)				是		否		是		是		否
+		city				VARCHAR(50)		否		否		是		否		否
+		address			VARCHAR(50)		否		否		否		否		否
+		country 		VARCHAR(50)		否		否		是		否		否
+		postalCode 	VARCHAR(15)		否		否		否		是		否
+*/
+#employees表:
+/*
+		字段名						数据类型			主键	外键	非空	唯一	自增
+		employeeNumber		INT(11)				是		否		是		是		是
+		lastName 					VARCHAR(50)		否		否		是		否		否
+		firstName 				VARCHAR(50)		否		否		是		否		否
+		mobile						VARCHAR(25)		否		否		否		是		否
+		officeCode 				INT(10)				否		是		是		否		否
+		jobTitle 					VARCHAR(50)		否		否		是		否		否
+		birth							DATETIME 			否		否		是		否		否
+		note 							VARCHAR(255)	否		否		否		否		否
+		sex 							VARCHAR(5)		否		否		否		否		否
+*/
+CREATE TABLE IF NOT EXISTS offices(
+officeCode INT PRIMARY KEY,		#老师写的:officeCode INT(10) PRIMARY KEY,
+city VARCHAR(50)	NOT NULL,
+address VARCHAR(50),
+country VARCHAR(50) NOT NULL,
+postalCode VARCHAR(15) UNIQUE
+);
+
+DESC offices;
+
+CREATE TABLE IF NOT EXISTS employees(
+employeeNumber INT PRIMARY KEY AUTO_INCREMENT,
+lastName VARCHAR(50) NOT NULL,
+firstName VARCHAR(50) NOT NULL,
+mobile VARCHAR(25) UNIQUE,
+officeCode INT NOT NULL,
+jobTitle VARCHAR(50) NOT NULL,
+birth DATETIME NOT NULL,
+note VARCHAR(255),
+sex VARCHAR(5),
+CONSTRAINT fk_emp_offcode FOREIGN KEY(officeCode) REFERENCES offices(officeCode)
+);
+
+DESC employees;
+
+#3、将表employees的mobile字段修改到officeCode字段后面
+ALTER TABLE employees
+MODIFY mobile VARCHAR(25) AFTER officeCode;
+
+#4、将表employees的birth字段名改为employee_birth
+ALTER TABLE employees
+CHANGE birth employee_birth DATETIME;
+
+#5、修改sex字段,数据类型为CHAR(1),非空约束
+ALTER TABLE employees
+MODIFY sex CHAR(1) NOT NULL;
+
+#6、删除字段note
+ALTER TABLE employees
+DROP COLUMN note;
+
+#7、增加字段名favoriate_activity,数据类型为VARCHAR(100)
+ALTER TABLE employees
+ADD favoriate_activity VARCHAR(100);
+
+#8、将表employees名称修改为employees_info
+RENAME TABLE employees
+TO employees_info;
+
+DESC employees_info;
+
+######################################################################
+
+#拓展练习
+#练习1
+#创建数据库test04_Market,在test04_Market中创建数据表customers。
+#customers表结构如下所示,按以下要求进行操作。
+/*
+		字段名			数据类型			主键	外键	非空	唯一	自增
+		c_num 			INT(11)				是		否		是		是		是
+		c_name 			VARCHAR(50)		否		否		否		否		否
+		c_contact 	VARCHAR(50)		否		否		否		否		否
+		c_city 			VARCHAR(50)		否		否		否		否		否
+		c_birth 		DATETIME 			否		否		是		否		否
+*/
+#1、创建数据库test04_Market。
+CREATE DATABASE test04_Market;
+
+USE test04_Market;
+
+#2、创建数据表customers,在c_num字段上添加主键约束和自增约束,在c_birth字段上添加非空约束。
+CREATE TABLE customers(
+c_num INT PRIMARY KEY AUTO_INCREMENT,
+c_name VARCHAR(50),
+c_contact VARCHAR(50),
+c_city VARCHAR(50),
+c_birth DATETIME NOT NULL
+);
+
+DESC customers;
+
+#3、将c_contact字段插入c_birth字段后面。
+ALTER TABLE customers
+MODIFY c_contact VARCHAR(50) AFTER c_birth;
+
+#4、将c_name字段数据类型改为VARCHAR(70)。
+ALTER TABLE customers
+MODIFY c_name VARCHAR(70);
+
+#5、将c_contact字段改名为c_phone。
+ALTER TABLE customers
+CHANGE c_contact c_phone VARCHAR(50);
+
+#6、增加c_gender字段,数据类型为CHAR(1)。
+ALTER TABLE customers
+ADD COLUMN c_gender CHAR(1);
+
+#7、将表名修改为customers_info。
+RENAME TABLE customers
+TO customers_info;
+
+DESC customers_info;
+
+#8、删除字段c_city。
+ALTER TABLE customers_info
+DROP c_city;
+
+
+#在test04_Market中创建数据表orders。orders表结构如下所示,按以下要求进行操作。
+/*
+		字段名		数据类型		主键	外键	非空	唯一	自增
+		o_num			INT(11)			是		否		是		是		是
+		o_date 		DATE 				否		否		否		否		否
+		c_id 			INT(11)			否		是		否		否		否
+*/
+#1、创建数据表orders,在o_num字段上添加主键约束和自增约束,在c_id字段上添加外键约束,关联customers表中的主键c_num。
+CREATE TABLE IF NOT EXISTS orders(
+o_num INT PRIMARY KEY AUTO_INCREMENT,
+o_date	DATE,
+c_id INT,
+CONSTRAINT fk_orders_c_id FOREIGN KEY(c_id) REFERENCES customers_info(c_num)
+);
+
+DESC orders;
+
+#2、删除orders表的外键约束,然后删除表customers。
+#查看约束信息,主要是查看外键约束名
+SELECT * FROM information_schema.TABLE_CONSTRAINTS
+WHERE table_name = 'orders';
+#删除外键约束
+ALTER TABLE orders
+DROP FOREIGN KEY fk_orders_c_id;
+#查看索引名
+SHOW INDEX FROM orders;
+#删除索引
+ALTER TABLE orders
+DROP INDEX fk_orders_c_id;
+
+######################################################################
+
+#练习2
+#创建数据表pet,并对表进行插入、更新与删除操作。pet表结构如下所示。
+#pet表结构
+/*
+		字段名		字段说明		数据类型			主键	外键	非空	唯一	自增
+		name 			宠物名称		ARCHAR(20)		否		否		是		否		否
+		owner 		宠物主人		ARCHAR(20)		否		否		否		否		否
+		species		种类				ARCHAR(20)		否		否		是		否		否
+		sex				性别				CHAR(1)				否		否		是		否		否
+		birth			出生日期		YEAR 					否		否		是		否		否
+		death			死亡日期		TEAR					否		否		否		否		否
+*/
+#pet表中记录
+/*
+		name 			owner 		species		sex 	birth		death
+		Fluffiy		Harold		cat 			f 		2003 		2010
+		Claws			Gwen			cat 			m  		2004 		NULL
+		Buffiy		NULL			dog				f 		2009		NULL
+		Fang			Benny			dog				m 		2000		NULL		
+		Bowser		Diane			dog				m 		2003		2009
+		Chirpy		NULL 			bird			f 		2008		NULL
+*/
+#1、首先创建数据表pet,使用不同的方法将表记录插入到pet表中。
+#创建表
+CREATE TABLE pet(
+`name` VARCHAR(20) NOT NULL,
+`owner` VARCHAR(20),
+species VARCHAR(20) NOT NULL,
+sex CHAR(1) NOT NULL,
+birth YEAR NOT NULL,
+death YEAR
+);
+
+DESC pet;
+
+#向表中插入数据
+INSERT INTO pet(name,owner,species,sex,birth,death)
+VALUES('Fluffiy','Harold','cat','f','2003','2010');
+
+INSERT INTO pet VALUES
+('Claws','Gwen','cat','m','2004',NULL),
+('Buffiy',NULL,'dog','f','2009',NULL),
+('Fang','Benny','dog','m','2000',NULL),
+('Bowser','Diane','dog','m','2003',2009),
+('Chirpy',NULL,'bird','f','2008',NULL);
+
+SELECT * FROM pet;
+
+#2、使用UPDATE语句将名称为Fang的狗的主人改为Kevin。
+UPDATE pet
+SET owner = 'Kevin'
+WHERE name = 'Fang';
+
+#3、将没有主人的宠物owner字段值都改为Duck。
+UPDATE pet
+SET owner = 'Duck'
+WHERE owner IS NULL;
+
+#4、删除已死亡的宠物记录。
+DELETE FROM pet
+WHERE death IS NOT NULL;
+
+#5、删除所有表中的记录。
+DELETE FROM pet;
+
+SELECT * FROM pet;
+
+######################################################################
+
+#练习3
+#1、创建数据库:test_company
+CREATE DATABASE IF NOT EXISTS test_company;
+
+USE test_company;
+
+#2、在此数据库下创建如下3表,数据类型,宽度,是否为空根据实际情况自己定义。
+/*
+	A、部门表(department):部门编号(depid)。部门名称(depname)。
+	部门简介(depinfo);其中部门编号为主键。
+	B、雇员表(employee):雇员编号(empid),姓名(name),性别(sex),
+	职称(title),出生日期(birthday),所在部门编号(depid);其中:
+	雇员编号为主键;
+	部门编号为外键,外键约束等级为(on update cascade和on delete set null);
+	性别默认为男;
+	C、工资表(salary):雇员编号(empid),基本工资(basesalary),职务
+	工资(titlesalary),扣除(deduction)。其中雇员编号为主键。
+*/
+#部门表
+CREATE TABLE department(
+depid INT,
+depname VARCHAR(20) NOT NULL,
+depinfo VARCHAR(50),
+PRIMARY KEY(depid)
+);
+
+DESC department;
+
+#雇员表
+CREATE TABLE employee(
+empid INT PRIMARY KEY,
+name VARCHAR(20) NOT NULL,
+sex CHAR(1) NOT NULL DEFAULT '男',
+title VARCHAR(15),
+birthday DATE NOT NULL,
+depid INT,
+CONSTRAINT fk_emp_depid FOREIGN KEY(depid) REFERENCES department(depid) ON UPDATE CASCADE ON DELETE SET NULL
+);
+
+DESC employee;
+
+#工资表
+CREATE TABLE salary(
+empid INT PRIMARY KEY,
+basesalary DECIMAL(10,2),
+titlesalary DECIMAL(10,2),
+deduction DECIMAL(10,2)
+);
+
+DESC salary;
+
+#3、给工资表(salary)的雇员编号(empid)增加外键约束,外键约束等级为
+#(on update cascade和on delete cascade)
+ALTER TABLE salary
+ADD CONSTRAINT fk_sal_empid FOREIGN KEY(empid) REFERENCES employee(empid) ON UPDATE CASCADE ON DELETE CASCADE;
+
+#4、添加数据如下:
+#部门表:
+/*
+		部门编号		部门名称		部门简介
+		111					生产部			NULL
+		222					销售部			NULL
+		333					人事部			人力资源管理
+*/
+#雇员表:
+/*
+	雇员编号		姓名		性别		职称					出生日期		所在部门编号
+	1001				张三		男			高级工程师		1975-1-1		111
+	1002				李四		女			助工					1985-1-1		111
+	1003				王五		男			工程师				1978-11-11	222
+	1004				张六		男			工程师				1999-1-1		222
+*/	
+#工资表:
+/*
+		雇员编号		基本工资		职务工资		扣除
+		1001				2200				1100				200
+		1002				1200				200					NULL
+		1003				2900				700					200
+		1004				1950				700					150
+*/
+#添加部门表数据
+INSERT INTO department VALUES
+(111,'生产部',NULL),
+(222,'销售部',NULL),
+(333,'人事部','人力资源管理');
+
+SELECT * FROM department;
+
+#添加雇员表数据
+INSERT INTO employee VALUES
+(1001,'张三',DEFAULT,'高级工程师','1975-1-1',111),
+(1002,'李四','女','助工','1985-1-1',111),
+(1003,'王五','男','工程师','1978-11-11',222),
+(1004,'张六',DEFAULT,'工程师','1999-1-1',222);
+
+SELECT * FROM employee;
+
+#添加工资表数据
+INSERT INTO salary VALUES
+(1001,2200,1100,200),
+(1002,1200,200,NULL),
+(1003,2900,700,200),
+(1004,1950,700,150);
+
+SELECT * FROM salary;
+
+#5、查询出每个雇员的雇员编号、姓名、职称、所在部门名称、应发工资(基本工资+职务工资),实发工资(基本工资+职务工资-扣除)
+SELECT emp.empid,emp.name,emp.title,dep.depname,sal.basesalary+sal.titlesalary AS '应发工资',sal.basesalary+sal.titlesalary-IFNULL(sal.deduction,0) AS '实发工资'
+FROM employee AS emp JOIN department dep JOIN salary AS sal
+ON emp.depid = dep.depid AND emp.empid = sal.empid;
+
+#6、查询销售部门的雇员姓名及其基本工资
+SELECT emp.name,sal.basesalary
+FROM department dep JOIN employee emp JOIN salary sal
+ON dep.depid = emp.depid AND emp.empid = sal.empid
+WHERE dep.depname = '销售部';
+
+#7、查询姓“张”且年龄小于40的员工的全部信息和年龄
+SELECT *,YEAR(NOW())-YEAR(birthday) AS '年龄'
+FROM employee
+WHERE name LIKE '张%' AND (YEAR(NOW())-YEAR(birthday)) < 40;
+
+#8、查询所有男员工的基本工资和职务工资
+SELECT * FROM employee;
+
+SELECT emp.empid,emp.name,sal.basesalary,sal.titlesalary
+FROM employee emp JOIN salary sal
+ON emp.empid = sal.empid
+WHERE emp.sex = '男';
+
+#9、查询基本工资低于2000的员工姓名和职称、所在部门名称
+SELECT emp.name,emp.title,dep.depname
+FROM department dep JOIN employee emp JOIN salary sal
+ON dep.depid = emp.depid AND emp.empid = sal.empid
+WHERE sal.basesalary < 2000;
+
+#10、查询员工总数
+SELECT COUNT(*)
+FROM employee;
+
+#11、查询部门总数
+SELECT COUNT(*)
+FROM department;
+
+#12、查询应发工资的平均工资和最高工资、最低工资
+SELECT AVG(basesalary+titlesalary) AS '平均工资',MAX(basesalary+titlesalary) AS '最高工资',MIN(basesalary+titlesalary) AS '最低工资'
+FROM salary;
+
+#13、按照部门统计应发工资的平均工资
+SELECT depid,AVG(basesalary+titlesalary)
+FROM employee JOIN salary
+ON employee.empid = salary.empid
+GROUP BY employee.depid
+
+#14、找出部门基本工资的平均工资低于2000的
+SELECT depid,AVG(basesalary) AS avgsal
+FROM employee JOIN salary
+ON employee.empid = salary.empid
+GROUP BY employee.depid
+HAVING avgsal < 2000;
+
+#15、按照员工编号、姓名、基本工资、职务工资、扣除,并按照职务升序排列,如果职务工资相同,再按照基本工资升序排列。
+SELECT emp.empid,emp.name,emp.title,basesalary,titlesalary,deduction
+FROM employee emp JOIN salary sal
+ON emp.empid = sal.empid
+ORDER BY emp.title ASC,basesalary ASC;
+
+#16、查询员工编号、姓名,出生日期,及年龄段。其中,如果80年之前出生的,定为“老年”;80后定为“中年”,90后定为“青壮年”
+SELECT empid,name,birthday,
+CASE WHEN YEAR(birthday) < 1980 THEN '老年'
+		 WHEN YEAR(birthday) < 1990 THEN '中年'
+		 ELSE '青壮年' END AS '年龄段'
+FROM employee;
+
+#17、查询所有的员工信息,和他所在的部门名称
+SELECT emp.*,dep.depname
+FROM employee emp LEFT JOIN department dep
+ON emp.depid = dep.depid
+
+#18、查询所有部门信息,和该部门的员工信息
+SELECT dep.*,emp.*
+FROM department dep LEFT JOIN employee emp
+ON dep.depid = emp.depid
+
+#19、查询所有职位中含“工程师”的男员工的人数
+SELECT COUNT(*)
+FROM employee
+WHERE sex = '男' AND title LIKE '%工程师%';
+
+#20、查询每个部门的男生和女生的人数和平均基本工资
+SELECT dep.depid,emp.sex,COUNT(*),AVG(sal.basesalary)
+FROM department dep JOIN employee emp JOIN salary sal
+ON dep.depid = emp.depid AND emp.empid = sal.empid
+GROUP BY dep.depid,emp.sex
+
+######################################################################
+
+#练习4:
+#1、创建一个数据库:test_school
+CREATE DATABASE IF NOT EXISTS test_school;
+
+USE test_school;
+
+#2、创建如下表格:
+#表1	Department表的定义
+/*
+	字段名			字段描述		数据类型			主键	外键	非空	唯一
+	DepNo				部门号			INT(10)				是		否		是		是
+	DepName 		部门名称		VARCHAR(20)		否		否		是		否
+	DepNote			部门备注		VARCHAR(50)		否		否		否		否
+*/
+#表2 Teacher表的定义
+/*
+	字段名		字段描述		数据类型			主键	外键	非空	唯一
+	Number		教工号			INT						是		否		是		是
+	Name 			姓名				VARCHAR(30)		否		否		是		否
+	Sex 			性别				VARCHAR(4)		否		否		否		否
+	Birth			出生日期		DATE 					否		否		否		否
+	DepNo			部门号			INT						否		是		否		否
+	Salary 		工资				FLOAT					否		否		否		否
+	Address 	家庭住址		VARCHAR(100)	否		否		否		否
+*/
+#创建表1
+CREATE TABLE Department(
+DepNo INT(10) PRIMARY KEY,
+DepName VARCHAR(20) NOT NULL,
+DepNote VARCHAR(50)
+);
+
+DESC Department;
+
+#创建表2
+CREATE TABLE Teacher(
+Number INT PRIMARY KEY,
+Name VARCHAR(30) NOT NULL,
+Sex VARCHAR(4),
+Birth DATE,
+DepNo INT,
+Salary FLOAT,
+Address VARCHAR(100),
+CONSTRAINT fk_teach_depno FOREIGN KEY(DepNo) REFERENCES Department(Depno)
+);
+
+DESC Teacher;
+
+#3、添加记录
+/*
+	DepNo		DepName 			DepNote
+	601			软件技术系		软件技术等专业
+	602			网络技术系		多媒体技术等专业
+	603			艺术设计系		广告艺术设计等专业
+	604			管理工程系		连锁经营管理等专业
+*/
+/*
+	Number 	Name 		Sex 	Birth				DepNo		Salary 		Address
+	2001		Tom 		女		1970-01-10	602			4500			四川省绵阳市
+	2002		Lucy		男		1983-12-18	601			2500			北京市昌平区
+	2003		Mike		男		1990-06-01	604			1500			重庆市渝中区
+	2004		James		女		1980-10-20	602			3500			四川省成都市
+	2005		Jack		男		1975-05-30	603			1200			重庆市南岸区
+*/
+#向部门表添加记录
+INSERT INTO Department VALUES
+(601,'软件技术系','软件技术等专业'),
+(602,'网络技术系','多媒体技术等专业'),
+(603,'艺术设计系','广告艺术设计等专业'),
+(604,'管理工程系','连锁经营管理等专业');
+
+SELECT * FROM Department;
+
+#向教师表中添加记录
+INSERT INTO Teacher VALUES
+(2001,'Tom','女','1970-01-10',602,4500,'四川省绵阳市'),
+(2002,'Lucy','男','1983-12-18',601,2500,'北京市昌平区'),
+(2003,'Mike','男','1990-06-01',604,1500,'重庆市渝中区'),
+(2004,'James','女','1980-10-20',602,3500,'四川省成都阳市'),
+(2005,'Jack','男','1975-05-30',603,1200,'重庆市南岸区');
+
+SELECT * FROM Teacher;
+
+#4、用SELECT语句查询Teacher表的所有记录
+SELECT * FROM Teacher;
+
+#5、找出所有其家庭地址中含有“北京”的教师的教工号及部门名称,要求显示结果中各列标题用中文别名表示。
+SELECT teach.Number AS '教工号',dep.DepName AS '部门名称',teach.Address
+FROM Teacher teach LEFT JOIN Department dep
+ON teach.DepNo = dep.DepNo
+WHERE teach.Address LIKE '%北京%';
+
+#6、获得Teacher表中工资最高的教工号和姓名。
+#我做的
+SELECT Number,Name,MAX(Salary)
+FROM Teacher
+
+#老师给的
+#方法一
+SELECT Number,Name
+FROM Teacher
+WHERE salary =(SELECT MAX(Salary) FROM Teacher);
+
+#方法二
+SELECT Number,Name
+FROM Teacher
+ORDER BY Salary DESC LIMIT 0,1;
+
+#7、找出所有收入在2500~4000之间的教工号。
+SELECT Number
+FROM Teacher
+WHERE Salary BETWEEN 2500 AND 4000;
+
+#8、查找在网络技术系工作的教师的姓名、性别和工资。
+SELECT Name,Sex,Salary
+FROM Teacher teach JOIN Department dep
+ON teach.DepNo = dep.DepNo
+WHERE dep.DepName = '网络技术系'
+
+######################################################################
+
+#练习5
+#1、建立数据库test_student
+
+#2、建立以下三张表,并插入记录
+#Table:Classes
+/*
+	专业					班级		姓名		性别		座位
+	计算机网络		1班			张三		男			8
+	软件工程			2班			李四		男			12
+	计算机维护		1班			王五		男			9
+	计算机网络		2班			LILY 		女			15
+	软件工程			1班			小强		男			20
+	计算机维护		1班			CoCo 		女			18
+*/
+#Table:Score
+/*
+	姓名		英语		数据		语文
+	张三		65			75			98
+	李四		87			45			86
+	王五		98			86			65
+	LILY 		75			86			87
+	小强		85			60			58
+	CoCo		96			87			70
+*/
+#Table:Records
+/*
+	姓名		记录
+	小强		迟到
+	小强		事假
+	李四		旷课
+	李四		旷课
+	李四		迟到
+	CoCo 		病假
+	LILY 		事假
+*/
+
+#3、写出将张三的语文成绩修改为88的SQL语句
+
+#4、搜索出计算机维护1班各门课程的平均成绩
+
+#5、搜索科目有不及格的人的名单
+
+#6、查询记录2次以上的学生的姓名和各科成绩
+
+######################################################################
+
+#练习6
+#1、建立数据库:test_xuankedb
+
+#2、建立如下三张表:
+/*
+		学生表Student由学号(Sno)、姓名(Sname)、性别(Ssex)、
+		年龄(Sage)、所在系(Sdept)五个字段,Sno为关键字。
+		
+		课程表(Course)由课程号(Cno)、课程名(Cname)、选修课号(Cpno)、
+		学分(Ccredit)四个字段,Cno为关键字。
+		
+		成绩表SG由学号(Sno)、课程号(Cno)、成绩(Grade)三个字段,
+		(Sno,Cno)为关键字。
+*/
+
+#3、向Student表增加“入学事件(Scome)”列,其数据类型为日期型。
+
+#4、查询选修了3号课程的学生的学号及其成绩,查询结果按分数的降序排列。
+
+#5、查询学习1号课程的学生最高分数、平均成绩。
+
+#6、查询与“李洋”在同一个系学习的学生。
+
+#7、将计算机系全体学生的成绩置零。
+
+#8、删除学生表中学号为05019的学生记录。
+
+#9、删除计算机系所有学生的成绩记录。
+
+######################################################################
+
+#练习7
+#1、建立数据库:test_library
+
+#2、建立如下三个表:
+/*
+	表一:press出版社	属性:编号pressid(int)、名称pressname(varchar)、
+	地址address(varchar)
+	
+	表二:sort种类 属性:编号sortno(int)、数量scount(int)
+	
+	表三:book图书 属性:编号bid(int)、名称bname(varchar)、
+	种类bsortno(int)、出版社编号pressid(int)
+*/
+
+#3、给sort表中添加一系列属性:描述describes(varchar)
+
+#4、向三个表中各插入几条数据
+#表一:press
+/*
+	pressid 		pressname 				address
+	100					外研社						上海
+	101					北大出版社				北京
+	102					教育出版社				北京
+*/
+#表二:sort
+/*
+	sortno 		scount		describes
+	11				50				小说
+	12				300				科幻
+	13				100				神话
+*/
+#表三:book
+/*
+	bid 	bname			bsortno		pressid
+	1			红与黑		11				100
+	2			幻城			12				102
+	3			希腊神话	13				102
+*/
+
+#5、查询出版社id为100的书的全部信息
+
+#6、查询出版社为外研社的书的全部信息
+
+#7、查询图书数量(scount)大于100的种类
+
+#8、查询图书种类最多的出版社信息
+
+######################################################################
+
+#练习8
+#1、建立数据库:test_tour
+
+#2、建立如下两个表
+#agency旅行社表:
+/*
+	列名(英文名)	列名(中文名)	数据类型		允许空值		说明
+	Id 							旅行社编号			INT					NO 					主键
+	Name 						旅行社名				VARCHAR			NO				
+	Address 				旅行社地址			VARCHAR 		NO
+	Areaid 					所属区域id			INT					YES
+*/
+#travel旅行线路表
+/*
+	列名(英文名)	列名(中文名)	数据类型		允许空值		说明
+	Tid 						旅行线路编号		INT					NO					主键
+	Time 						所需时间				VARCHAR			NO
+	Position 				目的地					VARCHAR			NO
+	Money						花费						FLOAT				YES
+	Aid 						所属旅行社id		INT					NO					外键
+	Count 					报名人数				INT					YES
+*/
+
+#3、添加记录
+#agency表数据
+/*
+	id 			name					address
+	101			青年旅行社		北京海淀
+	102			天天旅行社		天津海院
+*/
+#travel表数据
+/*
+	tid 		time		position 		money		aid		rcount
+	1				5天			八达岭			3000		101		10
+	2				7天			水长城			5000		101		14
+	3				8天			水长城			6000		102		11
+*/
+
+#4、查出旅行线路最多的旅社
+
+#5、查出最热门的旅行线路(也就是查询出报名人数最多的线路)
+
+#6、查询花费少于5000的旅行线路
+
+#7、找到一次旅行花费最昂贵的旅行社名
+
+#8、查出青年旅社所有的旅行线路都玩一遍需要多少时间
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 51 - 1
第十二章、MySQL数据类型精讲.sql

@@ -461,7 +461,57 @@ VALUES('男,女','睡觉,打豆豆');
 
 
 SELECT * FROM temp_mul;
 SELECT * FROM temp_mul;
 
 
-#64
+#10.1、BINARY 与 VARBINARY类型
+CREATE TABLE test_binary1(
+f1 BINARY,
+f2 BINARY(3),
+#f3 VARBINARY,
+f4 VARBINARY(10)
+);
+
+DESC test_binary1;
+
+INSERT INTO test_binary1(f1,f2)
+VALUES('a','abc');
+
+SELECT * FROM test_binary1;
+
+#Data too long for column 'f1' at row 1
+INSERT INTO test_binary1(f1)
+VALUES('ab');
+
+INSERT INTO test_binary1(f2,f4)
+VALUES('ab','ab');
+
+SELECT * FROM test_binary1;
+
+SELECT LENGTH(f2),LENGTH(f4)
+FROM test_binary1;
+
+#10.2、BLOB类型
+CREATE TABLE test_blob1(
+id INT,
+img MEDIUMBLOB
+);
+
+INSERT INTO test_blob1(id)
+VALUES(1001);
+
+SELECT * FROM test_blob1;
+
+#11、JSON类型
+CREATE TABLE test_json(
+js JSON
+);
+
+INSERT INTO test_json(js)
+VALUES('{"name":"songhk","age":18,"address":{"province":"beijing","city":"beijing"}}');
+
+SELECT * FROM test_json;
+
+SELECT js -> '$.name' AS name , js -> '$.age' AS age , js -> '$.address.province' AS province , js -> '$.address.city' AS city
+FROM test_json;
+