数据库语言与事务管理

数据库查询

1.use 【库名】/describle【表名】 /desc【表名】

desc/describle作用一样,desc 是describe的缩写,都是查询表的数据结构,
use切换数据库名称;
数据库语言与事务管理_第1张图片

2.navicat 手动添加表位置在结果栏里左下角;

当开启事务的时候,通过回滚,可以撤销已经删除的东西。
数据库语言与事务管理_第2张图片

3.navicat快捷键

ctrl+ /:单行注释,ctrl+shift+/:撤销注释;

ctrl+F6打开命令行窗口;CTRL+Q打开查询窗口;

4.使用dos命令启动数据库时密码保护

正常语句:

c:/users/auus/mysql> _u root _p123456 【回车键】

隐藏信息输入:

c:/users/auus/mysql> _u root _p 【回车键】

[系统提示enter your password:] 123456

[密码会用*代替输出]

5.使用数据库的两种方式

1用dos窗口命令行;

2.使用可视化工具navicat /sqlyog ;【本身是显示数据库的工具,不是存储数据库的工具类型】

6.注释

字符段的注释直接在字符段的约束后comment “别名”;

表名的注释,在创建表的小括号外直接添加comment=“别名”

标准的注释:两个中下划线 一个空格 – – 单行注释

多行注释/**/

在sqlyog中特有的是# 做单行注释
给变量起别名时 用关键字as ,可以省略as 和双引号

当有外键时给字符段注释的名字在外键之前

create table Course
(
Cno varchar(20) not null primary key comment “课程号”,
Cname varchar(20) not null comment “课程名称” ,
Tno varchar(20) not null comment"教工编号" references teacher(Tno)
**)comment=“课程表”;

7.键,设置主键和外键

foreign key 外键

primary key主键

【unique key】 唯一键

1.建表时添加外键

【primary key (id) refrences subjiect ( stuId)】

2.表完成后设置主键

alter table 表名 constraint pk_字段名 primary key(字段名);

3.表完成后.设置外键

【alter table 表名 constraint fk_字段名 foreign key(字段名) reference 关联的表名(关联表名的主键字段名);】

7-4复合主键【两个主键必须在一起定义,不能分开定义】

错误写法:

CREATE TABLE flight_details4(
flight_prefix VARCHAR(20) NOT NULL primary key ,
flight_id VARCHAR(10) NOT NULL PRIMARY KEY ,

………………其他字符段………………

);

正确写法:

CREATE TABLE flight_details4(

flight_prefix VARCHAR(20) NOT NULL ,
flight_id VARCHAR(10) NOT NULL ,

………………其他字符段………………,

PRIMARY KEY(flight_prefix,flight_id)
);

– 主键约束:学号、课程编号和日期构成组合主键**【复合主键】**
ALTER TABLE result PRIMARY key (stuNo,subject_num,subject_date);

8.添加/删除单列或多列 ;修改单列字段/字段内容;删除表语句

删除单列(多列)【删除表时不用添加约束】

alter table 表名 drop 字段1(,drop 字段2,drop 字段3);

添加单列及字段约束(多列j及字段约束)

alter table 表名 add 字段1 varchar(12)(,add 字段2 int (3),add 字段3 decimal(10,2));

修改表的约束

alter table 表名 modify 字段1 int (3);

修改表的字段重命名及约束

alter table 表名 change字段1 新字段1名字 int (3);

表的删除语句【不加where 判断条件删除整张表,加判断条件删除特定行】

delete from 表名【 where 条件;】

部分demo

create table grade(
id int(3) not null ,
name varchar(20) not null,
primary key(id)
)engine = innodb default charset utf8 comment=‘年级表’
alter table grade change id gradeId int(3);
alter table grade change name gradeName varchar(20);
– 创建学生表
create table if not exists student (
stuNo int not null,
loginPwd varchar(20)not null,
stuName varchar(20) not null,
sex char(2) not null DEFAULT ‘男’,
gradeId int not null ,
phone varchar(50),
address varchar(255) DEFAULT’地址不详’,
bornDate datetime,
email varchar(20),
idCard varchar(18) unique key,
PRIMARY key(stuNo)
)comment=“学生表”;
– 创建科目表
create table subject (
subject_num int not null primary key auto_increment,
subject_name varchar(50) not null,
classHour int not null,
gradeId int not null
)comment=‘科目表’;
– 在复合主键的情况下,可以使用外键但是不用声明外键;
– 成绩表
create TABLE if not exists score(
stuNo int not null,
subject_num int not null,
examDate datetime,
sutdent_score int not null
)comment=‘成绩表’;
– 显示建表的语言;
show create table score;
/*CREATE TABLE score (
stuNo int(11) NOT NULL,
subject_num int(11) NOT NULL,
examDate datetime DEFAULT NULL,
sutdent_score int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT=‘成绩表’
*/
– 查询数据库版本
select verson();
/*select verson()
1305 - FUNCTION kgc.verson does not exist
时间: 0.003s
*/
help int;
– 模糊查询
show variables like ‘storage engine%’;
– 向年级表中添加数据,多条
insert into grade (gradeId,gradeName)values (6,‘基础班’),(2,‘高级班’),(3,‘冲刺班’),(4,‘微服班’);
– 添加单条语句
insert into grade values (5,‘大数据班’);
– 查询表的具体信息;
select * from grade;
– 查询单列信息;
SELECT gradeName from grade;
– 根据条件查询信息一行的所有信息
select * from grade where gradeId=5;
– 根据条件查询信息一行的单列信息
select gradeName from grade where gradeId=4;
select * from grade;
– 查询单列信息;
SELECT gradeName from grade;
– 根据条件查询信息一行的所有信息
select * from grade where gradeId=5;
– 根据条件查询信息一行的单列信息
select gradeName from grade where gradeId=4;
INSERT into score values(24,2,“2020-10-12 00-00-00”,98),(5,2,“2020-10-12 00-00-00”,98),(6,2,“2020-10-12 00-00-00”,98),(7,2,“2020-10-12 00-00-00”,98),(8,2,“2020-10-12 00-00-00”,98),(9,3,“2020-10-12 00-00-00”,98),(10,2,“2020-10-12 00-00-00”,98),(11,2,“2020-10-12 00-00-00”,98),(12,2,“2020-10-12 00-00-00”,98),(13,2,“2020-10-12 00-00-00”,98),(14,3,“2020-10-12 00-00-00”,98),(15,3,“2020-10-12 00-00-00”,98),(16,2,“2020-10-12 00-00-00”,78);
INSERT into score values(4,2,“2020-10-12 00-00-00”,98);
show tables;
select * from score;

– 查看创建学生表的SQL语句
show create table student;
– 创建学生表
CREATE TABLE student (
stuNo int(11) NOT NULL,
loginPwd varchar(20) NOT NULL,
stuName varchar(20) NOT NULL,
sex char(2) NOT NULL DEFAULT ‘男’,
gradeId int(11) NOT NULL,
phone varchar(50) DEFAULT NULL,
address varchar(255) DEFAULT ‘地址不详’,
bornDate datetime DEFAULT NULL,
email varchar(20) DEFAULT NULL,
idCard varchar(18) DEFAULT NULL,
UNIQUE KEY idCard (idCard)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT=‘学生表’
– 添加一个学生
insert into student(stuNo,loginPwd,stuName,sex ,gradeId)values(7,“123123”,“赵1”,default,3);
insert into student(stuNo,loginPwd,stuName,sex ,gradeId)values(8,“123123”,“赵2”,default,2),(9,“123123”,“赵3”,default,2),(10,“123123”,“赵4”,default,2),(11,“123123”,“赵5”,default,2),(12,“123123”,“赵6”,default,2),(14,“123123”,“赵14”,default,2),(15,“123123”,“赵15”,default,2),(16,“123123”,“赵16”,default,2),(17,“123123”,“赵17”,default,2),(18,“123123”,“赵18”,default,2),(19,“123123”,“赵19”,default,2),(20,“123123”,“赵20”,default,2),(21,“123123”,“赵21”,default,2),(22,“123123”,“赵22”,default,2),(23,“123123”,“赵23”,default,2),(24,“123123”,“赵24”,default,2),(25,“123123”,“赵1”,default,2),(7,“123123”,“赵1”,default,2),(7,“123123”,“赵1”,default,2),(7,“123123”,“赵1”,default,2),(7,“123123”,“赵1”,default,2),(7,“123123”,“赵25”,default,2),(26,“123123”,“赵26”,default,2),(27,“123123”,“赵27”,default,2),(28,“123123”,“赵28”,default,2),(29,“123123”,“赵29”,default,2),(30,“123123”,“赵30”,default,2),(31,“123123”,“赵31”,default,2),(32,“123123”,“赵32”,default,2),(33,“123123”,“赵33”,default,2),(34,“123123”,“赵34”,default,2),(35,“123123”,“赵35”,default,2),(36,“123123”,“赵36”,default,2),(37,“123123”,“赵37”,default,2),(38,“123123”,“赵38”,default,2),(39,“123123”,“赵39”,default,2),(48,“123123”,“赵40”,default,2);
show create table subject;
CREATE TABLE subject (
subject_num int(11) NOT NULL AUTO_INCREMENT,
subject_name varchar(50) NOT NULL,
classHour int(11) NOT NULL,
gradeId int(11) NOT NULL,
PRIMARY KEY (subject_num)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT=‘科目表’
use test;
show tables ;
use kgc;
show tables;
– 查看所有数据库名
show databases ;
– 使用某个数据库
use kgc;
– 查看当前数据库下的表名;
show tables;
– 查看表结构
desc grade;

DESCRIBE grade;
– cha看数据库版本号
select VERSION();
– 查看某张表
show create table score;
CREATE TABLE score (
stuNo int(11) NOT NULL,
subject_num int(11) NOT NULL,
examDate datetime DEFAULT NULL,
sutdent_score int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='成绩表
show create table student;
CREATE TABLE student (
stuNo int(11) NOT NULL,
loginPwd varchar(20) NOT NULL,
stuName varchar(20) NOT NULL,
sex char(2) NOT NULL DEFAULT ‘男’,
gradeId int(11) NOT NULL,
phone varchar(50) DEFAULT NULL,
address varchar(255) DEFAULT ‘地址不详’,
bornDate datetime DEFAULT NULL,
email varchar(20) DEFAULT NULL,
idCard varchar(18) DEFAULT NULL,
UNIQUE KEY idCard (idCard)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='学生表
– 查询所有学生信息
– 设置自增的步长;
SELECT * from student;
set @@auto_increment_increment=100;
– 删除某张表
drop table if EXISTS grade2;
– 删除某个字段
Alter TABLE student drop email;
– 查看某个表的结构
DESC student;
– 删除一个表的多个字段
ALTER table student drop bornDate,DROP idCard;
– 增加一个字段;
ALTER table student ADD email varchar(59);
– 增加一个表多个字段;
ALTER table student add bornDate datetime,add idCard varchar(18);
– 查看某个表的结构
DESC student;
– 更改某个字段的约束;
Alter table student MODIFY stuNo int(3);
– 更改某个字段的名字;

– Alter TABLE student change sex gender varchar(1);
– 查询某个人的单条信息
SELECT * FROM student where stuNo=23;
– 查询某个人单列信息
SELECT stuName from student where stuNo=23;
– 删除某条信息;
DELETE from student where stuNo=23;
– 查询学员编号在12到35之间;
SELECT * from student where stuNO BETWEEN 12 and 35;
– 查询学员编号不是2的姓名性别信息;
SELECT stuName,gender from student wheregradeId!=2;
– 查询赵学生首字母为赵的
SELECT * from student where stuName like “赵%”;
– 查询赵姓同学名字两个字
SELECT * from student where stuName like “赵_”;
– 查询含赵同学的信息(赵字必须在中间)
SELECT * from student where stuName Like “%赵%”;
– 查询学生姓名是三位数,并且以4结尾的学生名字;
SELECT stuName FROM student WHERE stuName like “__4”;
– 年级表表结构
desc grade;
– 列的别名展示信息
SELECT gradeId “年级编号”,gradeName"年级名称"from grade;
– 去重
SELECT DISTINCT stuName from student ;
– 拼接显示
SELECT contact(stuName,“姓名”) as “学生姓名” from student;

– case when 条件1 then 取值1 when 条件2 then 取值2 else 取值3 end
– 显示结果
SELECT 23%5 as “结果”;
– 查询步长
select @@auto_increment_increment ;
– 设置步长
set @@auto_increment_increment=1;
– 同步计算,(成绩低于80的都加5分)查询学号和成绩
SELECT stuNo, sutdent_score+5 from score where sutdent_score<=80 ;

– page11 在test数据库中创建person表
create table person (
num int(4) auto_increment PRIMARY key comment"序号",name VARCHAR(50)comment"姓名" ,sex char(2)comment"性别",bornDate datetime comment"出生日期"
);
– 将表名修改为tb_person
ALTER table person rename tb_person;
– 删除出生日期字段
ALTER table tb_person DROP bornDate;
– 添加出生日期字段,数据类型为DATE类型
ALTER table tb_person add bornDate date;
– 修改序号字段名(number)为id,类型为BIGINT类型
ALTER table tb_person CHANGE num id BIGINT;
– page12result表需要添加的内容
– 主键约束:学号、课程编号和日期构成组合主键
ALTER TABLE result PRIMARY key (stuNo,subject_num,subjiect_date);
– 外键约束:主表student和从表result通过studentNo字段建立主外键关联
ALTER TABLE result FOREIGN key(stuNo) REFERENCES student(stuNo);

–page26 1.新建学生表;为学生表添加数据使用提供的SQL脚本为成绩表添加数据
– 为科目表添加数据,要求使用一条INSERT语句
insert into subject values (7,"Logic Java
",220,1),(8,"HTML
",160,1),(9,"Java OOP
",230,2);

– 为学生表添加数据(参考学生用书表3-3)
show create table student;
CREATE TABLE student (
stuNo int(3) DEFAULT NULL,
loginPwd varchar(20) NOT NULL,
stuName varchar(20) NOT NULL,
gender varchar(1) DEFAULT NULL,
gradeId int(11) NOT NULL,
phone varchar(50) DEFAULT NULL,
address varchar(255) DEFAULT ‘地址不详’,
email varchar(59) DEFAULT NULL,
bornDate datetime DEFAULT NULL,
idCard varchar(18) DEFAULT NULL,
age int(11) DEFAULT ‘18’
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT=‘学生表’
INSERT into student (stuNo ,loginPwd,stuName,gradeId)values(10000,“222”,“张三”,1),(11000,“222”,“张非”,1);
create table result (
select subject_num,subject_name,classHour, gradeId from kgc.subject
);
– page27 2-1将学生表中学号为20000的学生的邮箱修改为[email protected],密码改为000
update student set email=“[email protected]”,loginPwd ="000"where stuNo=20000;
– 2-2将科目表中课时数大于200且年级编号为1的科目的课时减少10
UPDATE subject set classHour=classHour-10 where gradeid=1 and classHour>200;
– 2-3将所有年级编号为1的学员姓名、性别、出生日期、手机号码信息保存到新表student_grade1中
create TABLE student_grade1 (
select stuName,gender,bornDate, phone from student where gradeid =1
);

– 修改字段名

alter table score change sutdent_score student_score int ;

– page28 3-1 查询2016年2月17日考试前5名的学员的学号和分数
SELECT stuNo,student_score from score WHERE examDate <="2016-2-17 00-00-00"order by score desc LIMIT 0,5;

–3-2将所有女学生按年龄从大到小排序,从第2条记录开始显示6女学生的姓名、年龄、出生日期、手机号信息
ALTER table student add age int DEFAULT 18;
select stuName,age, bornDate,phone from student ORDER BY age asc LIMIT 1,6;
– 3-3按出生年份分组统计学生人数,将各组中人数达到2人的年份和人数显示出来

SELECT YEAR(bornDate)AS 年份, COUNT(stuNo) AS 人数 FROM student
where bornDate is not null
GROUP BY 年份 HAVING 人数>=2【别名的as 和双引号可以省略】

– 3-4查询参加2016年2月12日考试的所有学员的最高分、最低分、平均分
select MAX(student_score)“最高分”,min(student_score)“最低分”,avg(student_score)“平均分” from score WHERE examDate=‘2016-02-17 00:00:00’;
数据库语言与事务管理_第3张图片
数据库语言与事务管理_第4张图片数据库语言与事务管理_第5张图片
数据库语言与事务管理_第6张图片
数据库语言与事务管理_第7张图片

数据库语言与事务管理_第8张图片
“2020-10-12 00-00-00”,日期格式手动输入,应该用双引号包裹
数据库语言与事务管理_第9张图片数据库语言与事务管理_第10张图片update student set sex=1 where studentNo in(1001,1002,1003);//更改具体的多行**;

9.新建表复制老表表结构/表内容

create table 【if not exists】表名 like 库名.指定的表名;

9-1-- 选中特定字段行建立新表

create table if not EXISTS user5 (
select id,userName,userPwd,phone from user2
);

9-2-- 拷贝表结构;

create table user3 LIKE user2;

9-3sql将查询结果建立为新表

数据库语言与事务管理_第11张图片

10.表的更新语句

数据库语言与事务管理_第12张图片 # 11.索引【分页】

limit 【起始位置((n-1)*每页数),每页记录数】

12.生成模拟数据库及索引原则

数据库语言与事务管理_第13张图片

数据库语言与事务管理_第14张图片
expalain select StudentNo,Address from student where MATCH(StudentName) AGAINST(‘张’)
全文索引的index只能用在【MyISAM表格的char、varchar和text】的字段上

建表时添加

CREATE TABLE student (
#省略一些SQL语句
【 FULLTEXT (StudentName) 】
)【ENGINE=MYISAM;】

建表后ALTER TABLE employee ADD FULLTEXT (first_name);

1.创建全文索引(FullText index)

   旧版的MySQL的全文索引只能用在MyISAM表格的char、varchar和text的字段上。 

   不过新版的MySQL5.6.24上InnoDB引擎也加入了全文索引,所以具体信息要随时关注官网,
 1.1. 创建表的同时创建全文索引

         CREATE TABLE article ( 
              id INT AUTO_INCREMENT NOT NULL PRIMARY KEY, 
              title VARCHAR(200), 
              body TEXT, 
              FULLTEXT(title, body) 
          ) TYPE=MYISAM; 

1.2.通过 alter table 的方式来添加

            ALTER TABLE `student` ADD FULLTEXT INDEX ft_stu_name  (`name`) #ft_stu_name是索引名,可以随便起

   或者:ALTER TABLE `student` ADD FULLTEXT ft_stu_name  (`name`)


1.3. 直接通过create index的方式

            CREATE FULLTEXT INDEX ft_email_name ON `student` (`name`)

       也可以在创建索引的时候指定索引的长度:

            CREATE FULLTEXT INDEX ft_email_name ON `student` (`name`(20))
  1. 删除全文索引
    2.1. 直接使用 drop index(注意:没有 drop fulltext index 这种用法)

              DROP INDEX full_idx_name ON tommy.girl ;
    

    2.2. 使用 alter table的方式

             ALTER TABLE tommy.girl DROP INDEX ft_email_abcd;
    

3.使用全文索引

 跟普通索引稍有不同

 使用全文索引的格式:  MATCH (columnName) AGAINST ('string')

 eg:

       SELECT * FROM `student` WHERE MATCH(`name`) AGAINST('聪')
       索引作用:快速定位特定数据

注意事项
index和key关键字都可设置常规索引
应加在查找条件的字段
不宜添加太多常规索引,影响数据的插入、删除和修改操作

- 删除 st5 表的主键alter table st5 drop primary key;
– 添加主键alter table st5 add primary key(id);# 12-2创建模拟1000万数据库
CREATE TABLE `user` ( 
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT '' COMMENT '用户昵称',
`email` varchar(50) NOT NULL COMMENT '用户邮箱', 
`phone` varchar(20) DEFAULT '' COMMENT '手机号', 
`gender` tinyint(4) unsigned DEFAULT '0' COMMENT '性别(0:男;1:女)',
`password` varchar(100) NOT NULL COMMENT '密码',
`age` tinyint(4) DEFAULT '0' COMMENT '年龄', 
`create_time` datetime DEFAULT CURRENT_TIMESTAMP, 
`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表'


DROP FUNCTION
IF
	EXISTS mock_data;

DELIMITER $$
CREATE FUNCTION mock_data ( ) RETURNS INT BEGIN
DECLARE
	num INT DEFAULT 2000;
DECLARE
	i INT DEFAULT 0;
WHILE
	i < num DO
	INSERT INTO user3 ( `name`, `email`, `phone`, `gender`, `password`, `age` )
VALUES
	(
	CONCAT( '用户', i ),
	CONCAT( "1", FLOOR( RAND( ) * 999999999+100000 ), "@qq.com" ),
	CONCAT( '18', FLOOR( RAND( ) * ( 999999999-100000000 ) + 100000000 ) ),
	FLOOR( RAND( ) * 2 ),
	UUID( ),
	FLOOR( RAND( ) * 100 ) 
	);

SET i = i + 1;

END WHILE;
RETURN i;

END;
SELECT
	mock_data ( );

--创建MyISAM模式表方便批量跑数据
 
CREATE TABLE `logs1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `logtype` varchar(255) DEFAULT NULL,
  `logurl` varchar(255) DEFAULT NULL,
  `logip` varchar(255) DEFAULT NULL,
  `logdz` varchar(255) DEFAULT NULL,
  `ladduser` varchar(255) DEFAULT NULL,
  `lfadduser` varchar(255) DEFAULT NULL,
  `laddtime` datetime DEFAULT NULL,
  `htmlname` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  AUTO_INCREMENT=1811 DEFAULT CHARSET=utf8 COMMENT='日志表';
 
 
--创建存储过程
 
DROP PROCEDURE IF EXISTS my_insert;
CREATE PROCEDURE my_insert()
BEGIN
   DECLARE n int DEFAULT 1;
        loopname:LOOP
            INSERT INTO `logs1`(`logtype`,`logurl`,`logip`,`logdz`,`ladduser` ,`lfadduser`,`laddtime`,`htmlname`) VALUES ( 2, '/index', '0:0:0:0:0:0:0:1', null, null, 'null', '2018-05-03 14:02:42', '首页');
            SET n=n+1;
        IF n=10000000 THEN
            LEAVE loopname;
        END IF;
        END LOOP loopname;
END;
 
 
--执行存储过程
CALL my_insert();
 
 
--数据插入成功后修改表模式InnoDB 时间稍微久点
 alter table `logs1` engine=InnoDB;

delimiter间隔符

其实就是告诉mysql解释器,该段命令是否已经结束了,mysql是否可以执行了。默认情况下,delimiter是分号;。在命令行客户端中,如果有一行命令以分号结束,那么回车后,mysql将会执行该命令。

    DELIMITER $$ 
    DROP TRIGGER IF EXISTS `updateegopriceondelete`$$ 
    CREATE 
        TRIGGER `updateegopriceondelete` AFTER  DELETE ON  `customerinfo` 
        FOR EACH ROW BEGIN 
    DELETE FROM egoprice  WHERE customerId=OLD.customerId; 
        END$$ 
    DELIMITER ; 

其中DELIMITER 定好结束符为"$$", 然后最后又定义为";", MYSQL的默认结束符为";". 
详细解释: 
其实就是告诉mysql解释器,该段命令是否已经结束了,mysql是否可以执行了。 
默认情况下,delimiter是分号;。在命令行客户端中,如果有一行命令以分号结束, 
那么回车后,mysql将会执行该命令。如输入下面的语句 
mysql> select * from test_table; 
然后回车,那么MySQL将立即执行该语句。 

但有时候,不希望MySQL这么做。在为可能输入较多的语句,且语句中包含有分号。 
如试图在命令行客户端中输入如下语句 

    mysql> CREATE FUNCTION `SHORTEN`(S VARCHAR(255), N INT) 
    mysql>     RETURNS varchar(255) 
    mysql> BEGIN 
    mysql> IF ISNULL(S) THEN 
    mysql>     RETURN ''; 
    mysql> ELSEIF N<15 THEN 
    mysql>     RETURN LEFT(S, N); 
    mysql> ELSE 
    mysql>     IF CHAR_LENGTH(S) <=N THEN 
    mysql>    RETURN S; 
    mysql>     ELSE 
    mysql>    RETURN CONCAT(LEFT(S, N-10), '...', RIGHT(S, 5)); 
    mysql>     END IF; 
    mysql> END IF; 
    mysql> END; 

默认情况下,不可能等到用户把这些语句全部输入完之后,再执行整段语句。 
因为 mysql一遇到分号,它就要自动执行。 
即,在语句RETURN '';时,mysql解释器就要执行了。 
这种情况下,就需要 事先把delimiter换成其它符号,如//或$$。 

    mysql> delimiter // 
    mysql> CREATE FUNCTION `SHORTEN`(S VARCHAR(255), N INT) 
    mysql>     RETURNS varchar(255) 
    mysql> BEGIN 
    mysql> IF ISNULL(S) THEN 
    mysql>     RETURN ''; 
    mysql> ELSEIF N<15 THEN 
    mysql>     RETURN LEFT(S, N); 
    mysql> ELSE 
    mysql>     IF CHAR_LENGTH(S) <=N THEN 
    mysql>    RETURN S; 
    mysql>     ELSE 
    mysql>    RETURN CONCAT(LEFT(S, N-10), '...', RIGHT(S, 5)); 
    mysql>     END IF; 
    mysql> END IF; 
    mysql> END;// 

这样只有当//出现之后,mysql解释器才会执行这段语句 .

例子

    mysql> delimiter // 
     
    mysql> CREATE PROCEDURE simpleproc (OUT param1 INT) 
    -> BEGIN 
    -> SELECT COUNT(*) INTO param1 FROM t; 
    -> END; 
    -> // 
    Query OK, 0 rows affected (0.00 sec) 

12-3模拟数据的规范

Mock.js 的语法规范包括两部分:

    数据模板定义规范(Data Template Definition,DTD)
    数据占位符定义规范(Data Placeholder Definition,DPD)

数据模板定义规范 DTD

数据模板中的每个属性由 3 部分构成:属性名、生成规则、属性值:

// 属性名   name
// 生成规则 rule
// 属性值   value
'name|rule': value

注意:

    属性名 和 生成规则 之间用竖线 | 分隔。
    生成规则 是可选的。
    生成规则 有 7 种格式:
        'name|min-max': value
        'name|count': value
        'name|min-max.dmin-dmax': value
        'name|min-max.dcount': value
        'name|count.dmin-dmax': value
        'name|count.dcount': value
        'name|+step': value
    生成规则 的 含义 需要依赖 属性值的类型 才能确定。
    属性值 中可以含有 @占位符。
    属性值 还指定了最终值的初始值和类型。

13 日期函数与 select 常用函数表达式;

13-1数字函数

abs(-8 ) 绝对值【8】

ceil(-8.2)向上取整【-8】

floor(-8.2)向下取整【-9】

round(-8.2)四舍五入【-8】

sign(9)整数判断正负 ,正数返回1,负数-1,0返回0【1】

rand() 0-1之间的随机数【0.238439】

mod(m, n) – m%n m mod n 求余 10%3=1

format(x, d) – 格式化千分位数值 format(1234567.456, 2) = 1,234,567.46

load_file(fmathile_name) – 从文件读取内容

查询结果参与运算

某列数据和固定值运算SELECT 列名 1 + 固定值 FROM 表名;

某列数据和其他列数据参与运算SELECT 列名 1 + 列名 2 FROM 表名;

-- 给所有的数学加 5 分
 select math+5 from student;

-- 查询 math + english 的和
select *,(math+english) as 总成绩 from student;
13-2字符串函数

upper/lower(str) 结果输出大写/小字母

contact(str1,str2,str3)字符串拼接

replace(str1,str2,str3)更改:str1中,用str 3新内容取代str2[原str1中的部分内容]

insert(str1,index1,index2,str3)更改:在下标范围内str3新内容取代str1中选定下标的内容;

char_length(str )返回字符串的长度;

substring(str1,index1,index2) 截取:选定范围的str1长度;

reverse(str)字符串反转

把姓唐的同学,更改为汤同学

select replace(stuName ,”唐”,“汤”) from sumbs_student where stuName= “唐%”;

13-3日期函数

当前日期 current_date() 或者curdate

当前时间 now() [输出年月日时分秒]

当前具体的时间年/月/小时 year(now())

当地时间 localtime()

系统时间 sysdate()

13-4用户

系统用户 system_user() 或者user()

13-5查询当前数据库sql版本

version()

14聚合函数

max() 最大值;

min()最小值;

avg()平均值

sum()求和

count()计数,计算总行数

count(stuname):查询总行数,如果某列表名为空,则不计算在总行数范围内
count(1)查询总行数,无论某列表名为空,则不计算在总行数范围内,只查1列,运行速度稍快,效率高
count(*) 查询总行数,无论某列表名为空,则不计算在总行数范围内,查询表的所有列,运行速度较慢,效率低

15.MD5加密

15-1.普通明文密码输入后要更新密码格式

update 表名 set pwd= md5(pwd);

15-2.插入时就对数据加密

insert into (id,name, pwd)表名 values (1,”唐哥”,MD5(“666666”));

15-3校验【将用户传递来的密码进行MD5加密,然后对比加密后的值】

select * from 表名 where name=“唐哥”and pwd= md5(“666666”);

16.复合查询

模糊查询

like “刘%” 的百分号是通配符,双引号不可省略;是指0个或多个字符;【姓刘的所有同学】

_下划线指定位数,

16-1**!和表达式配合需要使用()**

16-1-1简单条件查询中的模糊查询【between ……and……】和具体查询【in()】

-- 4、 查询Score表中成绩在60到80之间的所有记录。
SELECT * FROM score where degree BETWEEN 60 and 80;
-- select * from score where degree between 60 and 80
-- 5、 查询Score表中成绩为85,86或88的记录。
SELECT * from score where degree in (85,86,88);

16-2判断时否为null ,必须是 is (not ) null

【查询日期时排除空的年份 is not null ,不可以写成 !=null】

!和表达式配合需要使用()                尽量避免使用!=
where not id=3
where !(id=3)

16-3复合查询基本范式
SELECT <字段名列表>或者聚合函数
FROM <表名或视图>
[WHERE <查询条件>]

[GROUP BY <分组的字段名>]
[HAVING <条件>]
[ORDER BY <排序的字段名> [ASC 或 DESC]]
[LIMIT [位置偏移量, ]行数]

[] 括号代表可选的;
{} 括号代表必须的;
# MySQL语句中的注释符,也可以用 /该处为注释/

字段名列表为要查询的字段名,各字段之间使用逗号分隔,若查询表中所有字段使用“*”号表示。**
FROM后的表名为要查询的数据的来源,可以单个或多个。
WHERE子句为可选项,指定查询的条件。
GROUP BY子句表明查询出来的数据按指定字段进行分组。
HAVING子句用于筛选组
ORDER BY子句指定按什么顺序显示查询出来的数据,什么字段的升序(ASC)或降序(DESC)。默认降序;
limit 起始位置,行数; LIMIT ((页数-1)*条数),条数;

位置偏移量:指从结果集中第几条数据开始显示(第1条记录的位置偏移量是0,第2条记录的位置偏移量是1……),此参数可选,当省略时从第1条记录开始显示。
行数:指显示记录的条数

16-4年龄查询

SELECT * FROM studentinfo WHERE FLOOR(DATEDIFF(NOW(),bornDay)/365)<18;

select sname,YEAR(getdate())-YEAR(sbirthday) from student

-- 38、查询Student表中每个学生的姓名和年龄。【第一种方法更精确点】
-- SELECT sname, FLOOR(DATEDIFF(NOW(),sbirthday)/365) from student;
-- select sname,year(NOW())-year(sbirthday)from student

16-5order by 多个条件查询;

比如查询成绩,排序条件为成绩,姓名,学号,如果第一个相同,才会执行下一个,如果第一个条件都不相同,第二个和第三个条件都不会执行;

16-6having过滤

SELECT bornDate,count(1) FROM student ORDER BY bornDate having count(1)>=2;
– 选择的是选择聚合函数和分组的条件 ORDER BY 是分组的依据;have进一步进行筛选。是对聚合函数的应用,二次过滤;where 判断的条件是通用的;

16-6group by

注意:当我们使用某个字段分组,在查询的时候也需要将这个字段查询出来,否则看不到数据属于哪组的

 查询男女各多少人

  1. 查询所有数据,按性别分组。

  2. 统计每组人数

select sex, count(*) from student3 group by sex;

17简单子查询的用法

查询语句的条件是 where 字符段名 in【或者是关系表达式】(查询语句)

SELECT subjectName FROM subject WHERE gradeId IN (
SELECT gradeId FROM grade WHERE gradeName=‘S1’
)

嵌套查询可由多个子查询组成,求解的方式是由里及外 ;子查询返回的结果一般都是集合,故而建议使用 IN 关

三种查询方式

1.俄罗斯套娃式,从一个表中查询最终结果, 【 返回单个表的字段,子查询】

2.从多个表中查询所有的字符段(必须有中间表连接)【where 来联表查询】

3.联表查询,条件用and 连接; 【join on来联表查询;】

SELECT bornDate FROM student WHERE studentName='刘亚东'
SELECT * FROM student WHERE bornDate>'2006-01-01'
#简单子查询=比较运算符+子查询
#要求子查询必须返回一个值
SELECT * FROM student WHERE bornDate>(SELECT bornDate FROM student WHERE studentName='刘亚东')
#in子查询  查询刘亚东的信息
#好处:子查询可以返回多个值
SELECT * FROM student WHERE bornDate IN(SELECT bornDate FROM student WHERE studentName='刘亚东')
#查询Java课程至少一次考试成绩为60的学生信息
#subject  result student
#如果我想查询学生信息,我需要学号作为条件
#因为涉及到考试成绩,我们发现result表中有学号有成绩

#子查询方式1
SELECT studentName FROM stu WHERE studentNo IN(
SELECT studentNo
   FROM result
   WHERE studentResult=60 AND
    subjectNo IN (SELECT subjectNo FROM `subject` WHERE subjectName='java OPP')
)

#子查询方式2      
SELECT stu.studentName
FROM `stu` stu,`result` res,`subject` sub 
WHERE stu.studentNo=res.studentNo AND
sub.subjectNo=res.subjectNo AND
sub.subjectName='java OPP' AND
res.studentResult=60

#子查询方式3
SELECT studentName
  FROM stu stu INNER JOIN `result` res ON stu.studentNo=res.studentNo        
               INNER JOIN `subject` sub ON sub.subjectNo=res.subjectNo
  WHERE sub.subjectName='java OPP' AND 
        res.studentResult=60

18.turncate 与delete,drop

TRUNCATE命令

用于完全清空表数据,但表结构、索引、约束等不变

区别于DELETE命令
相同
都能删除数据、不删除表结构,但TRUNCATE【 速度更快】
删除表结构【drop】
不同
使用TRUNCATE TABLE【重新设置AUTO_INCREMENT计数器】
使用TRUNCATE TABLE不会对【事务】有影响

一、delete

1、delete是DML,执行delete操作时,每次从表中删除一行,并且同时将该行的的删除操作记录在redo和undo表空间中以便进行回滚(rollback)和重做操作,但要注意表空间要足够大,需要手动提交(commit)操作才能生效,可以通过rollback撤消操作。

2、delete可根据条件删除表中满足条件的数据,如果不指定where子句,那么删除表中所有记录。

3、delete语句不影响表所占用的extent,高水线(high watermark)保持原位置不变。

二、truncate

1、truncate是DDL,会隐式提交,所以,不能回滚,不会触发触发器。

2、truncate会删除表中所有记录,并且将重新设置高水线和所有的索引,缺省情况下将空间释放到minextents个extent,除非使用reuse storage,。不会记录日志,所以执行速度很快,但不能通过rollback撤消操作(如果一不小心把一个表truncate掉,也是可以恢复的,只是不能通过rollback来恢复)。

3、对于外键(foreignkey )约束引用的表,不能使用 truncate table,而应使用不带 where 子句的 delete 语句。

4、truncatetable不能用于参与了索引视图的表。

三、drop

1、drop是DDL,会隐式提交,所以,不能回滚,不会触发触发器。

2、drop语句删除表结构及所有数据,并将表所占用的空间全部释放。

3、drop语句将删除表的结构所依赖的约束,触发器,索引,依赖于该表的存储过程/函数将保留,但是变为invalid状态。

 

总结:

1、在速度上,一般来说,drop> truncate > delete。

2、在使用drop和truncate时一定要注意,虽然可以恢复,但为了减少麻烦,还是要慎重。

3、如果想删除部分数据用delete,注意带上where子句,回滚段要足够大;

   如果想删除表,当然用drop; 

   如果想保留表而将所有数据删除,如果和事务无关,用truncate即可;

   如果和事务有关,或者想触发trigger,还是用delete;

   如果是整理表内部的碎片,可以用truncate跟上reuse stroage,再重新导入/插入数据

19数据库的备份,导入导出数据###### 备份的应用场景

在服务器进行数据传输、数据存储和数据交换,就有可能产生数据故障。比如发生意外停机或存储介质损坏。这时,如果没有采取数据备份和数据恢复手段与措施,就会导致数据的丢失,造成的损失是无法弥补与估量的。

1.数据库备份mysqldump

  备份与还原的语句

1 备份格式: DOS 下,未登录的时候。这是一个可执行文件 exe,在 bin 文件夹

mysqldump -u  用户名 -p  密码  数据库 >  文件的路径

2 还原格式:mysql 中的命令,需要登录后才可以操作

USE  数据库;

SOURCE  导入文件的路径;

3 备份操作:

-- 备份 day21 数据库中的数据到 d:\\test1027.sql 文件中

mysqldump -uroot -proot test1027 > d:/test1027.sql

  导出结果:数据库中的所有表和数据都会导出成 SQL 语句

4.2.4 还原操作

还原 test1019 数据库中的数据,注意:还原的时候需要先登录 MySQL,并选中对应的数据库。

1)  删除 test1019 数据库中的所有表

2)  登录 MySQL

3)  选中数据库

4)  使用 SOURCE 命令还原数据

5)  查看还原结果


source d:/test1019.sql;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QcTVN6zM-1603114808116)(数据库查询与事务/image-20201019165142277.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZjrIjxNK-1603114808119)(数据库查询与事务/image-20201019170409727.png)]

2.数据库恢复

3.导入导出数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3PZ7cW5X-1603114808121)(数据库查询与事务/image-20201019171244814.png)]

1.MySQL数据库事务的ACID原则是:
原子性:事务是一个整体;
一致性:前后数据总和不变;
隔离性:分支运行时,互不干扰;
持久性:数据一旦提交,不可撤回,不可逆性
2 何关闭和开启MySQL的自动提交:set autocommit=0关闭默认自动提交1开启
3MySQL的事务处理实现流程是:连接数据库,并给名字设置为中文然后建库。在准备工作完成后
3-1取消默认的自动提交并开启事务,set autocommit=0;然后begins,或start transaction
3-2进行多条SQL语句操作,中途如果停止执行,可选择回滚事务rollback,数据会恢复到数据更新之前的状态;如果正确的执行完毕,选择commit提交,就会持久化到数据库中,这个过程是不可逆的;
3-3设置恢复默认自动提交,set autocommit=1;恢复默认自动提交。并通过select检查执行结果;
4,5MySQL数据库有哪些索引及作用【高效安全的获取数据,提高访问效率】
主键:某个属性或属性的组合可以唯一标识一条记录;
全文索引fulltext:快速定位数据;
一般索引,默认是不甜的,可以快速定位数据;
唯一索引:去报同一表中某一列的值重复
5.MySQL备份的2种方法:
6.如何实现mysqldump的导出以及SOURCE导入

20.数据库事务管理

管理MySQL事务处理只支持InnoDB和BDB数据表

什么是事务**

  事务是指是程序中一系列严密的逻辑操作,而且所有操作必须全部成功完成,否则在每个操作中所作的所有更改都会被撤消。可以通俗理解为:就是把多件事情当做一件事情来处理,好比大家同在一条船上,要活一起活,要完一起完 。

 

**事物的四个特性(ACID)**

  **● 原子性**(Atomicity)****操作这些指令时,要么全部执行成功,要么全部不执行。只要其中一个指令执行失败,所有的指令都执行失败,数据进行回滚,回到执行指令前的数据状态。

> **eg:**拿转账来说,假设用户A和用户B两者的钱加起来一共是20000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是20000,这就是事务的一致性。

  **● 一致性**(Consistency)****事务的执行使数据从一个状态转换为另一个状态,但是对于整个数据的完整性保持稳定。

  **● 隔离性**(Isolation)****隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。

              即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。

  **● 持久性**(Durability)****当事务正确完成后,它对于数据的改变是永久性的。

> **eg:** 例如我们在使用JDBC操作数据库时,在提交事务方法后,提示用户事务操作完成,当我们程序执行完成直到看到提示后,就可以认定事务以及正确提交,即使这时候数据库出现了问题,也必须要将我们的事务完全执行完成,否则就会造成我们看到提示事务处理完毕,但是数据库因为故障而没有执行事务的重大错误。

 

**并发事务导致的问题**

  在许多事务处理同一个数据时,如果没有采取有效的隔离机制,那么并发处理数据时,会带来一些的问题。

  **** 第一类丢失更新:撤销一个事务时,把其他事务已提交的更新数据覆盖。

> **eg:**小明去银行柜台存钱,他的账户里原来的余额为100元,现在打算存入100元。在他存钱的过程中,银行年费扣了5元,余额只剩95元。突然他又想着这100元要用来请女朋友看电影吃饭,不打算存了。在他撤回存钱操作后,余额依然为他存钱之前的100元。所以那5块钱到底扣了谁的?

  

  **● 脏读:脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。**

> **eg:**小明的银行卡余额里有100元。现在他打算用手机点一个外卖饮料,需要付款10元。但是这个时候,他的女朋友看中了一件衣服95元,她正在使用小明的银行卡付款。于是小明在付款的时候,程序后台读取到他的余额只有5块钱了,根本不够10元,所以系统拒绝了他的交易,告诉余额不足。但是小明的女朋友最后因为密码错误,无法进行交易。小明非常郁闷,明明银行卡里还有100元,怎么会余额不足呢?(他女朋友更郁闷。。。)

 

  **● 幻读也叫虚读:一个事务执行两次查询,第二次结果集包含第一次中没有或某些行已经被删除的数据,造成两次结果不一致,只是另一个事务在这两次查询中间插入或删除了数据造成的。**幻读是事务非独立执行时发生的一种现象。

> **eg:**例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。

 

  **● 不可重复读:**一个事务两次读取同一行的数据,结果得到不同状态的结果,中间正好另一个事务更新了该数据,两次结果相异,不可被信任。

> **eg:**例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读。

> **Tips:**不可重复读和脏读的区别:脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。 

> **Tips:**幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。

 

  **** 第二类丢失更新:是不可重复读的特殊情况。如果两个事务都读取同一行,然后两个都进行写操作,并提交,第一个事务所做的改变就会丢失。

> **eg:**小明和女朋友一起去逛街。女朋友看中了一支口红,(对,女朋友就是用来表现买买买的)小明大方的掏出了自己的银行卡,告诉女朋友:亲爱的,随便刷,随便买,我坐着等你。然后小明就坐在商城座椅上玩手机,等着女朋友。这个时候,程序员的聊天群里有人推荐了一本书,小明一看,哎呀,真是本好书,还是限量发行呢,我一定更要买到。于是小明赶紧找到购买渠道,进行付款操作。而同时,小明的女朋友也在不亦乐乎的买买买,他们同时进行了一笔交易操作,但是这个时候银行系统出了问题,当他们都付款成功后,却发现,银行只扣了小明的买书钱,却没有扣去女朋友此时交易的钱。哈哈哈,小明真是太开心了!

 

**数据库事务的隔离级别**

  事务的隔离级别有4种,由低到高分别为**Read uncommitted****Read committed****Repeatable read****Serializable** 。而且,在事务的并发操作中可能会出现**脏读****不可重复读****幻读**。下面通过事例一一阐述它们的概念与联系。

**Read uncommitted(最低级别,任何情况都无法保证。)**

读未提交,顾名思义,就是一个事务可以读取另一个未提交事务的数据。

> **eg:**老板要给程序员发工资,程序员的工资是3.6/月。但是发工资时老板不小心按错了数字,按成3.9/月,该钱已经打到程序员的户口,但是事务还没有提交,就在这时,程序员去查看自己这个月的工资,发现比往常多了3千元,以为涨工资了非常高兴。但是老板及时发现了不对,马上回滚差点就提交了的事务,将数字改成3.6万再提交。

> **Analyse:**实际程序员这个月的工资还是3.6万,但是程序员看到的是3.9万。他看到的是老板还没提交事务时的数据。这就是脏读。

那怎么解决脏读呢?Read committed!读提交,能解决脏读问题。 

 

**Read committed(可避免脏读的发生。)**

读提交,顾名思义,就是一个事务要等另一个事务提交后才能读取数据。

> **eg:**程序员拿着信用卡去享受生活(卡里当然是只有3.6万),当他埋单时(程序员事务开启),收费系统事先检测到他的卡里有3.6万,就在这个时候!!程序员的妻子要把钱全部转出充当家用,并提交。当收费系统准备扣款时,再检测卡里的金额,发现已经没钱了(第二次检测金额当然要等待妻子转出金额事务提交完)。程序员就会很郁闷,明明卡里是有钱的…

> **Analyse:**这就是读提交,若有事务对数据进行更新(UPDATE)操作时,读操作事务要等待这个更新操作事务提交后才能读取数据,可以解决脏读问题。但在这个事例中,出现了一个事务范围内两个相同的查询却返回了不同数据,这就是不可重复读。

那怎么解决可能的不可重复读问题?Repeatable read !

 

**Repeatable read(可避免脏读、不可重复读的发生。)**

重复读,就是在开始读取数据(事务开启)时,不再允许修改操作

> **eg:**程序员拿着信用卡去享受生活(卡里当然是只有3.6万),当他埋单时(事务开启,不允许其他事务的UPDATE修改操作),收费系统事先检测到他的卡里有3.6万。这个时候他的妻子不能转出金额了。接下来收费系统就可以扣款了。

> **Analyse:**重复读可以解决不可重复读问题。写到这里,应该明白的一点就是,不可重复读对应的是修改,即UPDATE操作。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。

什么时候会出现幻读?

> **eg:**程序员某一天去消费,花了2千元,然后他的妻子去查看他今天的消费记录(全表扫描FTS,妻子事务开启),看到确实是花了2千元,就在这个时候,程序员花了1万买了一部电脑,即新增INSERT了一条消费记录,并提交。当妻子打印程序员的消费记录清单时(妻子事务提交),发现花了1.2万元,似乎出现了幻觉,这就是幻读。

那怎么解决幻读问题?Serializable!

 

**Serializable(可避免脏读、不可重复读、幻读的发生。)** 序列化

Serializable 是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。

> **Tips:大多数数据库默认的事务隔离级别是Read committed,比如Sql Server , Oracle。**
>
>     **Mysql的默认隔离级别是Repeatable read。**

> **Tips:**隔离级别的设置只对当前链接有效。对于使用MySQL命令窗口而言,一个窗口就相当于一个链接,当前窗口设置的隔离级别只对当前窗口中的事务有效;对于JDBC操作数据库来说,一个Connection对象相当于一个链接,而对于Connection对象设置的隔离级别只对该Connection对象有效,与其他链接Connection对象无关。

> **Tips:**设置数据库的隔离级别一定要是在开启事务之前

事务:一组SQL大于一句,同批次执行,结果要么一起成功要么一起失败;

应用场景:【银行】

ACID原则:

automicity原子性:事务是一个完整的操作,要么同时成功,要么同时失败;

consistency 一致性:最终一致性,事务前后数据完整,不改变;

isolation 隔离性:多个语句执行,各个对象互不干扰;【比如角色权限,有利于数据安全】

duralibiy持久性:事务没有【临时存储,如果取消自动提交或没有提交在dos窗口种,事务本身不会修改,】;当开启事务后,用begin【或者 start transaction ;】 进行update 及 set 修改数据时,每执行一句,临时修改一句,当使用rollback时,会返回初始状态;当提交后,数据就持久化了。即使关闭数据库,重新打开,数据还存在;事务一旦提交,不可逆;

1. 事务的基本介绍
1. 概念:
* 如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败。
2. 操作:
1. 开启事务: start transaction;2. 回滚:rollback;3. 提交:commit;3. 例子:
CREATE TABLE account (id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(10),balance DOUBLE);-- 添加数据
INSERT INTO account (NAME, balance) VALUES ('zhangsan', 1000), ('lisi', 1000);
   SELECT * FROM account;UPDATE account SET balance = 1000;-- 张三给李四转账 500-- 0. 开启事务
START TRANSACTION;-
- 1. 张三账户 -500UPDATE account SET balance = balance - 500 WHERE NAME = 'zhangsan';-
- 2. 李四账户 +500-- 出错了...UPDATE account SET balance = balance + 500 WHERE NAME = 'lisi';-
- 发现执行没有问题,提交事务COMMIT;-
- 发现出问题了,回滚事务ROLLBACK;
4. MySQL数据库中事务默认自动提交
* 事务提交的两种方式:
* 自动提交:
* mysql就是自动提交的
* 一条DML(增删改)语句会自动提交一次事务。
* 手动提交:
* Oracle 数据库默认是手动提交事务
* 需要先开启事务,再提交
* 修改事务的默认提交方式:
* 查看事务的默认提交方式:SELECT @@autocommit; 
-- 1 代表自动提交 0 代表手动提交
* 修改默认提交方式: set @@autocommit = 0;
2. 事务的四大特征:
1. 原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败。
2. 持久性:当事务提交或回滚后,数据库会持久化的保存数据。
3. 隔离性:多个事务之间。相互独立。
4. 一致性:事务操作前后,数据总量不变
3. 事务的隔离级别(了解)
* 概念:多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。
* 存在问题:
1. 脏读:一个事务,读取到另一个事务中没有提交的数据
2. 不可重复读(虚读):在同一个事务中,两次读取到的数据不一样。
3. 幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。
* 隔离级别:
1. read uncommitted:读未提交
* 产生的问题:脏读、不可重复读、幻读
2. read committed:读已提交 (Oracle)
* 产生的问题:不可重复读、幻读
3. repeatable read:可重复读 (MySQL默认)
* 产生的问题:幻读
4. serializable:串行化
* 可以解决所有的问题
​* 注意:隔离级别从小到大安全性越来越高,但是效率越来越低
* 数据库查询隔离级别:
* select @@tx_isolation;* 数据库设置隔离级别:
* set global transaction isolation level 级别字符串;* 演示:
set global transaction isolation level read uncommitted;start transaction;-- 转账操作
update account set balance = balance - 500 where id = 1;update account set balance = balance + 500 where id = 2;

存在干扰,隔离可能导致的问题

1.脏读,一个事物读取了另外一个没有提交的数据;

  1. 不可复读:多次结果不同,不一定错误

  2. 虚读,幻读,一个事务看到了别的事务插入的数据,前后结果不同;

    save point保存;rollback to savepoint 回滚到指定保存点;

    /*课堂测试题目 A在线买一款价格为500元商品,网上银行转账. A的银行卡余额为2000,然后给商家B支付500. 商家B一开始的银行卡余额为10000 创建数据库shop和创建表account并插入2条数据 */ – i显示建flight库语句

如果用dos窗口,需要先设置中文
    mysql -uroot -p   #连接数据库
    【输密码】******
    set names gbk;#设置中文编码
    
DROP DATABASE
IF
	EXISTS shop;
-- 用指定编码格式建库
CREATE DATABASE
IF
	NOT EXISTS shop CHARACTER 
	SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
-- 建立账户表
CREATE TABLE account ( id INT NOT NULL auto_increment PRIMARY KEY, NAME VARCHAR ( 32 ) NOT NULL, cash DECIMAL ( 9, 2 ) NOT NULL ) ENGINE = INNODB CHARSET = utf8mb4;

-- 插入信息语句
insert into account(name,cash) values ("唐哥",2000),("远哥",12000);
-- 实现转账
-- 1.建库并关闭自动提交
set autocommit=0;
-- 2.开启事务,并写更新语句
    start transaction;[或者begin;两者择其一]
UPDATE account set cash=cash+5000 where name="唐哥";#中途执行一半可选择性回滚;
UPDATE account set cash=cash-5000 where name="远哥";
-- 3.提交
COMMIT;
-- 4.恢复自动提交;
set autocommit=1;
-- 查询表
SELECT * from account;

21分析数据库执行性能

EXPLAIN 表名 (DESC 表名)
EXPLAIN SELECT语句

22.查询搜索引擎

22-1查询所有 show engines;mysql中5.5以后默认引擎是innodb

数据库语言与事务管理_第15张图片

22-2查询当前表的搜索引擎 show create table 表名;

数据库语言与事务管理_第16张图片

22-3常见搜索引擎

MySQL5.5以后默认使用InnoDB存储引擎,其中InnoDB和BDB提供事务安全表,其它存储引擎都是非事务安全表。
数据库语言与事务管理_第17张图片

MyISAM
它不支持事务,也不支持外键,尤其是【访问速度快】,对事务完整性没有要求或者以SELECT、INSERT为主的应用基本都可以使用这个引擎来创建表。每个MyISAM在磁盘上存储成3个文件,其中文件名和表名都相同(MYI,MYD,frm)【自动增长列恢复为原先的位置处开始自增】

InnoDB
  InnoDB存储引擎提供了具有【提交、回滚和崩溃恢复能力的事务安全】。但是对比MyISAM的存储引擎,InnoDB写的处理效率差一些并且会占用更多的磁盘空间以保留数据和索引。

默认值是保存在内存中,数据库重启后该值将会丢失【自动增长列恢复为0】

MEMORY
  memory使用存在内存中的内容来创建表。每个MEMORY表实际对应一个磁盘文件,格式是.frm。MEMORY类型的表访问非常快,因为它到数据是放在内存中的,并且默认使用HASH索引,但是一旦服务器关闭,表中的数据就会丢失,但表还会继续存在。
  默认情况下,memory数据表使用散列索引,利用这种索引进行“相等比较”非常快,但是对“范围比较”的速度就慢多了。因此,散列索引值适合使用在”=”和”<=>”的操作符中,不适合使用在”<”或”>”操作符中,也同样不适合用在order by字句里。如果确实要使用”<”或”>”或betwen操作符,可以使用btree索引来加快速度。

MEMORY
  memory使用存在内存中的内容来创建表。每个MEMORY表实际对应一个磁盘文件,格式是.frm。MEMORY类型的表访问非常快,因为它到数据是放在内存中的,并且默认使用HASH索引,但是一旦服务器关闭,表中的数据就会丢失,但表还会继续存在。
  默认情况下,memory数据表使用散列索引,利用这种索引进行“相等比较”非常快,但是对“范围比较”的速度就慢多了。因此,散列索引值适合使用在”=”和”<=>”的操作符中,不适合使用在”<”或”>”操作符中,也同样不适合用在order by字句里。如果确实要使用”<”或”>”或betwen操作符,可以使用btree索引来加快速度。
数据库语言与事务管理_第18张图片

数据库语言与事务管理_第19张图片# 24.。readUTF 的常规协定是

:该方法读取使用 UTF-8 修改版格式编码的 Unicode 字符串的表示形式;然后以 String 的形式返回此字符串

25数据库创建及编码方式设定sql语句记录

  • 创建数据库时,设置数据库的编码方式
    – CHARACTER SET:指定数据库采用的字符集,utf8不能写成utf-8
    – COLLATE:指定数据库字符集的排序规则,utf8的默认排序规则为utf8_general_ci(通过show character set查看)
    drop DATABASE if exists shop
    – 设置字符码编码格式;

    CREATE DATABASE shop CHARACTER set utf8mb4 COLLATE utf8mb4_0900_ai_ci;

    – 修改数据库编码格式
    alter DATABASE shop CHARACTER set GBK COLLATE gbk_chinese_ci;

    alter DATABASE shop CHARACTER set utf8 COLLATE utf8_general_ci;

    use kgc ;
    show create DATABASE kgc;
    CREATE DATABASE kgc /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci / /!80016 DEFAULT ENCRYPTION=‘N’ */
    – cha看数据库源码
    show VARIABLES like " %char%";

26..联合体union的基本特性——和struct的同与不同

union,中文名“联合体、共用体”,在某种程度上类似结构体struct的一种数据结构,共用体(union)和结构体(struct)同样可以包含很多种数据类型和变量。

不过区别也挺明显:

结构体(struct)中所有变量是“共存”的——优点是“有容乃大”,全面;缺点是struct内存空间的分配是粗放的,不管用不用,全分配。

而联合体(union)中是各变量是“互斥”的——缺点就是不够“包容”;但优点是内存使用更为精细灵活,也节省了内存空间。

缺省的情况下,UNION 子句不返回重复的记录.如果想显示所有记录,可以加ALL选项
UNION运算要求查询具有相同数目的字段.但是,字段数据类型不必相同.

 -- 32、查询所有“女"教师和“女"同学的name、sex和birthday.
SELECT concat("学生",sname),ssex,sbirthday from student where  ssex= "女"union ALL select concat("教师",tname ),tsex,tbirthday from teacher where  tsex= "女"; 

27.内关联【同一张表中查询】

-- 33、 查询成绩比该课程平均成绩低的同学的成绩表。
SELECT * FROM score s1 where degree <(SELECT avg(degree)from score s2 where s1.cno=s2.cno );
20、【3】查询score中选学多门课程的同学中分数为非最高分成绩的记录。
-- 查询学生记录;选 学多门;成绩小于最高分[两者成绩必须要关联起来]
SELECT * from score s1 where sno in (SELECT sno from score GROUP BY sno HAVING count(1)>1) and degree <(SELECT max(degree)from score s2 where s1.cno=s2.cno);
-- 【4】 28、查询“计算机系"与“电子工程系“不同职称的教师的Tname和Prof。[【自查询】双不同]
SELECT tname,prof FROM teacher t1 where prof not in (select prof from teacher t2 where t1.depart !=t2.depart );

28any至少高于

-- 29【5】、查询选修编号为“3-105“课程且成绩至少高于选修编号为“3-245"的同学的Cno、Sno和Degree,并按Degree从高到低次序排序。【为啥用any】

-- 至少高于多对多一对一比较条件表达式大于,所以用any 
 SELECT cno, sno, degree from score where cno="3-105"  and degree >any(SELECT degree from score where cno="3-245")   ORDER BY	degree desc; 
--  也可以获得大于选择的最低值;
SELECT cno,sno, degree from score where cno ="3-105" and degree >(SELECT min(degree) from score where cno="3-245") order by degree desc;

29任课老师,未讲课的老师

-- 34、 查询所有任课教师的Tname和Depart.【学生上老师的课,cno不为空】
SELECT tname, depart from teacher where tno in(select tno from course where cno in (select DISTINCT cno from score));
-- select tname,depart from teacher where tno in(select tno from course where cno in (select distinct cno from score))
-- 35 、 查询所有未讲课的教师的Tname和Depart.
SELECT tname, depart from teacher where tno  not in(select tno from course where cno in (select DISTINCT cno from score));

30.临时表

使用查询语句放入临时表的创建内容;关键字temporary;

1.删除临时表

drop table if exists temp_表名;

2.创建表

create temporary table temp_表名{

select * from hos_house order by hom_id limit 5,10;

#查询前5-10条记录;第一位是起始条数,第二位是页面大小,即每页多少条;limit 5=limit 0,5;前五条记录

}

3.查询表

select * from temp_表名;

31.exists 子查询的判断语句(select 子句 加 where 子句)

#exists关键字的使用
#检查“Logic Java”课程最近一次考试成绩
#如果有 80分以上的成绩,显示分数排在前5名的学员学号和分数

查询=select java=subject(subjectName)

#最近一次考试=result(examDate)
#成绩=result(studentResult)
#1.首先查询java的课程编号,因为result中只有课程编号=subjectNo
SELECT subjectNo FROM subject WHERE subjectName=‘java’
#2.根据课程编号查询java课程最近一次考试日期(result)
SELECT MAX(examDate) FROM result WHERE subjectNo=(SELECT subjectNo FROM subject WHERE subjectName=‘java’)
#3
SELECT res.studentNo,res.studentResult# resu和res 连接;
FROM result res
WHERE EXISTS( #跟的是一个select语句;如果存在,返回行,不存在返回null;
SELECT studentNo FROM result resu
WHERE resu.subjectNo=(SELECT subjectNo FROM subject WHERE subjectName=‘java’)
AND resu.examDate=(SELECT MAX(examDate) FROM result WHERE subjectNo=(SELECT subjectNo FROM subject WHERE subjectName=‘java’))
AND resu.studentResult>=60
)
AND res.subjectNo=(SELECT subjectNo FROM subject WHERE subjectName=‘java’)
AND res.examDate=(SELECT MAX(examDate) FROM result WHERE subjectNo=(SELECT subjectNo FROM subject WHERE subjectName=‘java’))
AND res.studentResult>=60
ORDER BY res.studentResult DESC
LIMIT 5;

32.arrayList和linkedlist 不同点;和线程状态运行过程

ArrayList默认构造的容量为10,没错。 因为ArrayList的底层是由一个Object[]数组构成的,而这个Object[]数组,默认的长度是10,所以有的文章会说ArrayList长度容量为10。

然而你所指的size()方法,指的是“逻辑”长度。
所谓“逻辑”长度,是指内存已存在的“实际元素的长度” 而“空元素不被计算”

即:当你利用add()方法,向ArrayList内添加一个“元素”时,逻辑长度就增加1位。 而剩下的9个空元素不被计算。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tabpcR5V-1603115004779)(数据库查询与事务/image-20201019155426293.png)]

33.视图【虚拟表,方便快速查询结果】

事务本身是不存数据的,是虚拟的表,是一个抽象的逻辑表,不是物理表,可以筛选一个表的多个字段的数据或者多个表种字段的数据;创建,删除表;

-- 1指定数据库;
use kgc ;
-- 2删除同名视图;
drop VIEW if EXISTS view_student_score;
-- 3.利用查询语句新建视图。视图名字和你所查询的表相关联,view_表名1_表名2;
CREATE view view_student_score as SELECT s.student_name,s.student_num,student_score,exam_date from student s, score sc where s.student_num=sc.student_num;
-- 4.查询语句进行快速获得查询结果;
SELECT * FROM view_student_score;

34.用户权限管理

*root是超级管理员用户,很容易引发由于误操作所导致的数据不安全问题,怎么办?*

*对不同用户进行合理的用户角色权限分配,即用户管理*

1. *创建普通用户*

*CREATE USER user@host [IDENTIFIED ‘password’]*

*【主机名@用户名 密码】*

*创建本地用户teacher,密码为123456,本地用户student,无密码*

*CREATE USER teacher@localhost IDENTIFIED BY ‘123456’;*

*CREATE USER student@localhost;* *本地用户,允许登录其他主机可省略*

*2.********通过查看系统数据库mysql中的user表查看存在用户*

*USE mysql;* *SELECT * FROM user;*

*3.创建用户并授权*

*GRANT priv_type********【用户操作权限列表】*

*ON databasename.tablename* *【权限范围,即库名.表名】*

*TO user@host[IDENTIFIED BY ‘password’]*

*1.如果授予所有权限, priv_type可使用ALL*

*2.为所有数据库和表授权,权限范围可使用*.**

*创建本地用户xiaoming,密码123456,赋予myschool数据库中student表增加和查询权限*

*GRANT INSERT,SELECT ON myschool.student TO xiaoming@localhost*

*IDENTIFIED BY ‘123456’;*

*为student@localhost用户授予myschool数据库中view_student视图的查询权限*

*GRANT SELECT ON myschool.view_student TO student@localhost;*

4. *-1使用mysqladmin命令修改root账户密码*

*mysqladmin需在DOS命令行执行,回车后输入原密码*

*mysqladmin –u username –p password “newpassword”*

*将root密码修改为1234*

*mysqladmin –u root –p password “1234” Enter password:*****

*4-2使用SET命令修改用户密码*

*只有超级管理员用户(如root用户)才能修改其他用户密码,如果是普通用户,可修改自己的密码*

*SET PASSWORD [FOR username@host]= PASSWORD(“newpassword”)*

*#修改当前用户密码*

*SET PASSWORD = PASSWORD(“0000”);*

*#修改其他用户密码*

*SET PASSWORD FOR teacher@localhost= PASSWORD(“8888”);*

*5.删除用户*

*DROP USER username1@host[,username2@host……];*

*DROP USER student@localhost;*

创建本地用户tom ,密码0000,赋予bookDB数据库book表全部权限,以下语句正确的是(      )。
CREATE USER `tom`@`localhost` IDENTIFIED BY '0000';【创建普通用户】
 CREATE USER `tom`@`localhost` IDENTIFIED BY '0000'   FOR   bookDB.*;
 GRANT  ALL ON bookdb.book TO tom'@'localhost';
  GRANT  *.* ON bookdb.book TO tom'@'localhost';
c
以下说法正确的是(       )。
修改root账户密码可使用mysqladmin语句,需登录MySQL后使用【dos】
任何用户都可以修改其他用户密码【超级管理员】
可从系统数据库mysql中查看所有用户信息
删除用户需使用DELETE USER语句【drop】
 c
DCL:
* SQL分类:
1. DDL:操作数据库和表
2. DML:增删改表中数据
3. DQL:查询表中数据
4. DCL:管理用户,授权
​* DBA:数据库管理员
​* DCL:管理用户,授权
1. 管理用户
1. 添加用户:
* 语法:CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
2. 删除用户:
* 语法:DROP USER '用户名'@'主机名';
3. 修改用户密码:
UPDATE USER SET PASSWORD = PASSWORD('新密码') WHERE USER = '用户名';
UPDATE USER SET PASSWORD = PASSWORD('abc') WHERE USER = 'lisi';
SET PASSWORD FOR '用户名'@'主机名' = PASSWORD('新密码');
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123');* mysql中忘记了root用户的密码?
1. cmd -- > net stop mysql 停止mysql服务
* 需要管理员运行该cmd​
2.使用无验证方式启动mysql服务: mysqld --skip-grant-tables
3. 打开新的cmd窗口,直接输入mysql命令,敲回车。就可以登录成功
4. use mysql;
5. update user set password = password('你的新密码') where user = 'root';
6. 关闭两个窗口
7. 打开任务管理器,手动结束mysqld.exe 的进程
8. 启动mysql服务
9. 使用新密码登录。
4. 查询用户:
-- 1. 切换到mysql数据库
USE myql;-- 
2. 查询user表
SELECT * FROM USER;* 通配符: % 表示可以在任意主机使用用户登录数据库
​2. 权限管理:
1. 查询权限:
-- 查询权限
SHOW GRANTS FOR '用户名'@'主机名';SHOW GRANTS FOR 'lisi'@'%';2. 授予权限:
-- 授予权限
grant 权限列表 on 数据库名.表名 to '用户名'@'主机名';-- 给张三用户授予所有权限,在任意数据库任意表上
GRANT ALL ON *.* TO 'zhangsan'@'localhost';
3. 撤销权限:
-- 撤销权限:
revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';REVOKE UPDATE ON db3.`account` FROM 'lisi'@'%'

35ifnull函数

IFNULL( 列名,默认值) 如果列名不为空,返回这列的值。如果为 NULL ,则返回默认值。

– 查询 id 字段,如果为 null,则使用 0 代替

SELECT IFNULL(ename,0) FROM emp;

我们可以利用 IFNULL()函数,如果记录为 NULL,给个默认值,这样统计的数据就不会遗漏

36内连接,外连接

笛卡尔积:
* 有两个集合A,B .取这两个集合的所有组成情况。
* 要完成多表查询,需要消除无用的数据
* 多表查询的分类:
1. 内连接查询:
1. 1  隐式内连接:使用where条件消除无用数据
* 例子:
-- 查询所有员工信息和对应的部门信息
​SELECT * FROM emp,dept WHERE emp.`dept_id` = dept.`id`;-
- 查询员工表的名称,性别。部门表的名称
SELECT emp.name,emp.gender,dept.name FROM emp,dept WHERE emp.`dept_id` = dept.`id`;. 2 显式内连接:
* 语法: select 字段列表 from 表名1 [inner] join 表名2 on 条件
* 例如:
* SELECT * FROM emp INNER JOIN dept ON emp.`dept_id` = dept.`id`; 
* SELECT * FROM emp JOIN dept ON emp.`dept_id` = dept.`id`; ​
 内连接查询:
1. 从哪些表中查询数据
2. 条件是什么
3. 查询哪些字段

2. 外链接查询:
1. 左外连接:
* 语法:select 字段列表 from 表1 left [outer] join 表2 on 条件;
* 查询的是左表所有数据以及其交集部分。
* 例子:
-- 查询所有员工信息,如果员工有部门,则查询部门名称,没有部门,则不显示部门名称
SELECT t1.*,t2.`name` FROM emp t1 LEFT JOIN dept t2 ON t1.`dept_id` = t2.`id`;
2. 右外连接:
* 语法:select 字段列表 from 表1 right [outer] join 表2 on 条件;
* 查询的是右表所有数据以及其交集部分。
* 例子:
SELECT * FROM dept t2 RIGHT JOIN emp t1 ON t1.`dept_id` = t2.`id`;

3. 子查询:
* 概念:查询中嵌套查询,称嵌套查询为子查询。
-- 查询工资最高的员工信息
-- 1 查询最高的工资是多少 9000 
SELECT MAX(salary) FROM emp;-
- 2 查询员工信息,并且工资等于9000的
SELECT * FROM emp WHERE emp.`salary` = 9000;-- 一条sql就完成这个操作。子查询
SELECT * FROM emp WHERE emp.`salary` = (SELECT MAX(salary) FROM emp);* 子查询不同情况
1. 子查询的结果是单行单列的:
* 子查询可以作为条件,使用运算符去判断。 运算符: > >= < <= =* -- 查询员工工资小于平均工资的人
SELECT * FROM emp WHERE emp.salary < (SELECT AVG(salary) FROM emp);

2. 子查询的结果是多行单列的:
* 子查询可以作为条件,使用运算符in来判断
-- 查询'财务部''市场部'所有的员工信息
SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部';
SELECT * FROM emp WHERE dept_id = 3 OR dept_id = 2;-
- 子查询
SELECT * FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部');3. 子查询的结果是多行多列的:
* 子查询可以作为一张虚拟表参与查询
-- 查询员工入职日期是2011-11-11日之后的员工信息和部门信息
-- 子查询
SELECT * FROM dept t1 ,(SELECT * FROM emp WHERE emp.`join_date` > '2011-11-11') t2WHERE t1.id = t2.dept_id;-
- 普通内连接
SELECT * FROM emp t1,dept t2 WHERE t1.`dept_id` = t2.`id` AND t1.`join_date` > '2011-11-11'* 多表查询练习
​
-- 1.查询所有员工信息。查询员工编号,员工姓名,工资,职务名称,职务描述
/*
分析:
1.员工编号,员工姓名,工资,需要查询emp表 职务名称,职务描述 需要查询job表
2.查询条件 emp.job_id = job.id*/SELECT t1.`id`, -- 员工编号
t1.`ename`, -- 员工姓名
t1.`salary`,-- 工资
t2.`jname`, -- 职务名称
t2.`description` -- 职务描述
FROM emp t1, job t2WHERE t1.`job_id` = t2.`id`;
                                                       
-- 2.查询员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置
/*
分析:
1. 员工编号,员工姓名,工资 emp 职务名称,职务描述 job 部门名称,部门位置 dept2. 条件: emp.job_id = job.id and emp.dept_id = dept.id*/SELECT t1.`id`, -- 员工编号
t1.`ename`, -- 员工姓名
t1.`salary`,-- 工资
t2.`jname`, -- 职务名称
t2.`description`, -- 职务描述
t3.`dname`, -- 部门名称
t3.`loc` -- 部门位置
FROM emp t1, job t2,dept t3WHERE t1.`job_id` = t2.`id` AND t1.`dept_id` = t3.`id`;  -- 3.查询员工姓名,工资,工资等级
/*
分析:
1.员工姓名,工资 emp 工资等级 salarygrade2.条件 emp.salary >= salarygrade.losalary and emp.salary <= salarygrade.hisalaryemp.salary BETWEEN salarygrade.losalary and salarygrade.hisalary*/SELECT t1.ename ,t1.`salary`,t2.*FROM emp t1, salarygrade t2WHERE t1.`salary` BETWEEN t2.`losalary` AND t2.`hisalary`;
                                                       
-- 4.查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级
/*
分析:
1. 员工姓名,工资 emp , 职务名称,职务描述 job 部门名称,部门位置,dept 工资等级 salarygrade2. 条件: emp.job_id = job.id and emp.dept_id = dept.id and emp.salary BETWEEN salarygrade.losalary and salarygrade.hisalary*/SELECT t1.`ename`,t1.`salary`,t2.`jname`,t2.`description`,t3.`dname`,t3.`loc`,t4.`grade`FROM emp t1,job t2,dept t3,salarygrade t4WHERE t1.`job_id` = t2.`id` AND t1.`dept_id` = t3.`id`AND t1.`salary` BETWEEN t4.`losalary` AND t4.`hisalary`;
                                                       
-- 5.查询出部门编号、部门名称、部门位置、部门人数
/*
分析:
1.部门编号、部门名称、部门位置 dept 表。 部门人数 emp表
2.使用分组查询。按照emp.dept_id完成分组,查询count(id)3.使用子查询将第2步的查询结果和dept表进行关联查询
*/SELECT t1.`id`,t1.`dname`,t1.`loc` , t2.totalFROM dept t1,(SELECTdept_id,COUNT(id) totalFROM empGROUP BY dept_id) t2WHERE t1.`id` = t2.dept_id;
                           
-- 6.查询所有员工的姓名及其直接上级的姓名,没有领导的员工也需要查询
/*
分析:
1.姓名 emp, 直接上级的姓名 emp* emp表的id 和 mgr 是自关联
2.条件 emp.id = emp.mgr3.查询左表的所有数据,和 交集数据
* 使用左外连接查询
*//*selectt1.ename,t1.mgr,t2.`id`,t2.enamefrom emp t1, emp t2where t1.mgr = t2.`id`;*/SELECT t1.ename,t1.mgr,t2.`id`,t2.`ename`FROM emp t1LEFT JOIN emp t2ON t1.`mgr` = t2.`id`;

37mysql总结补充

数据库语言与事务管理_第20张图片

每行 SQL 语句需要选中再执行,可以按 F9
`反引号是为了避免与关键字冲突
使用 truncate 删除表中所有记录TRUNCATE TABLE 表名;

truncate 和 delete 的区别:truncate 相当于删除表的结构,再创建一张表。

in 里面的每个数据都会作为一次条件,只要满足条件的就会显示
范围查询BETWEEN 值 值 1 AND 值 值 2,包头又包尾
什么是单列排序:只按某一个字段进行排序,单列排序;什么是组合排序?同时对多个字段进行排序,如果第 1 个字段相等,则按第 2 个字段排序,依次类推
创建好以后修改起始值ALTER TABLE 表名 AUTO_INCREMENT= 起始值;。

DELETE 和 TRUNCATE 对自增长的影响

DELETE:删除所有的记录之后,自增长没有影响。

TRUNCATE:删除以后,自增长又重新开始

目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF) 、第四范式(4NF)和第五范式(5NF,又称完美范式)

你可能感兴趣的:(数据库语言与事务管理)