MySQL纯代码复习(下)

发布时间:2022-12-03 MYSQL 笔记 SQL 数据库

前言

本文章的语言描述会比上篇多一些

数据库的创建修改与删除

标识符命名规则

  • 数据库名、表名不得超过30个字符,变量限制为29个
  • 必须只能包含A-Z,a-z,0-9,_等63个字符
  • 数据库名、表名、字段名等对象名中间不要包含空格
  • 同一个MySQL软件中,数据库不能同名;同一个库中,表不能重名;同一个表中,字段不能重名
  • 必须保证你的字段没有和保留字、数据库系统或常用方法冲突。如果坚持使用,请在SQL语句中使用`(着重号)引起来(不建议这么做)
  • 保持字段名和类型的一致性:在命名字段并为其指定数据类型的时候一定要保证一致性,假如数据类型在一个表里是整数,那在另一个表中可别变成其他类型了

创建数据库

创建数据库的方式有三种:

#创建和管理表
SELECT * FROM ORDER;
SELECT * FROM `ORDER`;#使用着重号来区别保留字或关键字
#如何创建数据库
#创建数据库也是要有用户权限的
#root是根目录,我们学习都是用的root

数据库是不能改名的,有些图形工具可以改名的原因是,底层创建了一个新数据库,然后把要修改的数据库数据全部复制到新数据库里,然后删除旧数据库,所以一般不要修改数据库名,数据表是可以修改的
字符集默认使用utf8mb4
在这里插入图片描述

#显示创建的数据库的字符集和其他信息
#SHOW CREATE DATABASE databaseName;
#CREATE DATABASE `mytest1` 
#/*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */
#方式1:
CREATE DATABASE mytest1;
SHOW CREATE DATABASE mytest1;#默认utf8mb4
#方式2:指定字符集
CREATE DATABASE mytest2 CHARACTER SET 'gbk';
SHOW CREATE DATABASE mytest2;#gbk
#方式3(推荐使用):判断是否存在
#执行完毕后,字符集仍然是gbk,可以发现并不会覆盖和影响,只是不报错了
CREATE DATABASE IF NOT EXISTS mytest2 CHARACTER SET 'utf8';
#如果不存在,则正常创建
CREATE DATABASE IF NOT EXISTS mytest3 CHARACTER SET 'utf8';
SHOW CREATE DATABASE mytest3;#UTF8
#显示当前所有的数据库
SHOW DATABASES;#可以看到三个mytest数据库在列表中
#在非图形用户界面或者没有进入特定数据库时,是需要通过点击或use来进入数据库的
#切换\进入\使用数据库
USE atguigudb;#进入后,才可以进行表的操作,否则是提示命令表不存在
#查看当前数据库都存有哪些表
#没有表的话,图形中会是空的,命令行会提示:Empty set (0.00 sec),如果表没有数据也会是这样
USE mytest1;#进入数据库
SHOW TABLES;#显示该数据库的全部数据表
USE atguigudb;
SHOW TABLES;
#查看当前使用的数据库
SELECT DATABASE()FROM DUAL;#函数
#查看指定数据库下保存的表
SHOW TABLES FROM mysql;

修改数据库

#修改数据库
#更改数据库字符集
SHOW CREATE DATABASE mytest2;#查看创建结构
#将gbk修改成utf8
ALTER DATABASE mytest2 CHARACTER SET 'utf8';
SHOW CREATE DATABASE mytest2;#修改成功
#删除数据库
#方式1:
DROP DATABASE mytest1;#不能执行2次
SHOW DATABASES;
#方法2:
DROP DATABASE IF EXISTS mytest1;#如果不存在则不做任何处理
DROP DATABASE IF EXISTS mytest2;
SHOW DATABASES;
常见的数据类型_创建表的两种方式

在这里插入图片描述
数据类型
在这里插入图片描述
在这里插入图片描述

#如何创建数据表
USE atguigudb;
SHOW CREATE DATABASE atguigudb;#默认使用的是utf8
SHOW TABLES;
#方式1:
CREATE TABLE IF NOT EXISTS myemp1(#需要用户具备创建表的权限
id INT,
emp_name VARCHAR(15),#使用VARCHAR来定义字符串,必须在使用VARCAHR时指明其长度
hire_date DATE	
);
DESC myemp1;#查看表结构
#如果创建表时没有指明使用的字符集,则默认使用表所在的数据库的字符集
SHOW CREATE TABLE myemp1;#显示数据库创建时的语句
SELECT*FROM myemp1;#查看表数据
#方式2:
CREATE TABLE myemp2
AS 
SELECT employee_id ,last_name,salary
FROM employees;
DESC myemp2;SELECT*FROM myemp2;#有字段的
DESC employees;
#说明1:查询语句中字段的别名,可以作为新创建的表的字段的名称
#说明2:此时的查询语句可以结构比较丰富,使用前面讲过的各种SELECT
CREATE TABLE myemp3
AS
SELECT e.employee_id emp_id,e.last_name lname,d.department_name 
FROM employees e JOIN departments d
ON e.department_id = d.department_id;
SELECT*FROM myemp3
DESC myemp3;
#练习1:创建一个表employees_copy,实现对employees表的复制,包括表数
CREATE TABLE employees_copy
AS
SELECT * FROM employees;
SELECT*FROM employees_copy;
#练习2:创建一个表employees_blank,实现对employees表的复制,不包括表数
CREATE TABLE employees_blank
AS
SELECT * 
FROM employees
WHERE department_id > 10000;
SELECT * FROM employees_blank;
DESC employees_blank;

修改表_重命名表_删除表_清空表

#修改表_重命名表_删除表_清空表
DESC myemp1;
#修改表 --> ALTER TABLE
#添加一个字段
ALTER TABLE myemp1
ADD salary DOUBLE(10,2);#默认添加到表中的最后一个字段
DESC myemp1;
ALTER TABLE myemp1
ADD phone_number VARCHAR(20) FIRST;#FIRST:第一个
DESC myemp1;
ALTER TABLE myemp1
ADD email VARCHAR(45) AFTER emp_name;#AFTER:指定添加在某字段的后面
DESC myemp1;
#修改一个字段:数据类型、长度、默认值(略)
ALTER TABLE myemp1
MODIFY emp_name VARCHAR(25);#将emp_name的类型从VARCHAR(15)改为VARCHAR(25)
DESC myemp1;
ALTER TABLE myemp1
MODIFY emp_name VARCHAR(35) DEFAULT 'aaa'; #指定了默认值,如果插入数据为NULL,则默认为'aaa'
DESC myemp1;
#重命名一个字段
ALTER TABLE myemp1
CHANGE salary monthly_salary DOUBLE(10,2);
DESC myemp1;
ALTER TABLE myemp1
CHANGE email my_email VARCHAR(50);#类型也是可以修改的
DESC myemp1;
#删除一个字段
ALTER TABLE myemp1
DROP COLUMN my_email;
DESC myemp1;
#重命名表
#方式1:
RENAME TABLE myemp1
TO myemp11;
DESC myemp11;
#方式2:
ALTER TABLE myemp2
RENAME TO myemp12;
DESC myemp12;
#删除表:不光将结构删除,同时表中的数据也被删除,释放表空间
DROP TABLE IF EXISTS myemp2;
DROP TABLE IF EXISTS myemp12;
#清空表:只删除表数据,表结构不变 --> 包括自增列也会重置,而delete from 和 回滚事务 是无法重置自增列自增长值的
SELECT * FROM employees_copy;
TRUNCATE TABLE employees_copy;
SELECT * FROM employees_copy;

DCL中的COMMIT和ROLLBACK的使用

COMMIT表示提交,在数据库中是默认提交的,如果不是默认提交,则每次执行完数据库操作,如果不提交,则所有数据都会回滚,就像你写Word文档,但是没有保存,一旦没有保存,这些数据都会消失。

#DCL中COMMIT和ROLLBACK
#COMMIT:提交数据。一旦执行COMMIT,则数据就被永久的保存在数据库中,意味着数据不可以回滚
#ROLLBACK:回滚数据。一旦执行ROLLBACK,则可以实现数据的回滚。回滚到最近的一次COMMIT最后
#对比TRUNCATE TABLE 和 DELETE FROM
#相同点:都可以实现对表中所有数据的删除,同时保留表结构
#不同点:
#	TURNCATE TABLE:一旦执行此操作,表数据全部清除。同时,数据是不可以回滚的
#	DELETE FROM:一旦执此操作,表数据可以全部清除(不带WHERE)同时,数据是可以实现回滚的
/*
DDL 和 DML的说明
① DDL的操作一旦执行,就不可回滚SET autocommit = FALSE对DDL操作无效.
  (因为在执行完DDL操作之后,一定会执行一次COMMIT,而此操作不受SET autocomiit=false的影响)
② DML的默认情况下,一旦执行,也是不可回滚的。但是,如果在执行DML之前,
  执行了 SET autocommit = FALSE,则执行的DML操作就可以实现回滚
*/
#演示:DELETE FROM
#1)
COMMIT;#先提交一下
#2)
SELECT*FROM myemp3;#106条数据
#3)
SET autocommit = FALSE;
#4)
DELETE FROM myemp3;
#5)
SELECT*FROM myemp3;#0条数据
#6)
ROLLBACK;#回滚数据
#7)
SELECT*FROM myemp3;#106条数据

阿里MySQL命名规范及MySQL8.0DDL的原子化

阿里开发规范:
【参考】TRUNCATE TABLE比DELETE速度快,且使用的系统和事务日志资源少,但TRUNCATE无事务且不触发TRIGGER,有可能造成事故,故不建议在开发代码中使用此语句
说明:TRUNCATE TABLE在功能上与不带WHERE子句的DELETE语句相同
内容扩展

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#测试MySQL8.0的新特性:DDL的原子化
CREATE DATABASE mytest;
USE mytest;
CREATE TABLE book1(
book_id INT,
book_name VARCHAR(255)
);
SHOW TABLES;
DROP TABLE book1,book2
SHOW TABLES;
#区别是,如果是5.7版本的MySQL,上面的删除数据表语句,会将book1删除掉
#这里是没有book2的,所以肯定报错,但是8.0中,如果报错了就不会删除book1
#这也是DDL的原子化:要么都成功,要么就回滚
创建管理表练习

练习需知

#--------------------------------------------------------------------------------
#在查询所有数据库或所有表时,都是在后加上了s
#表示复数,SHOW DATABASES;SHOW TABLES;
#如下代码不要执行,只看代码语法结构,将实际表代入即可
#增加字段:
ALTER TABLE employees
ADD salary INT;
#修改字段:类型、位置
ALTER TABLE employees
MODIFY salary INT AFTER birth_date;#MODIFY salary INT FIRST
#修改字段名:
ALTER TABLE employees
CHANGE birth birthday DATE;
#删除字段:
ALTER TABLE employees
DROP COLUMN department_id;
#修改表名
RENAME employees TO emp1;
ALTER TABLE employees
RENAME TO emp1;
#查询所有表
SHOW TABLES;#默认当前数据库
SHOW TABLES FROM test03_company;#指定数据库
SHOW TABLES FROM atguigudb;#跨数据库查询
#使用查询复制式建表
CREATE TABLE myemp01
AS
SELECT * FROM employees;#没有问题,当前数据表
CREATE TABLE myemp02
AS
SELECT * FROM atguigudb.`departments`;#跨库,必须指定库名+表名 以.作为引用
#--------------------------------------------------------------------------------

练习1

#创建和管理表练习
#练习1:
#1.创建数据库test01_office,指明字符集为utf8。并在此数据库执行下述操作
CREATE DATABASE IF NOT EXISTS test01_office CHARACTER SET 'utf8';
USE test01_office;
#2.创建表dept01
/*
字段	类型
id	INT(7)
NAME	VARCHAR(25)
*/
CREATE TABLE IF NOT EXISTS dept01(
id INT(7),
`NAME` VARCHAR(25)
);
DESC dept01;
#3.将表departments的数据插入新表dept02表中
CREATE TABLE IF NOT EXISTS dept02
AS
#我们当前在test01_office数据库下,该数据库下是没有departments表的
#我们需要额外指定这张表来源于哪个数据库
SELECT *
FROM atguigudb.departments;
DESC dept02;SELECT*FROM dept02;
#4.创建表emp01
/*
字段		类型
id		INT(7)
first_name	VARCHAR(25)
last_name	VARCHAR(25)
dept_id		INT(7)
*/
CREATE TABLE IF NOT EXISTS emp01(
id INT(7),
first_name VARCHAR(25),
last_name VARCHAR(25),
dept_id INT(7)
);
DESC emp01;
#5.将列last_name的长度增加到50
ALTER TABLE emp01
MODIFY last_name VARCHAR(50);
DESC emp01;#查看表结构
#6.根据表employees创建emp2
CREATE TABLE IF NOT EXISTS emp02
AS
SELECT * FROM atguigudb.`employees`;
DESC emp02;SELECT*FROM emp02;
SHOW TABLES FROM test01_office;
#7.删除表emp01
DROP TABLE emp01;
ROLLBACK;#无效,因为执行完DDL操作,会自动提交
#8.将表emp02重命名为emp01
ALTER TABLE emp02
RENAME TO emp01;
#REANME TABLE emp01 TO emp02;
SHOW TABLES FROM test01_office;
#9.在表dept02和emp01中添加新列test_column,并检查所做的操作
ALTER TABLE emp01
ADD test_column VARCHAR(10);DESC emp01
ALTER TABLE dept02
ADD test_column VARCHAR(10);DESC dept02;
#10.直接删除表emp01中的列department_id
ALTER TABLE emp01
DROP COLUMN department_id;DESC emp01;

练习2

#1、创建数据库test02_market
CREATE DATABASE IF NOT EXISTS test02_market;
USE test02_market;
SHOW CREATE DATABASE test02_market;
#2、创建数据表customers
CREATE TABLE IF NOT EXISTS customers(
c_num INT,
c_name VARCHAR(50),
c_contact VARCHAR(50),
c_city VARCHAR(50),
c_birth DATE
);
SHOW TABLES;
#3、将c_contact字段移动到c_birth字段后面
ALTER TABLE customers
MODIFY c_contact VARCHAR(50) AFTER c_birth;
DESC customers;
#4、将c_name字段数据类型改为VARCHAR(70)
ALTER TABLE customers
MODIFY c_name VARCHAR(70);
DESC customers;
#5、将c_contact字段改名为c_phone
ALTER TABLE customers
CHANGE c_contact c_phone VARCHAR(50);
DESC customers;
#6、增加c_gender字段到c_name后面,数据类型为char(1)
ALTER TABLE customers
ADD c_gender CHAR(1) AFTER c_name;
DESC customers;
#7、将表名改为customers_info
RENAME TABLE customers#DESC customers;
TO customers_info;
SHOW TABLES;DESC customers_info;
#8、删除字段c_city
ALTER TABLE customers_info
DROP COLUMN c_city;
DESC customers_info;

练习3

#练习3:
#1、创建数据库test03_company
CREATE DATABASE IF NOT EXISTS test03_company CHARACTER SET 'utf8';
USE test03_company;
#2、创建表offices
CREATE TABLE IF NOT EXISTS offices(
officeCode INT,#办公号
city VARCHAR(30),#城市
address VARCHAR(50),#地址
country VARCHAR(50),#国家
postalCode VARCHAR(25)#邮政编码
);
DESC offices;
#3、创建表employees
CREATE TABLE IF NOT EXISTS employees(
empNum INT,#员工号
lastName VARCHAR(50),#姓
firstName VARCHAR(50),#名字
mobile VARCHAR(25),#住处
`code` INT,#代码...码
jobTitle VARCHAR(50),#职称
birth DATE,#生日
note VARCHAR(255),#记录
sex VARCHAR(5)#姓别
);
DESC employees;
#4、将表employees的mobile字段修改到code字段后面
ALTER TABLE employees
MODIFY mobile VARCHAR(20) AFTER `code`;
DESC employees;
#5、将表employees的birth字段改名为birthday
ALTER TABLE employees
CHANGE birth birthday DATE;
DESC employees;
#6、修改sex字段,数据类型为char(1)
ALTER TABLE employees
MODIFY sex CHAR(1);
DESC employees;
#7、删除字段note
ALTER TABLE employees
DROP COLUMN note;
DESC employees;
#8、增加字段名favoriate_activity,数据类型为varchar(100)
ALTER TABLE employees
ADD favoriate_activity VARCHAR(100);
DESC employees;
#9、将表employees的名称修改为employees_info
RENAME TABLE employees 
TO employees_info;
/*
ALTER TABLE employees
RENAME TO employees_info
*/
#DESC employees;
DESC employees_info;
SHOW TABLES;
数据处理之增删改

在实际开发场景中,我们总是会不断向数据表中增加数据、修改数据、删除数据等等操作,这里涉及到了增删改操作,数据库语言核心是:增删改查

DML之添加数据

#数据增删改
#储备工作
USE atguigudb;
CREATE TABLE IF NOT EXISTS emp1(
id INT,
`name` VARCHAR(15),
hire_date DATE,
salary DOUBLE(10,2)
);
DESC emp1;
SELECT * 
FROM emp1;#空
#添加数据
#方式1:一条一条的添加数据
#①没有指明添加的字段
#正确的
INSERT INTO emp1
#如果没有写小数点,则会隐式转换
VALUES(1,'Tom','2000-12-21',3400.00);#一定要按声明的字段的先后顺序添加
SELECT * 
FROM emp1;#1条
#错误的
#INSERT INTO emp1
#VALUES(2,3400,'2000-12-21','Jerry');#一定要按声明的字段的先后顺序添加
SELECT * 
FROM emp1;#1条
#方式2:
INSERT INTO emp1(id,hire_date,salary,`name`)#类似于Java的构造器
VALUES(2,'2000-12-21',3400,'Jerry');
SELECT * 
FROM emp1;#2条
INSERT INTO emp1(id,salary,`name`)
VALUES(3,4500.00,'shk');#其他没有指定的字段则为NULL,如果有默认值则为默认值
SELECT * 
FROM emp1;#3条 如果有约束的haul,则无法添加NULL 也就是 NOT NULL的非空约束(暂略)
#③
INSERT INTO emp1(id,`name`,salary)
VALUES 
(4,'zixuan',5000);
INSERT INTO emp1(id,`name`,salary)
VALUES 
(5,'美',99999); 
SELECT * FROM emp1;
#同时插入多条数据
INSERT INTO emp1 VALUES(6,'cat','2022-4-20',0.00),
(7,'tianyi','2012-7-12',8102.00);
SELECT * FROM emp1;
#方式2:将查询结果插入到表中
SELECT * FROM emp1;
INSERT INTO emp1(id,`name`,salary,hire_date)
#AS只能放到新表,而这个可以是新,也可以是旧
#查询语句
SELECT employee_id,last_name,salary,hire_date#查询的字段一定要与添加到的表的字段一一对应
FROM employees
WHERE department_id IN (70,60);#70 60 | 60 70顺序不影响结果
SELECT * FROM emp1;
DESC emp1;
DESC employees;
#说明:emp1表中要添加数据的字段的长度不能低于employees表中查询字段的长度
#否则容易精度丢失,可以更大,但是不能更小

在这里插入图片描述

DML之更新删除操作_MySQL8.0新特性之计算列

更新数据和删除数据

在这里插入图片描述
在这里插入图片描述

#更新数据(或修改数据)
SELECT*FROM emp1;SELECT*FROM emp1 WHERE id = 4;
#UPDATE ... SET ... WHERE ...
#可以实现批量修改数据
UPDATE emp1
SET hire_date = '2004-09-04' 
WHERE id = 4;#一定要添加条件,否则会全部修改掉
SELECT*FROM emp1;SELECT*FROM emp1 WHERE id = 4;
#同时修改一条数据的多个字段
UPDATE emp1
SET hire_date = CURDATE(),salary=6000
WHERE id = 5;
SELECT*FROM emp1;SELECT*FROM emp1 WHERE id = 5;
#题目:将表中姓名中包含字符a的提薪20%
UPDATE emp1
SET salary = salary*1.2
WHERE `name` LIKE '%a%';SELECT*FROM emp1;
#修改数据时,是可能存在不成功的情况的。原因:语法不对、有约束等等
UPDATE employees
SET department_id = 10000
WHERE employee_id = 102;
#删除数据 DELETE FROM ... WHERE ... 如果没有where,则会删除掉表中的所有数据
SELECT*FROM emp1;SELECT*FROM emp1 WHERE id = 1;
DELETE FROM emp1
WHERE id = 1;
SELECT*FROM emp1;
#由于约束影响,删除也是可能失败的
DELETE FROM departments
WHERE department_id = 50;
#小结:DML操作默认情况下,执行完以后都会自动提交数据
#如果希望执行完以后不自动提交数据,则需要使用 SET autocommit = FALSE;

MySQL8.0新特性计算列
在这里插入图片描述
在这里插入图片描述

#MySQL8.0新特性:计算列
USE atguigudb;
CREATE TABLE IF NOT EXISTS test1(
a INT,
b INT,
#GENERATED -> 生成|ALWAYS -> 总是|| VIRTUAL -> 虚拟
#这些关键字的单个翻译有点抽象,总翻译大概为 始终作为(a+b)虚拟生成
c INT GENERATED ALWAYS AS (a+b) VIRTUAL#此时c字段就作为了我们的计算列
);
INSERT INTO test1(a,b)
VALUES(10,20);
SELECT*FROM test1;DESC test1;
#更新数据
UPDATE test1#将a修改为100,我们只有一行,所以可以不加where条件
SET a = 100;
SELECT * FROM test1;#c变成了 120(a=100+b=20)

这关键字有点抽象,大概意思理解就行,该计算列的应用场景并不多,先知道有就行

DDL和DML的综合案列

#DDL和DML的综合案例
#1、创建数据库test01_library
CREATE DATABASE IF NOT EXISTS test01_library CHARACTER SET 'utf8';
USE test01_library;
#2、创建books表
CREATE TABLE IF NOT EXISTS books(
id INT,
`name` VARCHAR(50),
`authors` VARCHAR(100),
price FLOAT,
pubdate YEAR,
note VARCHAR(100),
num INT
);
DESC books;SELECT*FROM books;
#3、向books表中添加数据
INSERT INTO books
VALUES(1,'Tal of AAA','Dickes',23,'1995','novel',11),
(2,'EmmaT','Jane lura',35,'1993','joke',22),
(3,'Story of jane','Jane Tim',40,'2001','novel',0),
(4,'Lovey Day','George Byron',20,'2005','novel',30),
(5,'Old land','Honore Blade',30,'2010','law',0),
(6,'The Battle','Upton Sara',30,'1999','medicine',40),
(7,'Rose Hood','Richard haggard',28,'2008','cartoon',28);
SELECT*FROM books;
#4、将小说类型(novel)的书的价格都增加5
UPDATE books
SET price = price+5 
WHERE note = 'novel';
SELECT*FROM books;
#5、将名称为EmmaT的书的价格改为40,并将说明改为drama
UPDATE books
SET price = 40,note = 'drama' 
WHERE `name` = 'EmmaT';
SELECT*FROM books;
#6、删除库存为0的记录
DELETE FROM books 
WHERE num = 0;
SELECT * FROM books;
#补回删掉的两条数据
INSERT INTO books VALUES(3,'Story of jane','Jane Tim',40,'2001','novel',0),(5,'Old land','Honore Blade',30,'2010','law',0);
#7、统计书名中包含a字母的书
SELECT *
FROM books
WHERE `name` LIKE '%a%';
#8、统计书名中包含a字母的书的数量和库存总量
SELECT COUNT(*),SUM(num)
FROM books
WHERE `name` LIKE '%a%';
#9、找出"novel"类型的书,按照价格降序排列
SELECT *
FROM books
WHERE note = 'novel'
ORDER BY price DESC;
#10、查询图书信息,按照库存量降序排列,如果库存量相同的按照note升序排列
SELECT *
FROM books
ORDER BY num DESC,note ASC;
#11、按照note分类统计书的数量
SELECT note,COUNT(*)
FROM books
GROUP BY note;
#12、按照note分类统计书的库存量,显示库存量超过30本的
SELECT note,SUM(num)
FROM books
GROUP BY note
HAVING SUM(num) >= 30;
#13、查询所有图书,每页显示5本,显示第二页
SELECT*FROM books
LIMIT 5,5;
#14、按照note分类统计书的库存量,显示库存量最多的
SELECT note,SUM(num) sum_num
FROM books
GROUP BY note
ORDER BY sum_num DESC
LIMIT 0,1;
#15、查询书名达到10个字符的书,不包括里面的空格
SELECT `name`
FROM books
WHERE CHAR_LENGTH(REPLACE(`name`,' ','')) >= 10;
#16、查询书名和类型,其中note值为novel显示小说,law显示法律,medicine显示医药
#cartoon显示卡通,joke显示笑话
SELECT `name`,note,CASE note WHEN 'novel' THEN '小说'
				WHEN 'law' THEN '法律'
				WHEN 'medicine' THEN '医药'
				WHEN 'cartoon' THEN '卡通'
				WHEN 'joke' THEN '搞笑'
				ELSE '其他'
				END "类型"
FROM books;
#17、查询书名、库存,其中num值超过30本的,显示滞销,大于0并低于10的
#显示畅销,为0则显示需要无货
SELECT `name` AS "书名",num AS "库存",CASE WHEN num >30 THEN '滞销'
						WHEN num >0 AND num <10 THEN '畅销'
						WHEN num = 0 THEN '无货'
						ELSE '正常'
						END "显示状态"
FROM books;
#18、统计每一种note的库存量,并合并总量
SELECT IFNULL(note,'合计库存总量') AS note,SUM(num)
FROM books
GROUP BY note WITH ROLLUP;
#19、统计每一种note的数量,并合并总量
SELECT IFNULL(note,'合计库存总量') AS note,COUNT(*)
FROM books
GROUP BY note WITH ROLLUP;
#20、统计库存量前三名的图书
SELECT *
FROM books
ORDER BY num DESC
LIMIT 0,3;
#21、找出最早出版的一本书
SELECT * 
FROM books
ORDER BY pubdate ASC
LIMIT 0,1;
#22、找出novel中价格最高的一本书
SELECT * 
FROM books
WHERE note = 'novel'
ORDER BY price DESC
LIMIT 0,1;
#23、找出书名中字数最多的一本书,不包含空格
SELECT *
FROM books
ORDER BY CHAR_LENGTH(REPLACE(`name`,' ','')) DESC
LIMIT 0,1;
数据类型概述_字符集设置

MySQL中的数据类型

在这里插入图片描述
常见的属性
在这里插入图片描述

#MySQL数据类型
#关于属性:character set name

#创建数据库时指明字符集
CREATE DATABASE IF NOT EXISTS dbtest12 CHARACTER SET 'utf8';
USE dbtest12;
SHOW CREATE DATABASE dbtest12;
#创建表的时候,指明表的字符集
CREATE TABLE temp(
id INT
)CHARACTER SET 'utf8';
SHOW CREATE TABLE temp;
#创建表,指明字段时,可以指定字段的字符集
CREATE TABLE temp1(
id INT,
NAME VARCHAR(15) CHARACTER SET 'gbk'
);
SHOW CREATE TABLE temp1;
#没有指明,就向上指明 
#字段->表->库->ini配置文件
SHOW VARIABLES LIKE 'character_%';
数据类型精讲

整型数据类型讲解

类型介绍
整数类型一共有5种,包括TINYINT、SMALLINT、MEDIUMINT、INT(INTEGER)和BIGINT
区别如下:
在这里插入图片描述
在这里插入图片描述

#整型数据类型
#本章的内容测试建议使用MySQL5.7进行测试
#类型后面小括号里的数是表示类型宽度
USE dbtest12;#进入指定数据库
CREATE TABLE test_int1(
f1 TINYINT,
f2 SMALLINT,
f3 MEDIUMINT,
f4 INTEGER,
f5 BIGINT
);
DESC test_int1;
INSERT INTO test_int1(f1)
VALUES(12),(-12),(-128),(127);
SELECT*FROM test_int1;
#INSERT INTO test_int1(f1)超出了范围
#VALUES(128);
CREATE TABLE test_int2(
f1 INT,
f2 INT(5),#这里的宽度指定,意义不大
#显示宽度为5,当insert不足五位时,使用0填充
f3 INT(5) ZEROFILL#配合ZEROFILI才有意义 并且会自动添加 UNSIGNED 不为负数 无符号 因为是补充0
);
INSERT INTO test_int2(f1,f2)
VALUES(123,123),(123456,123456);#超出了长度,但是执行没有问题
SELECT * FROM test_int2;
DESC test_int2;
INSERT INTO test_int2(f3)
VALUES(123),(123456);#如果不足位数,则用0补充
SELECT * FROM test_int2;
DESC test_int2;
SHOW CREATE TABLE test_int2;
#关于类型宽度基本上没有什么大用,了解就行了

无符号
在这里插入图片描述
在这里插入图片描述
因为无符号,所以直接取值正数的范围,一共是10位

CREATE TABLE test_int3(
f1 INT UNSIGNED#无符号
);
DESC test_int3;
INSERT INTO test_int3
VALUES(2412321);
SELECT * FROM test_int3;
#INSERT INTO test_int3
#VALUES(4294967296);#4294967295是最大范围,这里超出了最大范围

扩展

在这里插入图片描述
一般都是用INT类型,在Java中也是这样
在这里插入图片描述
在这里插入图片描述

浮点数、定点数与类型讲解

浮点类型

浮点数和定点数类型的特定是可以处理小数,你可以把整数看成小数的一个特例。因此,浮点数和定点数的使用场景,比整数大多了。MySQL支持的浮点类型,分别是FLOAT、DOUBLE、REAL

  • FLOAT表示单精度浮点数
  • DOUBLE表示双精度浮点数
#浮点类型
CREATE TABLE test_double1(
f1 FLOAT,
f2 FLOAT(5,2),
f3 DOUBLE,
f4 DOUBLE(5,2)
);
DESC test_double1;
INSERT INTO test_double1(f1,f2)
VALUES(123.45,123.45);
SELECT * FROM test_double1;
INSERT INTO test_double1(f3,f4)
VALUES(123.45,123.456);#小数位四舍五入了 123.456 - > 123.46
INSERT INTO test_double1(f3,f4)
VALUES(123.45,1234.456);#Out of range value for column 'f4' at row 1
INSERT INTO test_double1(f3,f4)
VALUES(123.45,999.995);#Out of range value for column 'f4' at row 1
#测试FLOAT和DOUBLE的精度问题
CREATE TABLE test_double2(
f1 DOUBLE
);
INSERT INTO test_double2
VALUES(0.47),(0.44),(0.19);
SELECT SUM(f1)
FROM test_double2;#1.0999999999999999 ≠ 1.1
SELECT SUM(f1) = 1.1,1.1 = 1.1#1表示true
FROM test_double2;#0表示false

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
定点数类型
decimal(M,D)

#定点数类型
CREATE TABLE test_decimal1(
f1 DECIMAL,#默认10,0
f2 DECIMAL(5,2)#指明了 M,D 整数5位,小数2位
);
DESC test_decimal1;
INSERT INTO test_decimal1(f1)
VALUES(123),(123.45);#有四舍五入情况
SELECT * FROM test_decimal1;
INSERT INTO test_decimal1(f2)
VALUES(999.99);#f2的最大可添加数范围
SELECT * FROM test_decimal1;
INSERT INTO test_decimal1(f2)
VALUES(67.567);#四舍五入
SELECT * FROM test_decimal1;
INSERT INTO test_decimal1(f2)#超出了设定的最大范围
VALUES(1267.567);#Out of range value for column 'f2' at row 1
INSERT INTO test_decimal1(f2)
VALUES(999.995);#f2的最大可添加数范围,但是四舍五入是无法进行的
#修改上面测试精度表的字段类型
/*

#测试FLOAT和DOUBLE的精度问题
CREATE TABLE test_double2(
f1 DOUBLE
);

*/
ALTER TABLE test_double2
MODIFY f1 DECIMAL(5,2);
DESC test_double2;
#可以看到差距,定点数类型的相加是正常的
#精准1.1
SELECT * FROM test_double2;
SELECT SUM(f1)
FROM test_double2;
SELECT SUM(f1) = 1.1,1.1=1.1
FROM test_double2;#1表示 true 0表示false null表示其他情况

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
位类型
BIT

#位类型:BIT
CREATE TABLE test_bit1(
f1 BIT,
f2 BIT(5),
f3 BIT(64)#BIT(65) --> for column f3(max=64)
);
DESC test_bit1;
INSERT INTO test_bit1(f1)
VALUES(0),(1);
SELECT*FROM test_bit1;#b'0' b'1'
#b是SQLYong呈现的原因
#--------------------------
#Data too long for column 'f1' at row 1
INSERT INTO test_bit1(f1)
VALUES(2);#2是十进制的体现样式 如果十进制2转换为二进制2则是 10 占2位,而BIT默认只占一位,我们的f2可以插入的
INSERT INTO test_bit1(f2)
VALUES(31);
SELECT*FROM test_bit1;
INSERT INTO test_bit1(f2)#Data too long for column 'f2' at row 1
VALUES(32);#超过了5位

在这里插入图片描述
先说关于BIT类型查询区别
在SQLYong中,查询的BIT数据会带个b前缀
在这里插入图片描述
下面我们看看在cmd命令行中的样子,因为8.0显示有点问题,我们只看5.7的样子
5.7的样子
在这里插入图片描述

在这里插入图片描述
可以看到,以16进制的形式展现的数据
通过函数我们也可以展示指定的进制
在这里插入图片描述
在这里插入图片描述

SELECT BIN(f1),BIN(f2),#二进制展示数据函数
HEX(f1),HEX(F2)#十六进制
FROM test_bit1;

上面的命令行是8.0版本的,可能显示乱码是因为8.0需要显式指定进制,只是猜测,不去深究
在这里插入图片描述

SELECT f1+0,f2+0#开发中用的很少很少,先了解了解即可
FROM test_bit1;#此时+0以后,可以以十进制的方式显示数据

日期与时间类型

在上MySQL纯代码复习(上)中我们有介绍过关于日期与时间的函数,这里将介绍关于本质的类型详细

YEAR类型

#YEAR类型
CREATE TABLE test_year(
f1 YEAR,
f2 YEAR(4)
);
DESC test_year;#我们会发现即使是没有指定4,也会是4
INSERT INTO test_year(f1)
VALUES('2021'),(2022);
SELECT*FROM test_year;#最小1901 最大2155
INSERT INTO test_year(f1)
VALUES('2155');
INSERT INTO test_year(f1)
VALUES('2156');#Out of range value for column 'f1' at row 1
INSERT INTO test_year(f1)
VALUES('69'),('70');
INSERT INTO test_year(f1)
VALUES(0),('00');
SELECT*FROM test_year;#最小1901 最大2155

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
建议尽量写四位的YEAR

date类型
在这里插入图片描述

#date类型
CREATE TABLE test_date1(
f1 DATE
);
DESC test_date1;
INSERT INTO test_date1
VALUES('2020-10-01'),('20221001'),(20221001);
INSERT INTO test_date1
VALUES('00-01-01'),('000101'),('69-10-01'),('691001'),('70-01-01'),('700101'),('99-01-01'),('990101');
SELECT * FROM test_date1;
INSERT INTO test_date1
VALUES(000301),(690301),(700301),(990301);#存在隐式转换
INSERT INTO test_date1
VALUES(CURDATE()),(CURRENT_DATE()),(NOW());
SELECT * FROM test_date1;

time类型
在这里插入图片描述

#time类型
CREATE TABLE test_time1(
f1 TIME
);
DESC test_time1;
INSERT INTO test_time1
VALUES('2 12:30:29'),('12:35:29'),('12:40'),('2 12:40'),('1 05'),('45');
SELECT * FROM test_time1;
INSERT INTO test_time1
VALUES('123520'),(124011),(1210);
INSERT INTO test_time1
VALUES(NOW()),(CURRENT_TIME());
SELECT*FROM test_time1;

datetime类型
在这里插入图片描述

#datetime类型
CREATE TABLE test_datetime1(
dt DATETIME
);
DESC test_datetime1;
INSERT INTO test_datetime1
VALUES('2021-01-01 06:50:30'),('20210101065030');
INSERT INTO test_datetime1
VALUES('99-01-01 00:00:00'),('990101000000'),('20-01-01 00:00:00'),('200101000000');
INSERT INTO test_datetime1
VALUES(20200101000000),(200101000000),(19990101000000),(990101000000);
SELECT*FROM test_datetime1;

timestamp类型
在这里插入图片描述

CREATE TABLE test_timestamp1(
ts TIMESTAMP
);
DESC test_timestamp1;
INSERT INTO test_time1
VALUES('1999-01-01 03:04:50'),('19990101030450'),('99-01-01 03:04:05'),('99010103040');
INSERT INTO test_timestamp1
VALUES('2020@01@01@00@00@00'),('20@01@01@00@00@0');
INSERT INTO test_timestamp1
VALUES(CURRENT_TIMESTAMP()),(NOW());
SELECT*FROM test_timestamp1;
#Incorrect datetime value: '2038-01-20 03:14:07' for column 'ts' at row 1
INSERT INTO test_timestamp1
VALUES('2038-01-20 03:14:07');

TIMESTAMP和DATETIME的区别
在这里插入图片描述
在这里插入图片描述

#对比DATETIME和TIMESTAMP
CREATE TABLE temp_time(
d1 DATETIME,
d2 TIMESTAMP
);
INSERT INTO temp_time VALUES('2021-9-2 14:45:32','2021-9-2 14:45:52');
INSERT INTO temp_time VALUES(NOW(),NOW());
SELECT*FROM temp_time;
#修改当前的时区
SET time_zone = '+9:00';
SELECT*FROM temp_time;
SET time_zone = '+8:00';
SELECT*FROM temp_time;

文本字符串类型(含ENUM、SET)

在这里插入图片描述
CHAR和VARCHAR类型
在这里插入图片描述
char类型
在这里插入图片描述

#char类型
CREATE TABLE test_char1(
c1 CHAR,#默认只有一个字符
c2 CHAR(5)
);
DESC test_char1;
INSERT INTO test_char1(c1)
VALUES('a');
SELECT * FROM test_char1;
#Data too long for column 'c1' at row 1
INSERT INTO test_char1(c1)
VALUES('ab');#超出了指定的长度,添加失败
INSERT INTO test_char1(c2)#c2长度是5
VALUES('ab');
INSERT INTO test_char1(c2)#c2长度是5
VALUES('hello');
INSERT INTO test_char1(c2)#c2长度是5
VALUES('尚');
INSERT INTO test_char1(c2)#c2长度是5
VALUES('硅谷');
SELECT * FROM test_char1;
INSERT INTO test_char1(c2)#c2长度是5
VALUES('尚硅谷教育');
SELECT * FROM test_char1;
#字符不等于字节
#Data too long for column 'c2' at row 1
INSERT INTO test_char1(c2)#c2长度是5
VALUES('尚硅谷IT教育');#超过了5个字符
SELECT CONCAT(c2,'***')
FROM test_char1;#检索数据时,会把空格去掉
INSERT INTO test_char1(c2)
VALUES('ab  ');#自己写的空格也会被去掉
SELECT CHAR_LENGTH(c2)
FROM test_char1;

varchar类型

在这里插入图片描述
在这里插入图片描述

#varchar类型
CREATE TABLE test_varchar1(
`name` VARCHAR#错误 因为是可变长度的字符串
);
#Column length too big for column 'name' (max = 21845); use BLOB or TEXT instead
CREATE TABLE test_varchar2(
`name` VARCHAR(65535)
);
#最大值应该是 21845 --> 21845 *3 = 65535
CREATE TABLE test_varchar3(
`name` VARCHAR(5)
);
INSERT INTO test_varchar3
VALUES('尚硅谷'),('尚硅谷教育');#3个汉字 = 9个字节 3*3 
#Data too long for column 'name' at row 1
INSERT INTO test_varchar3
VALUES('尚硅谷IT教育');

TEXT类型
在这里插入图片描述

#Text类型
CREATE TABLE IF NOT EXISTS test_text(
tx TEXT
);
INSERT INTO test_text
VALUES('atguigu   ')
SELECT CHAR_LENGTH(tx)
FROM test_text;

在这里插入图片描述
ENUM类型
在这里插入图片描述

#enum类型
CREATE TABLE test_enum(
season ENUM('春','夏','秋','冬','unknow')#unknow表示未知 5选一 枚举法
);
INSERT INTO test_enum
VALUES('春'),('秋');
SELECT*FROM test_enum;
#Data truncated for column 'season' at row 1
#不能添加2个和非枚举值的数据
INSERT INTO test_enum
VALUES('春,秋');
INSERT INTO test_enum
VALUES('人');
#添加unknow值
INSERT INTO test_enum
VALUES('unknow');
SELECT*FROM test_enum;
INSERT INTO test_enum
VALUES('UNKNOW');#忽略大小写的
SELECT*FROM test_enum;
INSERT INTO test_enum
VALUES(1),('3');#通过索引值添加
SELECT*FROM test_enum;
INSERT INTO test_enum
VALUES(NULL);
SELECT*FROM test_enum;#没有限制字段非空,所以可以添加NULL

SET类型
在这里插入图片描述

#set类型
CREATE TABLE IF NOT EXISTS test_set(
s SET('A','B','C')
);
INSERT INTO test_set(s) VALUES('A'),('A,B');#可多选的
SELECT*FROM test_set;
#插入重复的SET类型成员时,MySQL会自动删除重复的成员
INSERT INTO test_Set(s) VALUES('A,B,C,A');
SELECT*FROM test_set;#并没有重复A
#Data truncated for column 's' at row 1
INSERT INTO test_Set(s) VALUES('A,B,C,D');
SELECT *
FROM test_set;#并没有D
#结合使用
CREATE TABLE temp_mu1(
gender ENUM('男','女'),
hobby SET('吃饭','睡觉','躺着','写代码')
);
INSERT INTO temp_mu1
VALUES('男','睡觉,躺着');
SELECT*FROM temp_mu1;
#只能选一个枚举值
INSERT INTO temp_mu1
VALUES('男,女','睡觉,躺着');#Data truncated for column 'gender' at row 1

二进制字符串类型

在这里插入图片描述
在这里插入图片描述

#BINARY与VARBINARY
CREATE TABLE test_binary1(
f1 BINARY,#默认1
f2 BINARY(3),
#f3 VARBINARY 和VARCHAR一样,必须指定长度
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('abc');
INSERT INTO test_binary1(f2,f4)
VALUES('ab','ab');
SELECT * FROM test_binary1;
SELECT LENGTH(f2),LENGTH(f4)
FROM test_binary1;#和CHAR于VARCAHR去呗不大

BLOB类型
在这里插入图片描述
在这里插入图片描述

#blob类型
CREATE TABLE IF NOT EXISTS test_blob1(
id INT,
img MEDIUMBLOB
);
INSERT INTO test_blob1(id)
VALUES(1001);
SELECT*FROM test_blob1;

在这里插入图片描述
上面是通过SQLYong的操作添加的图片

JSON类型
在这里插入图片描述

#json
CREATE TABLE test_json(
js json
);
INSERT INTO test_json(js)
#格式 key:valye
VALUES('{"name":"songhk","age":18,"address":{"province":"beijing","city":"beijing"}}');
SELECT js -> '$.name' AS `NAME`,js -> '$.age' AS age,js -> '$.address.province' AS province,
js -> '$.address.city' AS city
FROM test_json;

空间类型

小结及类型使用建议

在这里插入图片描述

约束

数据完整性与约束的分类

#约束
#如何查看表中的约束
SELECT*FROM information_schema.`TABLE_CONSTRAINTS`
WHERE table_name = '表名称';#语法格式
SELECT*FROM information_schema.`TABLE_CONSTRAINTS`
WHERE table_name = 'employees';

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

非空约束

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

CREATE DATABASE dbtest13;
USE dbtest13;
#NOT NULL(非空约束)
#在CREATE TABLE时添加约束
CREATE TABLE test1(
id INT NOT NULL,
last_name VARCHAR(15) NOT NULL,
email VARCHAR(25),
salary DECIMAL(10,2)
);
DESC test1;
INSERT INTO test1(id,last_name,email,salary)
VALUES(1,'TOM','tom@126.com',3400);
SELECT*FROM test1;
#Column 'last_name' cannot be null 非空约束
INSERT INTO test1(id,last_name,email,salary)
VALUES(2,NULL,'tom@126.com',3400);
SELECT*FROM test1;
#Column 'id' cannot be null 非空约束
INSERT INTO test1(id,last_name,email,salary)
VALUES(NULL,'Jerry','jerry@126.com',3400);
#错误代码: 1364
#Field 'last_name' doesn't have a default value
#如果没有赋值,则会先去查看该字段是否有默认值存在
INSERT INTO test1(id,email)
VALUES(2,'abc@126.com');
UPDATE test1
SET email = NULL
WHERE id = 1;
#Column 'last_name' cannot be null
UPDATE test1
SET last_name = NULL
WHERE id = 1;
#在ALTER TABLE时添加约束
SELECT*FROM test1;
DESC test1;
#Invalid use of NULL value 存在NULL值
ALTER TABLE test1
MODIFY email VARCHAR(25) NOT NULL;#有一条记录,email此时是空值
DESC test1;
UPDATE test1
SET email = 'tom@126.com'
WHERE id = 1;
ALTER TABLE test1
MODIFY email VARCHAR(25) NOT NULL;
DESC test1;#如果有多条记录,只要有一个是NULL值,就不允许修改
#在ALTER TABLE时删除约束
ALTER TABLE test1
MODIFY email VARCHAR(25) NULL;
DESC test1;#可以看到NULL从NO变成了YES

唯一性约束

用来限制某个字段的值不能重复
在这里插入图片描述
在这里插入图片描述
关键字:UNQIUE
特点
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#unique(唯一约束)
#列级约束 vs 表级约束
#列级约束:将此约束声明在对应的字段后面
#表级约束:将表中所有的字段都声明完,在所有字段的后面声明的约束
#在CREATE TABLE时添加约束
CREATE TABLE test2(
id INT UNIQUE,#id普遍都是唯一非空的 列级约束
last_name VARCHAR(15),
#email varchar(25) unique,邮箱一般都是唯一的
email VARCHAR(25),
salary DECIMAL(10,2),#工资不唯一
#表级约束
#这单词好记着呢:con(包含头)str(字符串缩写)a(变量a)int(整形) str a int a = straint
#这名字含义:uk(unique约束)_test2(表名)_email(字段名)
CONSTRAINT uk_test2_eamil UNIQUE(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);
SELECT * FROM test2;#添加成功
#刻意不修改id字段
#错误代码: 1062
#Duplicate entry '1' for key 'id' 
INSERT INTO test2(id,last_name,email,salary)
VALUES(1,'Tom','tom1@126.com',4600);
#刻意不修改email字段
#错误代码: 1062
#Duplicate entry 'tom@126.com' for key 'uk_test2_eamil'
INSERT INTO test2(id,last_name,email,salary)
VALUES(1,'Tom1','tom@126.com',4600);
INSERT INTO test2(id,last_name,email,salary)
VALUES(2,'Tom1',NULL,4600);#传入NULL
SELECT*FROM test2;#唯一约束允许出现多个NULL值
DESC test2;
INSERT INTO test2(id,last_name,email,salary)
VALUES(3,'Tom2',NULL,4600);#传入NULL 仍然没有问题
#在ALTER TABLE时添加约束
DESC test2;
#先将不是唯一的值修改掉
UPDATE test2
SET salary = 5000
WHERE id = 3;
#方式1:添加形式
ALTER TABLE test2
ADD CONSTRAINT uk_test2_sal UNIQUE(salary);#add unique(salary)
DESC test2;#可以看到salary的key有了一个UNI的属性
#方式2:修改形式
ALTER TABLE test2
MODIFY last_name VARCHAR(15) UNIQUE;#有点像列级约束的形式
DESC test2;#可以看到last_name的key有了一个UNI的属性
#复合的唯一性约束
CREATE TABLE `USER`(
id INT,
`name` VARCHAR(15),
`password` VARCHAR(25),
#表级约束(其实只能用表级约束来声明复合约束)
CONSTRAINT uk_user_name_password UNIQUE(`name`,`password`)
);
DESC `USER`;
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) UNIQUE KEY,#电话
carid CHAR(18) UNIQUE KEY#身份证号
);
#课程表
CREATE TABLE course(
cid INT,#课程编号
cname VARCHAR(20)#课程名称
);
#选课表
CREATE TABLE student_course(
id INT,
sid INT,
cid INT,
scoure 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),#本表id 学生id 选课id 成绩
(2,1,1002,90),
(3,2,1001,88),
(4,2,1002,56);#成功
SELECT * FROM student_course;
#Duplicate entry '2-1002' for key 'sid'
INSERT INTO student_course VALUES
(5,2,1002,67);#不可以再次添加成绩 --> 复合约束
#-----------------------------------------------
#删除唯一性约束
#必须通过索引来删除,关键词为唯一索引名,和设置的约束名相同
#如果没有指定则和字段名相同,如果是复合函数,则以()中第一个字段名来命名
#先查看表中的约束
SELECT * FROM information_schema.`TABLE_CONSTRAINTS`
WHERE table_name = 'student_course';
SELECT * FROM information_schema.`TABLE_CONSTRAINTS`
WHERE table_name = 'test2';
#我们去删除test2的唯一约束,这个表里全部都是唯一约束
DESC test2;
SHOW CREATE TABLE test2;
#可以通过show index from 表名称;查看表的索引
SHOW INDEX FROM test2;
ALTER TABLE test2
DROP INDEX uk_test2_sal;
ALTER TABLE test2
DROP INDEX last_name;
SELECT * FROM information_schema.`TABLE_CONSTRAINTS`
WHERE table_name = 'test2';
SHOW INDEX FROM test2;

主键约束

在这里插入图片描述
也可以这么理解,主键用于唯一标识某一条记录,所以主键是绝对不可以为空或者重复的
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

USE dbtest13;
#主键约束
#PRIMARY KEY 
#primary key
#在CREATE TABLE时添加约束
CREATE TABLE test3(
id INT PRIMARY KEY,
last_name VARCHAR(15) PRIMARY KEY, #一个表中最多只能有一个主键约束
salary DECIMAL(10,2),
email VARCHAR(25)
);0
#主键约束特征:非空且唯一,用于唯一的标识条中的一条记录
CREATE TABLE test4(
id INT PRIMARY KEY,#列级约束创建
last_name VARCHAR(15),#primary key 一个表中最多只能有一个主键约束
salary DECIMAL(10,2),
email VARCHAR(25)
);
CREATE TABLE test5(
id INT,#
last_name VARCHAR(15),#primary key 一个表中最多只能有一个主键约束
salary DECIMAL(10,2),
email VARCHAR(25),
#表级约束	
CONSTRAINT pk_test5_id PRIMARY KEY(id)
);
SELECT * FROM information_schema.`TABLE_CONSTRAINTS`#PRIMARY KEY
WHERE table_name = 'test4';#PRIMARY
SELECT * FROM information_schema.`TABLE_CONSTRAINTS`#PRIMARY KEY
WHERE table_name = 'test5';#PRIMARY
INSERT INTO test4(id,last_name,salary,email)
VALUES(1,'Tom',4500,'tom@126.com');
SELECT * FROM test4;
#Duplicate entry '1' for key 'PRIMARY' 重复
INSERT INTO test4(id,last_name,salary,email)
VALUES(1,'Tom',4500,'tom@126.com');
#Column 'id' cannot be null 不能为NULL
INSERT INTO test4(id,last_name,salary,email)
VALUES(NULL,'Tom',4500,'tom@126.com');
CREATE TABLE `USER1`(
id INT,
`name` VARCHAR(15),
`password` VARCHAR(15),
PRIMARY KEY(`name`,`password`)
);
INSERT INTO `USER1`
VALUES(1,'Tom','abc');
INSERT INTO `USER1`
VALUES(1,'Tom1','abc');
SELECT * FROM `USER1`;
#Column 'name' cannot be null
INSERT INTO `USER1`
VALUES(1,NULL,'abc');
#在ALTER TABLE时添加约束
CREATE TABLE test6(
id INT,
last_name VARCHAR(15),
salary DECIMAL(10,2),
email VARCHAR(25)
);
DESC test6;
#为id添加主键约束
ALTER TABLE test6
ADD PRIMARY KEY(id);
DESC test6;
#删除主键约束(实际开发中,根本不会删除主键)
ALTER TABLE test6
DROP PRIMARY KEY;
DESC test6;

主键列自增策略

在这里插入图片描述
在这里插入图片描述

#主键列自增
#AUTO_INCREMENT
#auto_increment
/*
CREATE TABLE test7(
id int auto_increment,
last_name varchar(15) UNIQUE AUTO_INCREMENT
);
*/
CREATE TABLE test7(
id INT PRIMARY KEY AUTO_INCREMENT,
last_name VARCHAR(15)
);
INSERT INTO test7(last_name)
VALUES('Tom');#id不指定,默认自增从1开始
SELECT * FROM test7;#当我们向主键(包含AUTO_CREMENT)的字段上添加0或者NULL时,实际上会自动的往上添加指定的自增值
INSERT INTO test7(id,last_name)
VALUES(10,'Tom');
SELECT * FROM test7;
INSERT INTO test7(id,last_name)
VALUES(4,'Tom');
SELECT * FROM test7;
INSERT INTO test7(last_name)
VALUES('Tom');
SELECT * FROM test7;#并不能回溯自增长的值
#在ALTER TABLE时添加
CREATE TABLE test8(
id INT PRIMARY KEY,
last_name VARCHAR(15)
);
DESC test8;
ALTER TABLE test8
MODIFY id INT AUTO_INCREMENT;
DESC test8;
#在ALTER TABLE时删除
ALTER TABLE test8
MODIFY id INT;
DESC test8;

MySQL8.0新特性-自增变量的持久化
在5.7中演示
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
5.7重启服务器后,自增列会重新获取自增列值,根据表最后的自增列取值

在8.0中演示

在这里插入图片描述
5.7是放在内存中维护的,而8.0是放在一个重做日志里,是持久化的
在这里插入图片描述

外键约束

FOREIGN KEY
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#MySQL8.0新特性-自增变量的持久化
#foreign key(外键约束)
#在CREATE TABLE时添加
#主表和从表:父表和子表
#*-------------
#①先创建主表
CREATE TABLE dept1(
dept_id INT,
dept_name VARCHAR(15)
);
#②再创建从表
#④创建
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)#REFERENCES -> 参照
);#要求从表参照主表的字段必须是主键
#上述操作报错,因为主表中dept_id上没有主键约束或唯一行约束
#③添加
ALTER TABLE dept1
ADD PRIMARY KEY (dept_id);
DESC dept1;
DESC emp1;
#演示外键效果
/*
Cannot add or update a child row: 
a foreign key constraint fails 
(`dbtest13`.`emp1`, CONSTRAINT `fk_emp1_dept_id` FOREIGN KEY (`department_id`) 
REFERENCES `dept1` (`dept_id`))

*/
INSERT INTO emp1
VALUES(1001,'Tom',10);
#为主表增加参照字段值
INSERT INTO dept1
VALUES(10,'IT');
#重新插入数据
INSERT INTO emp1
VALUES(1001,'Tom',10);
SELECT * FROM emp1;
#不能直接删除主表的数据,要先删除从表的数据
#Cannot delete or update a parent row: a foreign key CONSTRAINT fails
#删除失败
DELETE FROM dept1
WHERE dept_id = 10;
#更新失败
UPDATE dept1
SET dept_id = 20
WHERE dept_id = 10;#同上
#在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'; 	
#删除外键约束
#一个表可以声明有多个外键约束
USE atguigudb;
SELECT * FROM information_schema.`TABLE_CONSTRAINTS`
WHERE table_name = 'employees'; 
#---------------------------
USE dbtest13;
SELECT * FROM information_schema.`TABLE_CONSTRAINTS`
WHERE table_name = 'emp1'; 
ALTER TABLE emp1
DROP FOREIGN KEY fk_emp1_dept_id;
SELECT * FROM information_schema.`TABLE_CONSTRAINTS`
WHERE table_name = 'emp1'; 
#再手动的删除外键约束对应的普通索引
SHOW INDEX FROM emp1;
ALTER TABLE emp1
DROP INDEX fk_emp1_dept_id;
SHOW INDEX FROM emp1;

应用场景
在这里插入图片描述
在这里插入图片描述

检索约束与默认值约束

CHECK约束
在这里插入图片描述

#check约束
CREATE TABLE test10(
id INT,
last_name VARCHAR(15),
salary DECIMAL(10,2) CHECK(salary > 2000)
);
INSERT INTO test10
VALUES(1,'Tom1',2500);
INSERT INTO test10
VALUES(2,'Tom1',1500);#如果是8.0就会添加失败
SELECT*FROM test10;
DESC test10;

default约束

#DEFAULT约束
#在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);
SELECT * FROM test11;
INSERT INTO test11(id,last_name)
VALUES(2,'Tom1');
SELECT * FROM test11;#默认值是2000,没有赋值就是2000
#在ALTER TABLE添加约束
CREATE TABLE test12(
id INT,
last_name VARCHAR(15),
salary DECIMAL(10,2)
);
DESC test12;
ALTER TABLE test12
MODIFY salary DECIMAL(10,2) DEFAULT 2500;
DESC test12;
#在ALTER TABLE删除约束
ALTER TABLE test12
MODIFY salary DECIMAL(8,2);
DESC test12;

扩展
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

视图

什么是数据库对象?

在这里插入图片描述

视图的理解

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

创建视图

在这里插入图片描述
在这里插入图片描述

#准备工作
CREATE DATABASE dbtest14;
USE dbtest14;
CREATE TABLE emps
AS 
SELECT *
FROM atguigudb.`employees`;
CREATE TABLE depts
AS 
SELECT *
FROM atguigudb.`departments`;
#如何创建视图
#针对于单表
#下面就是创建了一个视图
#情况1:视图中的字段与基表的字段有对应关系
CREATE VIEW vu_emp1
AS
SELECT employee_id,last_name,salary
FROM emps;

#查看视图
SELECT*FROM vu_emp1;
#确实视图中字段名的方式1:
CREATE VIEW vu_emp2
AS
SELECT employee_id emp_id,last_name lname,salary#查询语句中,字段的别名会作为视图中字段的名称出现
FROM emps
WHERE salary > 8000;

SELECT * FROM vu_emp2;
#确定视图中字段名的方式2:
CREATE VIEW vu_emp3(emp_id,`name`,monthly_sal)#类型和个数必须相同
AS
SELECT employee_id,last_name,salary
FROM emps
WHERE salary > 8000;

SELECT*FROM vu_emp3;

#情况2:视图中的字段在基表中可能没有对应的字段
CREATE VIEW vu_emp_sal
AS
SELECT department_id,AVG(salary) avg_sal
FROM emps
WHERE department_id IS NOT NULL
GROUP BY department_id;

SELECT*FROM vu_emp_sal;

#针对于多表
CREATE VIEW vu_emp_dept
AS
SELECT e.employee_id,e.department_id,d.department_name
FROM emps e JOIN depts d
ON e.department_id = d.department_id

SELECT * FROM vu_emp_dept;

#利用视图对数据进行格式化
CREATE VIEW vu_emp_dept1
AS
SELECT CONCAT(e.last_name,"(",d.department_name,')') emp_info
FROM emps e JOIN depts d
ON e.department_id = d.department_id

SELECT * FROM vu_emp_dept1;

#基于视图创建视图
CREATE VIEW vu_emp4
AS
SELECT employee_id,last_name
FROM vu_emp1;

SELECT *
FROM vu_emp4;

#查看视图
#语法1:查看数据的表对象、视图对象
SHOW TABLES;#包含了表和视图
#语法2:查看视图的结构
DESC vu_emp1;
#语法3:查看视图的属性信息
SHOW TABLE STATUS LIKE 'vu_emp1';	
#语法4:查看视图的详细定义信息
SHOW CREATE VIEW vu_emp1;

更新视图数据与视图的删除

#先查看基表和视图中的数据,此时101号员工的工资
SELECT * FROM vu_emp1;
#基表或视图它们修改都会互相影响
SELECT employee_id,last_name,salary
FROM emps;
#更改视图中101号员工工资为20000,查询基表和视图发现都修改为了20000
UPDATE vu_emp1
SET salary = 20000
WHERE employee_id = 101;
#更改基表中101号员工工资为10000,查询视图和基表发现都修改为了10000
UPDATE emps
SET salary = 10000
WHERE employee_Id = 101;

DELETE FROM vu_emp1
WHERE employee_id = 101;#复制的表并没有复制来外键约束等等,可以直接删除
#先查看基表和视图中的数据,此时101已被删除
SELECT * FROM vu_emp1;
#基表或视图它们修改都会互相影响
SELECT employee_id,last_name,salary
FROM emps;
#上面一般情况下都是可以执行成功的


#不能更新视图中的数据
SELECT * FROM vu_emp_sal;

UPDATE vu_emp_sal
SET avg_sal = 5000;#The target table vu_emp_sal of the UPDATE is not updatable
DELETE FROM vu_emp_sal
WHERE department_id = 30;

#修改视图
DESC vu_emp1

#方式1
CREATE OR REPLACE VIEW vu_emp1
AS
SELECT employee_id,last_name,salary,email
FROM emps
WHERE salary > 7000;
DESC vu_emp1;

#方式2:
ALTER VIEW vu_emp1
AS
SELECT employee_id,last_name,salary,hire_date
FROM emps
DESC vu_emp1;

#删除视图
DESC vu_emp4;
DROP VIEW vu_emp4;
SHOW TABLES;
DROP VIEW vu_emp2,vu_emp3;
SHOW TABLES;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

视图练习
#视图练习
USE dbtest14;
#练习1:
#1.使用表emps创建视图employee_vu,其中包括姓名(LAST_NAME),员工号(EMPLOYEE_ID),部门号(DEPARTMENT_ID)
CREATE OR REPLACE VIEW employee_vu(lname,emp_id,dept_id)
AS
SELECT last_name,employee_id,department_id
FROM emps;
#2.显示视图的结构
DESC employee_vu;
#3.查询视图中的全部内容
SELECT * FROM employee_vu;
#4.将视图中的数据限定在部门号是80的范围内
CREATE OR REPLACE VIEW employee_vu(lname,emp_id,dept_id)
AS
SELECT last_name,employee_id,department_id
FROM emps
WHERE department_id = 80;
#查看
SELECT * FROM employee_vu;


#练习2:
#1.创建视图emp_v1,要求查询电话号码以'011'开头的员工姓名和工资、邮箱
CREATE OR REPLACE VIEW emp_v1
AS
SELECT last_name,salary,email
FROM emps
WHERE phone_number LIKE '011%';
#2.要求将视图emp_v1修改为查询电话号码以'011'开头的并且邮箱中包含e字符的员工姓名和邮箱、电话号码
CREATE OR REPLACE VIEW emp_v1
AS
SELECT last_name,email,phone_number,salary
FROM emps
WHERE phone_number LIKE '011%' AND email LIKE '%e%';
SELECT*FROM emp_v1;
#3.向emp_v1插入一条记录,是否可以?
DESC emps;#非空约束,不允许插入NULL
INSERT INTO emp_v1#Field of view 'dbtest14.emp_v1' underlying table doesn't have a default value
VALUES('Tom','tom@126.com','01012345');
#4.修改emp_v1中员工的工资,每人涨薪1000
UPDATE emp_v1
SET salary = salary + 1000;
SELECT * FROM emp_v1;
#5.删除emp_v1中姓名为Olsen的员工
DELETE FROM emp_v1#如果有外键不一定能删
WHERE last_name = 'Olsen';
#6.创建视图emp_v2,要求查询部门的最高工资高于12000的部门id和其最高工资
CREATE OR REPLACE VIEW emp_v2(dept_id,max_sal)
AS
SELECT department_id,MAX(salary)
FROM emps
GROUP BY department_id
HAVING MAX(salary) > 12000;
SELECT * FROM emp_v2;
#7.向emp_v2中插入一条记录,是否可以?
INSERT INTO emp_v2(dept_id,max_sal)
VALUES(4000,20000);#The target table emp_v2 of the INSERT is not insertable-into
#8.删除刚才的emp_v2和emp_v1
DROP VIEW IF EXISTS emp_v1,emp_v2;
SHOW TABLES;

存储过程与存储函数

在这里插入图片描述

存储过程使用说明

在这里插入图片描述
在这里插入图片描述
特征
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
需要使用DILIMITER的原因是,首先我们在存储过程里定义多条不同的SQL语句,并且这些语句也都是需要分号来结束的,但是如果我们没有设置分隔符的话,到了第一条SQL语句结束就直接结束存储过程了,就会直接报错,所以我们需要区分开SQL语句结束和存储过程结束
在这里插入图片描述

存储过程的创建与调用

#存储过程的创建与调用
#0.准备工作
CREATE DATABASE dbtest15;
USE dbtest15;

CREATE TABLE employees
AS
SELECT * 
FROM atguigudb.`employees`;
CREATE TABLE departments
AS
SELECT *
FROM atguigudb.`departments`;
DESC employees;DESC departments;
#1.创建存储过程
#举例1:创建存储过程select_all_data(),查看emps表的所有数据
DELIMITER $
CREATE PROCEDURE select_all_data()
BEGIN
	SELECT * FROM employees;
END $ 
DELIMITER ;
#存储过程里不可以有注释
#上面第一行先将结束符号设置为美元符号,然后创建存储过程的begin end里表示存储了一条SQL语句,为了不让该语句默认结束,所以修改了结束符号
#在存储完后,再将结束符号修改回分号,调用存储过程时,分号就生效了
#2.存储过程的调用
CALL select_all_data();#使用CALL关键字调用
#举例2:创建存储过程avg_employee_salary(),返回所有员工的平均工资
DELIMITER //
CREATE PROCEDURE abg_employee_salary()
BEGIN 
	SELECT AVG(salary)
	FROM employees;
END //
DELIMITER ;
CALL abg_employee_salary();
#举例3:创建存储过程show_max_salary(),用来查看"emps"表的最高薪资值
DELIMITER //
CREATE PROCEDURE show_max_salary()
BEGIN
	SELECT MAX(salary)
	FROM employees;
END //
DELIMITER ;
CALL show_max_salary();

#带 OUT
#举例4:创建存储过程show_min_salary(),查看"emps"表的最低薪资值。并将最低薪资值
#通过OUT参数"ms"输出
DELIMITER //
CREATE PROCEDURE show_min_salary(OUT ms DOUBLE)
BEGIN
	SELECT MAX(salary) INTO ms
	FROM employees;
END //
DELIMITER ;
#调用,需要传入输出的变量
CALL show_min_salary(@ms);
CALL show_min_salary(@ds);#可以不参数同名
SELECT @ds FROM DUAL;
SELECT @ms;

#带IN
#举例5:创建存储过程show_someone_salary(),查看"emps"表中的某个员工的薪资,并用IN参数empname输入员工姓名
DELIMITER //
CREATE PROCEDURE show_someone_salary(IN empname VARCHAR(20))
BEGIN
	SELECT salary 
	FROM employees
	WHERE last_name = empname;
END //
DELIMITER ;
#上面参数的格式 IN name type
#调用 IN
#调用方式1:	
CALL show_someone_salary('Abel');
#调用方式2:
SET @empname := 'Abel';#自定义变量用一个@符号 系统是2个@@
CALL show_someone_salary(@empname);
SET @name := 'Abel'; #冒号等于是明示的赋值符号
CALL show_someone_salary(@name);#形参名仍然可以随意,个数和类型对就行

#IN+OUT
#举例6:创建存储过程show_someone_salary2(),查看"emps"表的某个员工的薪资
#并用IN参数empname输入员工姓名,用OUT参数empsalary输出员工薪资
DELIMITER //
CREATE PROCEDURE show_someone_salary2(IN empname VARCHAR(20),OUT empsalary DOUBLE)
BEGIN
	SELECT salary INTO empsalary
	FROM employees
	WHERE last_name = empname;
END //
DELIMITER ;
#调用
SET @empname := 'Abel';#如果是King的话,会报错,因为有2个King
CALL show_someone_salary2(@empname,@empsalary);
SELECT @empname;
SELECT @empsalary;

#INOUT
#举例7:创建存储过程show_mgr_name(),查询某个员工领导的姓名
#并用INOUT参数"empname"输入员工姓名,输出领导的姓名
DELIMITER $$
CREATE PROCEDURE show_mgr_name(INOUT empname VARCHAR(25))
BEGIN
	SELECT last_name INTO empname
	FROM employees
	WHERE employee_id = (
		SELECT manager_id
		FROM employees
		WHERE last_name = empname
		);
END $$
DELIMITER ;
SET @empname := 'Abel';#想多行执行就一定要写个分号
CALL show_mgr_name(@empname);
SELECT @empname;
#合着就是一个变量两用 既是形参又是返回值,感觉比IN + OUT 要简洁点

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

存储函数的创建与调用

#存储函数
#举例1:创建存储函数,名称为email_by_name(),参数定义为空,
#该函数查询Abel的email,并返回,数据类型为字符串类型
#下面是需要添加的特性,特性也只是解决方式的一种
	#DETERMINISTIC -> 确定性的
	#CONTAINS SQL -> 包含SQL的
	#READS SQL DATA -> 可读SQL的数据
DELIMITER //
CREATE FUNCTION email_by_name()
RETURNS VARCHAR(25)
	DETERMINISTIC
	CONTAINS SQL
	READS SQL DATA
BEGIN
	RETURN( SELECT email FROM employees
	WHERE last_name = 'Abel');
	
END //
DELIMITER ;
#还可以通过 SET GLOBAL log_bin-trust_function_creators = 1;

#调用
SELECT email_by_name();
#举例2:创建存储函数,名称为email_by_id(),参数插入emp_id,该函数查询emp_id的email
#并返回,数据类型为字符串型
#创建函数前,执行此语句,保证函数的创建会成功
SET GLOBAL log_bin_trust_function_creators = 1;

DELIMITER //
CREATE FUNCTION email_by_id(emp_id INT)
RETURNS VARCHAR(25)
BEGIN
	RETURN(SELECT email 
	FROM employees
	WHERE employee_id = emp_id); 
END //
DELIMITER ;

#调用
SELECT email_by_id(101);
#变量
SET @emp_id := 102;
SELECT email_by_id(@emp_id);

#举例3:创建存储函数count_by_id(),参数传入dept_id,该函数查询dept_id部门的
#员工人数,并返回,数据类型为整形
DELIMITER //
CREATE FUNCTION count_by_id(dept_id INT)
RETURNS INT 
BEGIN
	RETURN(
		SELECT COUNT(*)
		FROM employees
		WHERE department_id = dept_id
	);
END //

DELIMITER ;
#调用
SELECT count_by_id(50);
SET @dept_id := 30;
SELECT count_by_id(@dept_id);

80P
在这里插入图片描述
在这里插入图片描述

存储过程与存储函数的查看修改和删除

#存储过程、存储函数的查看
#1.使用SHOW CREATE语句查看存储过程和函数的创建信息
SHOW CREATE PROCEDURE show_mgr_name;

SHOW CREATE FUNCTION count_by_id;
#2.使用SHOW STATUS语句查看存储过程和存储函数的状态信息
SHOW PROCEDURE STATUS;#会全部列举出来

SHOW PROCEDURE STATUS LIKE 'show_max_salary';#模糊查询

SHOW FUNCTION STATUS LIKE 'email_by_id';
#3.从information_schema.Routines表查看存储过程和函数的信息
SELECT * FROM information_schema.`ROUTINES`
WHERE ROUTINE_NAME = 'email_by_id' AND ROUTINE_TYPE = 'FUNCTION'; #区分大小写的

SELECT * FROM information_schema.`ROUTINES`
WHERE ROUTINE_NAME = 'show_min_salary' AND ROUTINE_TYPE = 'PROCEDURE'; 

#存储过程、存储函数的修改
ALTER PROCEDURE show_max_salary
SQL SECURITY INVOKER
COMMENT '查询最高工资';

#删除
DROP FUNCTION IF EXISTS count_by_id;
DROP PROCEDURE IF EXISTS show_min_salary;

扩展

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

存储过程和存储函数练习

存储过程的练习

#存储过程和存储函数练习
#准备工作
CREATE DATABASE test15_pro_func;
USE test15_pro_func;
#1.创建存储过程insert_user(),实现传入用户名和密码,插入到admim表中
CREATE TABLE admin(
id INT PRIMARY KEY AUTO_INCREMENT,
user_name VARCHAR(15) NOT NULL,
pwd VARCHAR(25) NOT NULL
);
DELIMITER //
CREATE PROCEDURE insert_user(IN user_name VARCHAR(15),IN pwd VARCHAR(25))
BEGIN
	INSERT INTO admin(user_name,pwd)
	VALUES(user_name,pwd);
END //
DELIMITER ;
#调用
CALL insert_user('MP7','血腥运动-隐秘');
SET @user_name := 'P90';SET @pwd := '二西莫夫-隐秘';
CALL insert_user(@user_name,@pwd);
SELECT * FROM admin;
#2.创建存储过程get_phone(),实现传入女神编号,返回女神姓名和电话
CREATE TABLE beauty(
id INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(15) NOT NULL,
phone VARCHAR(15) UNIQUE,
birth DATE
);
INSERT INTO beauty(`name`,phone,birth)
VALUES
('朱茵','13201233453','1982-02-12'),
('孙燕姿','13501233653','1980-12-09'),
('东雪莲','13651238755','1983-08-21'),
('邓紫棋','17843283452','1991-11-12'),
('刘若英','18635575464','1989-05-18'),
('杨超越','13761238755','1994-05-11');
SELECT * FROM beauty;

DELIMITER //
CREATE PROCEDURE get_phone(IN id INT,OUT `name` VARCHAR(15),OUT phone VARCHAR(15))
BEGIN 
	SELECT b.`name`,b.phone INTO `name`,phone
 	FROM beauty b
	WHERE b.id = id;
END //
DELIMITER ;

#调用
CALL get_phone(1,@`name`,@phone);
SELECT @`name`,@phone;

#3.创建存储过程date_diff(),实现传入两个女神生日,返回日期即那个大小

DELIMITER //
CREATE PROCEDURE date_diff(IN birth1 DATE,IN birth2 DATE,OUT sum_date INT)
BEGIN 
	SELECT DATEDIFF(birth1,birth2) INTO sum_date;
END //
DELIMITER ;
#上面相当于写成了通用函数,结果不需要从任何表来

#调用
SET @birth1 := '1992-09-08';
SET @birth2 := '1992-10-30';
CALL `date_diff`(@birth1,@birth2,@sum_date);
SELECT @sum_date;

#4.创建存储过程format_date(),实现传入一个日期,格式化成xx年xx月xx日并返回

DELIMITER //
CREATE PROCEDURE format_date(IN my_date DATE,OUT str_date VARCHAR(25))
BEGIN
	SELECT DATE_FORMAT(my_date,'%y年%m月%d日') INTO str_date;
END //
DELIMITER ;

#调用
CALL format_date('1999-10-10',@str_date);
SELECT @str_date;

#5.创建存储过程beauty_limit(),根据传入的起始索引和条目数,查询女神表的记录
DELIMITER //
CREATE PROCEDURE beauty_limit(IN start_index INT,IN size INT)
BEGIN
	SELECT *
	FROM beauty
	LIMIT start_index,size;
END //
DELIMITER ;

#调用
CALL beauty_limit(1,4);

#创建带inout模式参数的存储过程
#6.传入a和b两个值,最终a和b都翻倍返回
DELIMITER //
CREATE PROCEDURE add_double(INOUT a INT,INOUT b INT)
BEGIN 
	SET a = a*2;
	SET b = b*2;
END //
DELIMITER ;

#调用
SET @a = 3,@b = 5;
CALL add_double(@a,@b);
SELECT @a,@b;

#7.删除题目5的存储过程
DROP PROCEDURE IF EXISTS beauty_limit;

#8.查看题目6中存储过程的信息
SHOW CREATE PROCEDURE add_double;

SHOW PROCEDURE STATUS LIKE 'add_double';

存储函数的练习

#存储函数的练习
#0.准备工作
USE test15_pro_func;
CREATE TABLE employees
AS
SELECT * FROM atguigudb.employees;
CREATE TABLE departments
AS
SELECT * FROM atguigudb.`departments`;

#无参返回
#1.创建函数get_count(),返回公司的员工个数
DELIMITER //
CREATE FUNCTION get_count()
RETURNS INT 
BEGIN 
	RETURN(SELECT COUNT(*) FROM employees);
END //
DELIMITER ;
#如果没有首次创建函数则需要去设置一下关于信息表的全局活动表函数创建的设置
#调用
SELECT get_count() FROM DUAL;#和普通函数调用没有区别

#有参返回
#2.创建函数ename_salary(),根据员工姓名,返回它的工资

DELIMITER //
CREATE FUNCTION ename_salary(last_name VARCHAR(15))
RETURNS DOUBLE
BEGIN 
	RETURN(SELECT salary 
	FROM employees e
	WHERE e.last_name = last_name);
END //
DELIMITER ;

#调用
SELECT ename_salary('Abel');

#3.创建函数dept_sal(),根据部门名,返回该部门的平均工资

DELIMITER //
CREATE FUNCTION dept_sal(dept_name VARCHAR(15))
RETURNS DOUBLE
BEGIN
	RETURN(SELECT AVG(e.salary)
	FROM employees e JOIN departments d
	ON e.department_id = d.department_id
	WHERE d.department_name = dept_name);
END //
DELIMITER ;

#调用
SELECT dept_sal('IT');

#4.创建函数add_float(),实现传入两个float,返回二者之和
DELIMITER //
CREATE FUNCTION add_float(value1 FLOAT,value2 FLOAT)
RETURNS FLOAT
BEGIN
	RETURN(SELECT value1+value2);
END //
DELIMITER ;

#调用
SELECT add_float(1,2);
SET @v1 := 1.2;
SET @v2 := 2.4;
SELECT add_float(@v1,@v2); 
变量

更多相关推荐


关于mysql数据类型为null的问题

发布时间:2022-11-16 MYSQL 数据库
select*fromuser_tablewherephonenotin('18277776666')假设总共三条数据,其中phone=null ,另外两条,有一条值 18277776666,有一条值 18277778888 结论:执行以上sql结果只出现一条数据,因为会先排除null的数据,再去检索...

sql常用函数day6

发布时间:2022-11-04 SQL 数据库
1.instr(string,substr,开始查找位置)//返回子串在字符串中的位置selectinstr('aythisisayhelloworldhowaboutyouay','ay',5,2)//从字符串的第5位开始查找第二个'ay'selectinstr('aythisisayhelloworldhowaboutyouay','ay',-5,2)//倒序即从右往左,从右开始第五个字符(即...

FreeSql 教程引导

发布时间:2019-05-23 数据库
FreeSql是一个功能强大的NETStandard库,用于对象关系映射程序(O/RM),以便于开发人员能够使用.NETStandard对象来处理数据库,不必经常编写大部分数据访问代码。特性支持CodeFirst迁移;支持DbFirst从数据库导入实体类,支持三种模板生成器;采用ExpressionTree高性能读取数据;支持深入的类型映射,比如pgsql的数组类型,堪称匠心制作;支持丰富的表达式...

hive函数大全

发布时间:2018-08-02 HIVE SPARKS SQL 大数据 SQL 函数
hive的内置方法很多,特被容易忘,记录在次方便使用。1.内置运算符1.1关系运算符运算符类型说明A=B所有原始类型如果A与B相等,返回TRUE,否则返回FALSE。A&lt;&gt;B所有原始类型如果A不等于B返回TRUE,否则返回FALSE。如果A或B值为”NULL”,结果返回”NULL”。A!=B所有原始类型如果A不等于B返回TRUE,否则返回FALSE。如果A或B值为”NULL”,结果返回...

SQLServer 实现行转列

发布时间:2013-01-11 数据库
createtableAllScore(idintidentity(1,1)primarykey,--主键stu_namevarchar(20),--学生名categoryvarchar(20),--学科recordfloat,--成绩)/*插入数据*/insertintoAllScore(stu_name,category,record)values('刘德华','Chinese',100)in...

SQLServer中将字符串的列转行和行转列

发布时间:2022-11-21 SQLSERVER 数据库
/*如讲以某个字符相隔的字符串转换为表如字符串Nothing,isimpossible,to,a,willing,heart--列转行select*fromudf_ConvertStrtoTable('Nothing,isimpossible,to,a,willing,heart',',')--行转列select*into#tempfromudf_ConvertStrtoTable('Nothin...

Redis数据结构之list

发布时间:2022-11-21 REDIS 数据库
        redis的列表的数据类型可以被看做的简单的字符创列表,列表按照插入的顺序的顺序进行排列,在操作的Redis的列表的时候,可以讲一个元素插入到这个的列表的头部或者尾部。向链表中插入值    LPUSH:将多个值插入到链表头部LPUSHkeyvalue[value...]LPUSH命令将一个或者多个value值插入列表key的头部,如果同时插入多个value值,那么各个value值会...

Redis数据结构之Set

发布时间:2022-11-21 NOSQL REDIS 数据库
        Redis的数据类型是string类型的无序集合,集合无序并且不能存在的重复的元素,集合是通过hash实现的,所以使用集合进行的添加、删除、查询的效率比较高的。向集合中添加元素SADD:添加多个元素到的集合中SADDKEYmember[member...]SADD命令用于讲一个或者多个的member元素添加到的集合的key中,如果集合中存在对应的member那么将会忽略该对象。 S...

Grafana+MySQL(4)grafana展示mysql表数据:生成折线图

发布时间:2022-11-22 MYSQL GRAFANA 数据库
背景grafana展示mysql源数据,且以折线形式展示。MySQL表内数据格式如下:折线图只需要各个接口的point_time对应的rps和99分位响应时间,其他字段可忽略。添加折线图Dashboard添加panel,右侧菜单选择TimeSeries,添加Query,选择MySQL数据源,选择SQLEdit模式,输入SQL语句SQL如下:SELECTdate_sub(point_time,int...

插入 更新 删除

发布时间:2015-12-15 数据库
原文链接:http://www.cnblogs.com/lyhabc/p/3776000.html将多行查询结果插入到表中语法INSERTINTOtable_name1(column_list1)SELECT(column_list2)FROMtable_name2WHERE(condition)INSERTINTOSELECT在SQLSERVER里也是支持的table_name1指定待插入数据的...

mysql之插入、更新、删除

发布时间:2016-02-18 MYSQL LEARNING 基本语法
插入将多行查询结果插入到表中语法INSERTINTOtable_name1(column_list1)SELECT(column_list2)FROMtable_name2WHERE(condition)INSERTINTOSELECT在SQLSERVER里也是支持的table_name1指定待插入数据的表;column_list1指定待插入表中要插入数据的哪些列;table_name2指定插入数...

MySQL系统表information_schema.INNODB_TRX详解及查看当前运行事务

发布时间:2022-11-23 MYSQL 数据库
1.目的在日常管理数据库的过程中,有时需要查询MySQL数据库是否正在有正在执行的事务,便于排查业务问题。MySQL的系统库表有数据维护对应的信息,就在information_schema库中的INNODB_TRX表,包含事务中是否存在锁,事务开启时间,事务执行的语句等等。2.说明2.1查询正在执行的事务SELECT*FROMinformation_schema.innodb_trx;2.2详细字...

项目中我为什么用Mongodb取代Mysql

在项目设计的初期,我当时有了这样的想法,同时也是在满足下面几个条件的情况下来选择最终的nosql方案的:1、需求变化频繁:开发要更加敏捷,开发成本和维护成本要更低,要能够快速地更新进化,新功能要在最短的周期内上线。2、客户端/api支持,因为这直接影响开发效率3、部署简单4、扩展能力强5、节省系统资源,对cpu等资源耗费较小满足这些要求的nosql方案,就剩下了mongodb和redis了,对于r...

mysql 差异备份和恢复

发布时间:2021-05-06 MYSQL 备份和恢复
备份[root@localhostdata]#mysqldump-uroot-pmei1206--single-transaction--flush-logs--master-data=2--all-databases--delete-master-logs&gt;all-20210506123.sql修改之前mysql&gt;select*fromstudent;+------+-------+...

面试官: B 树和 B+ 树有什么区别?

发布时间:2022-11-23 JAVA编程 数据库 ORACLE JAVA面试 JAVA MONGODB
问各位小可爱一个问题:MySQL中B树和B+树的区别?请自己先思考5秒钟,看看是否已经了然如胸? 好啦,时间到!B树和B+树是两种数据结构,构建了磁盘中的高速索引结构,因此不仅MySQL在用,MongoDB、Oracle等也在用,基本属于数据库的标配常规操作。数据库要经常和磁盘与内存打交道,为了提升性能,通常需要自己去构建类似文件系统的结构。今天主要来看看数据库是如何利用磁盘空间设计索引的?行存储...

SQLServer 远程备份和恢复

发布时间:2007-12-10 数据库 SQLSERVER CMD ASP.NET SQL
--以下语句要在查询分析器中逐步逐句执行,删除注释标识"--"执行,完了再加上"--",接着执行下一句--第一步: 在备份机建立共享文件夹 在程序代码中调用(或者CMD窗口)--master..xp_cmdshell 'md D:/SqlBak'--master..xp_cmdshell 'net share SqlBak=D:/SqlBak'--第二步: 建立共享信用关系--exec maste...

[附源码]java毕业设计学校失物招领系统

发布时间:2022-11-23 JAVA MYSQL 开发语言
项目运行环境配置:Jdk1.8+Tomcat7.0+Mysql+HBuilderX(Webstorm也行)+Eclispe(IntelliJIDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:SSM+mybatis+Maven+Vue等等组成,B/S模式+Maven管理等等。环境需要1.运行环境:最好是javajdk1.8,我们在这个平台上运行的。其他版本理论上也可以。2.ID...

命令行如何远程连接MySQL数据库

发布时间:2013-01-11 LINUX 数据库
新使用MySQL,说起来是个简单的事情,但是却费了些周折:1、登陆服务器端,进入命令行,windowscmd;2、设置用户、密码让指定的IP访问:mysql-uroot-p或安装的快捷方式进入:MySQLCommandLineClient,使用grant命令:grant权限1,权限2,…权限non数据库名称.表名称to用户名@用户地址identifiedby'连接口令';例子:mysql&gt;g...

SQL Story摘录(一)————简单查询初探

发布时间:2002-06-06 数据库
在CSDN上回贴时,我总是苦口婆心地劝告楼上楼下的朋友们多用联接。可响应甚微。往往一个简单的功能,也一定要写成子查询或游标,弄得非常复杂冗长。的确,这样写对于初学者来说,费力不费脑,思路比较好理解。所以往往得分的也是这些回贴。可事实上,如果你真正熟悉了SQL的编程风格,你会明白,联接查询才是最直接、最清晰、最有力的方法,而更好的办法就是无招胜有招,一条简单查询结束战斗。下面我举几个例子来证明一下这...

SQL Server性能优化(1)使用SET函数

发布时间:2017-07-28 SERVER SQL
在一切开始之前,先看下微软的建议:在系统的整体性能优化里面,TSQL优化优先级并不是最高的。本文包括四部分:SETSTATISTICSTIMEONSETSTATISTICSIOSETSHOWPLAN_ALLONSETSTATISTICSPROFILEONSET函数主要是为了显示sql执行时的查询计划,CPU、硬盘使用情况。1.SETSTATISTICSTIMEON:当SETSTATISTICSTI...

ASP.NET数据库连接字符串总结

发布时间:2012-04-25 数据库
  一、使用OleDbConnection对象连接OLEDB数据源1.连接Access数据库Access2000:“provider=Microsoft.Jet.Oledb.3.5;DataSource=Access文件路径”Access2003:“provider=Microsoft.Jet.Oledb.4.0;DataSource=Access文件路径”Access2007:“provider...

Day07-mysql基础篇之实用的sql语句

发布时间:2022-11-09 MYSQL SQL 数据库
插入或者替换如果我们需要插入一条新的记录,如果记录已经存在,就先删除原纪录,再插入新纪录,此时可以使用replace语句,这样就不必先查询再决定是不是删除再插入。根据主键id判断--插入或者替换--replaceinto`students`(id,class_id,name,gender,score)values(1,1,'小明','F',99);插入或者更新如果我们希望插入一条新记录,但如果记录...

SQL语句熟悉

发布时间:2015-09-28 语句 SQL
createtableStudent(Snochar(7)primarykey,Snamechar(10)notnull,Ssexchar(2),Sagetinyint,Sdeptchar(20))engine=innodbdefaultcharset=utf8auto_increment=1;createtableCourse(Cnochar(6)notnulldefault'000000',C...

关于MySQL并发控制的基础,你知道吗?

发布时间:2022-11-16 MYSQL 数据库
MySQL并发控制无论何时,只要有多个查询需要在同一时刻修改数据,就会存在并发控制的问题。MySQL在这两个层面上就进行了并发控制,分别是服务器层和存储引擎层。下面举一个简单的例子,在发送邮件的时候,可能单条邮件发送很正常,不会出什么问题,仅仅是一条接着一条这样来实现发送,但是在并发环境下,却不会是想象中的那么简单。假设这样一种可能,有两个进程同时对同一个邮箱来投递邮件,会发生什么情况呢?显然,邮...

server sql的时间格式化

发布时间:2019-08-16 数据库
SELECTCONVERT(varchar(100),GETDATE(),0)05920119:12AMSELECTCONVERT(varchar(100),GETDATE(),1)05/09/11SELECTCONVERT(varchar(100),GETDATE(),2)11.05.09SELECTCONVERT(varchar(100),GETDATE(),3)09/05/11SELECTC...

Oracle AQ 使用

发布时间:2010-11-22 数据库 PROPERTIES ORACLE OBJECT JAVA USER
本文转自:http://blog.itpub.net/category/32506/function.mysql-pconnect 随着不同应用模块间的消息交互和通信成为一个关键的功能,并且变得越来越重要。Oracle引入了一种强大的队列机制,通过它程序间可以实现信息的交互,oracle把它称作为AQ-AdvancedQueuing.使用OracleAQ,我们不需要安装额外的中间件,它是Oracl...

【Mysql】主从一致

发布时间:2022-11-22 MYSQL 服务器 数据库
(一)主从复制【1】什么是主从复制mysql的主从复制是指数据可以从一个mysql数据库服务器主节点复制到一个或者多个从节点。mysql默认采用异步复制方式,这样从节点不用一致访问主服务器来更新自己的数据,数据的更新可以在远程链接上进行,从节点可以复制主数据库中的所有数据库或者特定的数据库,或者特定的表。【2】为什么需要主从复制(1)在业务复杂的系统中,有这么一个情景,有一句sql语句需要锁表,导...

ORACLE_AQ 队列

发布时间:2015-11-25 数据库
OracleAQDemo,StepbyStep我准备用AQ来做一个数据仓库系统,提交分析任务队列。有以下需求:1.利用通知异步的执行存储过程2.设定队列大小极限3.出列即删除OK,let'sgoforitstep1:创建用户--createuser--CreatetheusercreateuserPHSidentifiedby""defaulttablespacePHSDATAtemporaryt...

用nifi把hdfs数据导到hive

发布时间:2017-11-22 大数据 JSON 数据库
全景图:  1.ListHDFS&amp;FetchHDFS:ListHDFS: FetchHDFS: 2.EvaluateJsonPath:{"status":{"code":500,"message":"FAILED","detail":"DTUIDnotexists"}}如果json里有数组,需要先用SplitJson分隔:  3.RouteOnContent: 4.ReplaceText:...

Log4J 配置文件模板及代码说明

发布时间:2017-03-05 JAVA 操作系统 数据库
相对而言,这个日志系统的配置就没那么随意了,而且有些功能用起来也不是那么爽,譬如动态读取配置文件。不过鉴于使用这个日志的系统还是很多,所以也写一个demo贴出来,风格跟log4j2一样,配置的说明全在代码里。ps:此处只使用xml方式来配置,个人觉着properties方式不是很友好,理解起来没xml容易。&lt;?xmlversion="1.0"encoding="UTF-8"?&gt;&lt;...

SQLServer自动建表存储过程

发布时间:2008-11-25 数据库
--建表存储过程Create Proc [dbo].[PN_CreateHistoryDataTable] ASBegin Declare @Count int Declare @CollCode varchar(4) Declare @TableName varchar(30) Declare @StrSql nvarchar(2000) Declare @CreateSQL varchar(2...

从EXCEL导入数据到SQL SERVER

发布时间:2019-04-24 EXCEL SQL
               从EXCEL导入数据到SQLSERVER左直拳介绍两种途径将数据从EXCEL中导入到SQLSERVER。一、       在程序中,用ADO.NET。代码如下: //连接串stringstrConn="Provider=Microsoft.Jet.OLEDB.4.0;ExtendedProperties=Excel8.0;DataSource="+[EXCEL文件,含...

SQL Server 数据导入Mysql详细教程

发布时间:2017-09-11 大数据 数据库
百度经验:https://jingyan.baidu.com/article/acf728fd1a7bd0f8e410a357.htmlSQLServer数据库和Mysql数据库都是关系型数据库,虽然很多数据库都对SQL语句进行了再开发和扩展,使得在不同的数据库中执行的方法或用法不一,但是SQL Server,Mysql,Access等都采用了SQL语言标准,不同的数据库中的数据是可以导入的。对于...

厉害了,设计了一套千万级可扩展的架构!

发布时间:2021-06-28 缓存 数据库 中间件 分布式 JAVA
点击上方“芋道源码”,选择“设为星标”管她前浪,还是后浪?能浪的浪,才是好浪!每天8:55更新文章,每天掉亿点点头发...源码精品专栏 原创|Java2020超神之路,很肝~中文详细注释的开源项目RPC框架Dubbo源码解析网络应用框架Netty源码解析消息中间件RocketMQ源码解析数据库中间件Sharding-JDBC和MyCAT源码解析作业调度中间件Elastic-Job源码解析分布式事务...

搜狗搜索网站快照说明

发布时间:2022-11-22 运维 服务器 数据库
什么是网页快照?网页快照,英文名叫WebCache,网页缓存。搜狗在收录网页时,对网页进行备份,存在自己的服务器缓存里,当用户在搜索引擎中点击“网页快照”链接时,搜狗将搜狗Spider系统当时所抓取并保存的网页内容展现出来,称为“网页快照”。互联网上的网页并不是一成不变的,而是不断增加、删除、改动。因此,搜狗网页数据库中的网页也需要及时更新,既把互联网上网页重新复制一遍。如果你在你的网站上删除一张...

07 Lamda表达式 概念 函数式接口 代码 总结

发布时间:2022-03-24 多线程 JAVA 面试 数据库
Lamda表达式概念λ希腊字母表中排序第十一位的字幕,应为名称为Lambda避免匿名内部类定义过多其实只属于函数式编程的概念(params)-&gt;expression[表达式](params)-&gt;statement[语句](params)-&gt;{statements}a-&gt;System.out.println(“ilikelambda–&gt;”+a);newThread(()...

hibernate连接mysql时的乱码问题

发布时间:2009-10-10 JDBC MYSQL HIBERNATE
1.首先,在创建数据库的时候要指定编码(这个很重要,否则数据库会按默认的编码进行存储,肯定是乱码,除非制定默认编码为utf8或gbk等)。2.其次,页面编码要设置与数据库统一,同时有必要的话可写一个编码过滤器(或是编码处理类,手动修改编码)3.最后,就是hibernate的连接数据库语句要指定字符编码,这一步容易被忽略,特别是自动生成的hibernate配置文件。jdbc:mysql://loca...

【大数据存储技术】第7章 MongoDB 的原理和使用

第7章MongoDB的原理和使用7.1概述7.2MongoDB技术原理7.2.1文档和集合7.2.2分片机制和集群架构7.2.3CouchDB简介7.3安装配置MongoDB7.3.1单机环境部署7.3.2MOngoDB配置文件7.4基本命令行操作7.4.1Shell环境7.4.2数据库和集合操作7.4.3基本增删改查操作7.4.4聚合和管道7.4.5索引操作7.4.6Gridfs的原理和操作7....

畅想(3)-打通编程的任督二脉

发布时间:2013-05-15 VIEWUI 前端 数据库 后端
  从事编程多年了.最早是Winform,那样的开发,其实主要是前端后端一体的.前端就是窗体,界面,交互,后端主要是业务,数据库.这就是传说中的C/S.  后来,发展到Web,因为Web的特性,把研发一般分成前,后端了.初期,前端很简单,就是Html加CSS,一般不需要编程,加上.net的Winform技术,封装了很多控件.开发主要是后端.  再后来,就是现在了.我们发现世界产生了一些不一样的逆转...

ASP NET Core Razor页面教程的笔记

发布时间:2022-11-25 前端 HTML 数据库
一.QueryStringParametersinRazorPages的顺序1.从前端的&lt;aasp-page="/Employees/Details"asp-route-ID="@employee.Id"class="btnbtn-primarym-1"&gt;View&lt;/a&gt;通过默认,ID是参数。变成 https://localhost:7030/Employees/Detai...

干货丨如何开启TiDB集群中的节点通信加密?

发布时间:2022-11-23 网络 安全 TIDB 数据库
笔者在一个银行项目中,费尽千辛万苦,好不容易通过PoC测试。就当一切就绪,准备正式上线时,突然传来了噩耗:未通过银行内部的漏洞扫描,发现存在高危漏洞,需要马上进行修复。这可给我吓坏了,赶紧查看了银行提供的漏洞报告,如下:报告中也给出了解决办法:1、给TiDB组件间通信开启加密传输2、通过控制指定IP及端口来限制访问的范围这两种方案各有利弊。于是结合现场情况,笔者选择了第一种方案,操作简单且安全性更...

MySQL学习笔记

发布时间:2022-11-23 学习 MYSQL 数据库
写SQL能力在日常的开发工作中很重要,我下面主要展示在xml里面经常用的标签,常用的用法1.常用的SQL语句查询和修改是最常用的,至于新增的删除一般都是用工具实现的, 查询语句:select字段from表where.....修改语句update表名set字段=?where.....2.xml中常用的标签 &lt;select&gt;&lt;/select&gt;查询标签,标签内写SQL&lt;up...

权限模块设计及使用

发布时间:2016-04-25 JAVA 数据库
  最近一直在做权限那一块,越做越乱,有很多疑问,想和大家探讨交流。希望大家不吝赐教、  1、项目用的是springsecurity框架,在用这个框架的时候,配置文件的配置就花了很长时间,然后就是将项目中的所有url都进行控制,输入数据库或配到配置文件中。  2、在做的时候,出现了分歧,老大的意思是只控制到菜单级别,有权限就可以看到菜单,没权限就不能看到菜单。但是默认所有的url都是可以访问的,只...

调用CodeSmith类库实现代码生成(含源码)

发布时间:2012-01-29 数据库
     CodeSmith的作用是不言而喻的,用过的人都会觉得它非常强大.根据自定义模板,快速生成代码.只是我们使用的时候,要在它提供的CodeSmithStudio环境下使用模板,再传入相应参数,最终生成NET的类文件.     如果我们可以通过编码方式,把CodeSmith功能融入NET代码中,这样就会比较灵活,方便我们控制了.根据下面的操作步骤我们就可以实现.     先说下环境,我安装的...

Kafka 快速起步

发布时间:2017-03-03 大数据 数据库
Kafka快速起步原创2017-01-05杜亦舒性能与架构性能与架构性能与架构微信号yogoup功能介绍网站性能提升与架构设计主要内容:1.kafka安装、启动2.消息的生产、消费3.配置启动集群4.集群下的容错测试5.从文件中导入数据,并导出到文件单机示例安装tar-xzfkafka_2.10-0.10.1.1.tgzcdkafka_2.10-0.10.1.1启动&gt;bin/zookeepe...