【MySQL基础】

1、初识Mysql

1.1 安装mysql

建议安装压缩包版本,因为卸载方便干净,exe版本的安装和卸载不方便

1、解压缩文件mysql-5.7.19-winx64.zip,到相应的位置

2、配置环境变量,变量值为bin目录,例如:D:\Environment\mysql-5.7.19\bin

3、安装的根目录(D:\Environment\mysql-5.7.19)新建一个配置文件my.ini

[mysqld]
basedir=D:\Environment\mysql-5.7.19\
datadir=D:\Environment\mysql-5.7.19\data\
port=3306
skip-grant-tables

skip-grant-tables 为跳过密码验证,data目录不用手动创建,自己生成的

4、管理员身份打开CMD,执行 cd /d D:\Environment\mysql-5.7.19\bin 进入bin目录

​ 执行mysqld -install命令

5、输入mysqld --initialize-insecure --user=mysql初始化数据文件

6、net start mysql命令启动服务

7、进入mysql,执行mysql -u root -p密码为空

8、更改登录密码语句,update mysql.user set authentication_string=password(“123456”) where user=“root” and Host=“localhost”;

9、刷新权限,flush privileges;

10、修改my.ini文件,#skip-grant-tables加井号注释掉

11、退出mysql命令exit,net stop mysql停止服务,net start mysql命令再次启动服务

12、重新进入成功!

sc delete mysql清空服务,就是删掉mysql服务

1.2 安装SQLyog

版本:SQLyog-12.0.8-0.x64.exe

注册—>>>名称:随便写

​ 证书密钥:8d8120df-a5c3-4989-8f47-5afc79c56e7c

1.3 命令行连接数据库

配置好环境变量的情况下,直接在命令行mysql -u root -p,可以连接mysql

show databases; -- 查看所有数据库

use school -- 切换数据库 use 数据库名

show tables; -- 查看所有的表

describe student; -- 显示表中所有的字段

create database mydata; -- 创建一个数据库

exit -- 退出连接

2、操作数据库

sql语句不区分大小写

2.1 操作数据库(了解)

1、创建数据库

CREATE DATABASE IF NOT EXISTS school;

2、删除数据库

DROP DATABASE IF EXISTS school;

3、使用数据库

-- 如果表名和字段是一个特殊字符,则需要加``
USE `school`;

4、查看数据库

SHOW DATABASES;

2.2 数据库的列类型

数值

  • tinyint 十分小的数据 1个字节
  • samllint 较小的数据 2个字节
  • mediumint 中等大小的数据 3个字节
  • int 标准的整数 4个字节 (常用的)
  • bigint 较大的数据 8个字节
  • float 浮点数 4个字节
  • double 浮点数 8个字节
  • decimal 字符串形式的浮点数 ,金融计算的时候使用

字符串

  • char 字符串固定大小 0-255
  • varchar 可变字符串 0-65535 (常用)
  • tinytext 微型文本 2^8-1
  • text 文本串 2^16-1

事件日期

- date              YYYY-MM-DD    日期格式
- time               HH:mm:ss      时间格式
- datetime        YYYY-mm-ss  HH:MM:SS     (常用)
- timestamp     时间戳        也常用

null

- 没有值,未知
- 不要使用进行运算

2.3 数据库的字段属性(重点)

unsigned:

  • 无符号的整数
  • 声明该列值不能为负数

zerofill:

- 0填充的
- 不足的位使用0来填充

自增:

  • 自动在上一条记录上增加1(默认)
  • 通常用来设置唯一的主键,必须是整数类型
  • 可以自定义自增的起始值和步长

非空:

- 设置为非空的字段,在添加数据市不给它赋值,会报错
- 如果不勾选非空,则默认为null

默认:

  • 设置默认的值
  • 如果不指定该列的值,则会有默认的值

2.4 创建数据库表

数据类型后面的顺序可以颠倒,但是建议还是有一定规律去写

表的名和字段使用``括起来

字符串使用单引号括起来

-- 表的名和字段使用``括起来
-- AUTO_INCREMENT 自增
-- 字符串使用单引号括起来
-- PRIMARY KEY为主键
CREATE TABLE IF NOT EXISTS `student`( 
`id` INT(4) NOT NULL AUTO_INCREMENT COMMENT '学号',
`name` VARCHAR(30) NOT NULL DEFAULT '匿名' COMMENT '姓名',
`pwd` VARCHAR(10) NOT NULL DEFAULT '123456' COMMENT '密码',
`sex` VARCHAR(1) NOT NULL DEFAULT '男' COMMENT '性别',
`birthday` DATETIME DEFAULT NULL COMMENT '生日',
`address` VARCHAR(30) DEFAULT NULL COMMENT '地址',
`email` VARCHAR(50) DEFAULT NULL COMMENT '邮件',
PRIMARY KEY(`id`)
)
ENGINE=INNODB DEFAULT CHARSET=utf8;

格式

CREATE TABLE [IF NOT EXISTS] `表名`(
    `字段名` 列类型 [属性] [索引] [注释],
    .....
    `字段名` 列类型 [属性] [索引] [注释]
)[表类型] [字符集设置][注释]

常用命令

SHOW CREATE DATABASE school; -- 查询创建数据库的语句
SHOW CREATE TABLE student; -- 查询创建表的语句
DESCRIBE student; -- 显示表的结构,或DESC student;

2.5 数据表的类型

-- 关于数据库引擎
/**
	 InnoDB 默认使用
     MyISAM 早期使用
*/
MyISAMInnoDB
事务支持不支持支持
数据行锁定不支持支持
外键约束不支持支持
全文索引支持不支持
表空间大小较小较大,约为2倍
在物理文件上的区别文件*.frm 表结构定义文件,*.MYD 数据文件,*.MYI 索引文件数据库表只有一个*.frm文件,以及上级ibdata1文件

所有数据库文件都存在data目录下,一个文件夹代表一个数据库

本质还是文件存储

2.6 修改删除表

修改

-- 格式:ALTER TABLE 旧表名 RENAME AS 新表明;
ALTER TABLE student1 RENAME AS teacher; -- 更改表名

-- 格式:ALTER TABLE 表名 ADD 字段 列属性;
ALTER TABLE teacher ADD age INT(3);-- 表中增加字段

-- 格式:ALTER TABLE 表名 MODIFY 字段 列属性;
ALTER TABLE teacher MODIFY age VARCHAR(11); -- 修改表字段约束

-- 格式:ALTER TABLE 表名 CHANGE 旧字段 新字段 列属性;
ALTER TABLE teacher CHANGE age1 age VARCHAR(3); -- 修改表字段名称,并改约束

-- 格式:ALTER TABLE 表名 DROP 字段;
ALTER TABLE teacher DROP age; -- 删除表中的子段

删除

DROP TABLE IS EXISTS teacher; -- 删除表

3、MySQL数据库管理

3.1 外键(了解)

方式一,在创建表的时候,增加约束(麻烦,比较复杂)

-- 创建grade表
CREATE TABLE `grade`(
	`gradeid` INT(10) NOT NULL AUTO_INCREMENT COMMENT '年级id',
	`gradename` VARCHAR(50) NOT NULL COMMENT '年级名称',
	PRIMARY KEY(`gradeid`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;

要删除有引用关系的表,先删除引用的,再删除被引用的

-- 创建student表,并设置外键
CREATE TABLE `student`(
	`id` INT(10) NOT NULL AUTO_INCREMENT COMMENT '学生id',
	`name` VARCHAR(30) NOT NULL COMMENT '学生名字',
	`gradeid` INT(10) NOT NULL COMMENT '学生年级',
	`age` INT(3) NOT NULL DEFAULT "10",
	PRIMARY KEY(`id`),
	KEY `FK_gradeid` (`gradeid`),
	CONSTRAINT `FK_gradeid` FOREIGN KEY (`gradeid`) REFERENCES `grade`(`gredeid`)
)ENGINE= INNODB DEFAULT CHARSET= utf8;

方式二,先创建表后,再添加外键

格式:ALTER TABLE 表名 ADD CONSTRAINT 约束名 FOREIGN KEY (作为外键的列) REFERENCES 哪个表(哪个字段)

ALTER TABLE `student` ADD
CONSTRAINT `FK_gradeid` FOREIGN KEY (`gradeid`) REFERENCES `grade`(`gradeid`);

以上都是物理外键,数据库级别的外键,我们不建议使用(避免数据多造成困扰)

最佳实践:

- 数据库就是单纯的表,只用来存数据,只有行(数据)和列(字段)
- 我们想使用多张表的数据,想使用外键(程序去实现)

3.2 DML语言(掌握)

DML:数据库管理语言

​ insert:插入

​ update:修改

​ delete:删除

3.3 添加

insert into 表名(字段名) values(‘值’);

-- 插入一个字段格式: INSERT INTO `表名`[(`字段1`,`字段1`)] VALUES('值1',值2);
INSERT INTO `student`(`name`,`gradeid`,`age`) VALUES('陕西',3,23);
-- 插入多个字段格式: INSERT INTO `表名`[(`字段1`,`字段1`)] VALUES('值1',值2),('值1',值2);
INSERT INTO `student`(`name`,`gradeid`,`age`) VALUES('陕西',3,23),('北京',2,32);
-- 表字段可以省略,前提是,字段可以为空,值和字段是一一对应的

3.4 修改

UPDATE 表名 SET 字段名 = ‘值’ WHERE 字段名 = 值;

字段的值也可以设置为变量

-- 修改名字为张三,条件是id为4
UPDATE `student` SET `name` = '张三' WHERE `id` = 4;
-- 修改名字为李四,无条件,则会改所有的记录
UPDATE `student` SET `name` = '李四'
-- 修改多个属性,用逗号隔开
UPDATE `student` SET `name` = '王五',`age` = 78 WHERE `id` = 6;

where 后面的运算语句,和java中的类似,不多赘述

​ between…and…,在什么之间

3.5 删除

-- 删除全部数据(避免这样写,会删除全部数据)
DELETE FROM `student`;
-- 删除指定数据
DELETE FROM `student` WHERE `id` = 5;

-- 清空一个数据库表,表的结构和索引约束不变
TRUNCATE `grade`;

TRUNCATE和DELETE的区别:

	- TRUNCATE 重新设置自增列,计数器归零,不会影像事务
	- DELETE 不会重新设置自增列

4、DQL查询数据(超重点)

4.1 DQL

​ Data Query Language 数据查询语言

生成的测试数据:

-- 创建数据库
CREATE DATABASE `school`;
-- 切换到数据库
USE `school`;
-- 创建年级表
CREATE TABLE `grade`(
	`gradeid` INT(10) NOT NULL AUTO_INCREMENT COMMENT '年级id',
	`gradename` VARCHAR(10) NOT NULL COMMENT '年级名称',
	PRIMARY KEY(`gradeid`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;
-- 插入年级数据
INSERT INTO `grade`(`gradename`)VALUES('大一'),('大二'),('大三'),('大四'),('预科班');

-- 创建学生表
CREATE TABLE `student`(
	`StudentNo` INT(10) NOT NULL AUTO_INCREMENT COMMENT '学号',
	`LoginPwd` VARCHAR(10) NOT NULL COMMENT '登录密码',
	`StudentName` VARCHAR(10) NOT NULL COMMENT '学生姓名',
	`Sex` INT(1) NOT NULL COMMENT  '性别',
	`GradeId` INT(1) NOT NULL COMMENT '年级id',
	`Phone` VARCHAR(11) NOT NULL COMMENT '电话',
	`Address` VARCHAR(50) NOT NULL COMMENT '地址',
	`BornDate` DATETIME  NOT NULL COMMENT '出生日期',
	`Email` VARCHAR(50) NOT NULL COMMENT '邮箱',
	`IdentityCard` VARCHAR(18) NOT NULL COMMENT '身份证',
	PRIMARY KEY(`StudentNo`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;

-- 设置主键的起始值
ALTER TABLE `student` AUTO_INCREMENT=1000;

-- 插入学生数据
INSERT INTO `student`(`LoginPwd`,`StudentName`,`Sex`,`GradeId`,`Phone`,`Address`,`BornDate`,`Email`,`IdentityCard`)
VALUES('225215','周丹',1,1,'13500000001','北京市海淀区中关村1号','1987-12-11 00:00:00','test@qq.com','610121198305184232'),
('111111','周丹',1,1,'13500000002','北京市海淀区中关村1号','1987-12-11 00:00:00','test@qq.com','610121198305184232'),
('22521','周颖',1,2,'13500000003','北京市海淀区中关村1号','1986-12-11 00:00:00','test@qq.com','610121198305184232'),
('111111','杨文瑞',2,3,'13500000004','北京市海淀区中关村1号','1983-12-11 00:00:00','test@qq.com','610121198305184232'),
('22521','韩萌',2,1,'13500000005','北京市海淀区中关村1号','1987-12-11 00:00:00','test@qq.com','610121198305184232'),
('22521','刘丽霞',1,4,'13500000006','北京市海淀区中关村1号','1985-12-11 00:00:00','test@qq.com','610121198305184232'),
('111111','蒋家航',2,1,'13500000007','北京市海淀区中关村1号','1987-12-11 00:00:00','test@qq.com','610121198305184232'),
('22521','郑家稀',1,3,'13500000008','北京市海淀区中关村1号','1982-12-11 00:00:00','test@qq.com','610121198305184232'),
('111111','刘洋',1,2,'13500000009','北京市海淀区中关村1号','1987-12-11 00:00:00','test@qq.com','610121198305184232'),
('22521','张扬',2,1,'13500000010','北京市海淀区中关村1号','1986-12-11 00:00:00','test@qq.com','610121198305184232'),
('111111','赵杰',2,4,'13500000011','北京市海淀区中关村1号','1987-12-11 00:00:00','test@qq.com','610121198305184232'),
('22521','赵成',2,4,'13500000012','北京市海淀区中关村1号','1984-12-11 00:00:00','test@qq.com','610121198305184232'),
('111111','刘恒',1,1,'13500000013','北京市海淀区中关村1号','1987-12-11 00:00:00','test@qq.com','610121198305184232'),
('22521','张玮琪',1,3,'13500000014','北京市海淀区中关村1号','1986-12-11 00:00:00','test@qq.com','610121198305184232'),
('111111','马会',2,1,'13500000015','北京市海淀区中关村1号','1987-12-11 00:00:00','test@qq.com','610121198305184232'),
('22521','陈冕',1,3,'13500000016','北京市海淀区中关村1号','1984-12-11 00:00:00','test@qq.com','610121198305184232'),
('111111','赵辉',2,3,'13500000017','北京市海淀区中关村1号','1987-12-11 00:00:00','test@qq.com','610121198305184232'),
('22521','王珊',1,1,'13500000018','北京市海淀区中关村1号','1981-12-11 00:00:00','test@qq.com','610121198305184232');

-- 创建科目表
CREATE TABLE `subject`(
	`SubjectNo` INT(5) NOT NULL AUTO_INCREMENT COMMENT '科目id',
	`SubjectName` VARCHAR(50) NOT NULL COMMENT '科目名',
	`ClassHour` INT(5) NOT NULL COMMENT  '学时',
	`GradeId` INT(1) NOT NULL COMMENT '年级id',
	PRIMARY KEY(`SubjectNo`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;

-- 插入科目数据
INSERT INTO `subject`(`SubjectName`,`ClassHour`,`GradeId`)
VALUES('高等数学-1',90,1),('高等数学-2',100,2),('高等数学-3',90,3),('高等数学-4',120,4),
('C语言-1',100,1),('C语言-2',90,2),('C语言-3',150,3),('C语言-4',120,4),('java-1',100,1),
('java-2',90,2),('java-3',150,3),('java-4',120,4),('数据库结构-1',100,1),('数据库结构-2',90,2),
('数据库结构-3',150,3),('数据库结构-4',120,4),('C#基础',120,1);

-- 创建考试成绩表
CREATE TABLE `result`(
	`StudentNo` INT(10) NOT NULL COMMENT '学生id',
	`SubjectNo` INT(5) NOT NULL COMMENT '科目id',
	`ExemDate` DATETIME NOT NULL COMMENT '考试时间',
	`StudentResult` INT(3) NOT NULL COMMENT '成绩'
)ENGINE=INNODB DEFAULT CHARSET=utf8;
-- 插入年级数据
INSERT INTO `result`(`StudentNo`,`SubjectNo`,`ExemDate`,`StudentResult`)
VALUES
(1000,1,'2011-12-5 00:00:00',99),(1000,2,'2011-12-5 00:00:00',89),(1000,3,'2011-12-5 00:00:00',87),(1000,4,'2011-12-5 00:00:00',95),
(1000,5,'2011-12-5 00:00:00',84),(1000,6,'2011-12-5 00:00:00',92),(1000,7,'2011-12-5 00:00:00',94),(1000,8,'2011-12-5 00:00:00',78),
(1000,9,'2011-12-5 00:00:00',84),(1000,10,'2011-12-5 00:00:00',86),(1000,11,'2011-12-5 00:00:00',72),(1000,12,'2011-12-5 00:00:00',82),
(1000,13,'2011-12-5 00:00:00',79),(1000,14,'2011-12-5 00:00:00',69),(1000,15,'2011-12-5 00:00:00',86),(1000,16,'2011-12-5 00:00:00',83),
(1001,1,'2011-12-5 00:00:00',99),(1001,2,'2011-12-5 00:00:00',89),(1001,3,'2011-12-5 00:00:00',87),(1001,4,'2011-12-5 00:00:00',95),
(1001,5,'2011-12-5 00:00:00',84),(1001,6,'2011-12-5 00:00:00',92),(1001,7,'2011-12-5 00:00:00',94),(1001,8,'2011-12-5 00:00:00',78),
(1001,9,'2011-12-5 00:00:00',84),(1001,10,'2011-12-5 00:00:00',86),(1001,11,'2011-12-5 00:00:00',72),(1001,12,'2011-12-5 00:00:00',82),
(1001,13,'2011-12-5 00:00:00',79),(1001,14,'2011-12-5 00:00:00',69),(1001,15,'2011-12-5 00:00:00',86),(1001,16,'2011-12-5 00:00:00',83),
(1002,1,'2011-12-5 00:00:00',99),(1002,2,'2011-12-5 00:00:00',89),(1002,3,'2011-12-5 00:00:00',87),(1002,4,'2011-12-5 00:00:00',95),
(1002,5,'2011-12-5 00:00:00',84),(1002,6,'2011-12-5 00:00:00',92),(1002,7,'2011-12-5 00:00:00',94),(1002,8,'2011-12-5 00:00:00',78),
(1002,9,'2011-12-5 00:00:00',84),(1002,10,'2011-12-5 00:00:00',86),(1002,11,'2011-12-5 00:00:00',72),(1002,12,'2011-12-5 00:00:00',82),
(1002,13,'2011-12-5 00:00:00',79),(1002,14,'2011-12-5 00:00:00',69),(1002,15,'2011-12-5 00:00:00',86),(1002,16,'2011-12-5 00:00:00',83),
(1003,1,'2011-12-5 00:00:00',99),(1003,2,'2011-12-5 00:00:00',89),(1003,3,'2011-12-5 00:00:00',87),(1003,4,'2011-12-5 00:00:00',95),
(1003,5,'2011-12-5 00:00:00',84),(1003,6,'2011-12-5 00:00:00',92),(1003,7,'2011-12-5 00:00:00',94),(1003,8,'2011-12-5 00:00:00',78),
(1003,9,'2011-12-5 00:00:00',84),(1003,10,'2011-12-5 00:00:00',86),(1003,11,'2011-12-5 00:00:00',72),(1003,12,'2011-12-5 00:00:00',82),
(1003,13,'2011-12-5 00:00:00',79),(1003,14,'2011-12-5 00:00:00',69),(1003,15,'2011-12-5 00:00:00',86),(1003,16,'2011-12-5 00:00:00',83),
(1004,1,'2011-12-5 00:00:00',99),(1004,2,'2011-12-5 00:00:00',89),(1004,3,'2011-12-5 00:00:00',87),(1004,4,'2011-12-5 00:00:00',95),
(1004,5,'2011-12-5 00:00:00',84),(1004,6,'2011-12-5 00:00:00',92),(1004,7,'2011-12-5 00:00:00',94),(1004,8,'2011-12-5 00:00:00',78),
(1004,9,'2011-12-5 00:00:00',84),(1004,10,'2011-12-5 00:00:00',86),(1004,11,'2011-12-5 00:00:00',72),(1004,12,'2011-12-5 00:00:00',82),
(1004,13,'2011-12-5 00:00:00',79),(1004,14,'2011-12-5 00:00:00',69),(1004,15,'2011-12-5 00:00:00',86),(1004,16,'2011-12-5 00:00:00',83),
(1005,1,'2011-12-5 00:00:00',99),(1005,2,'2011-12-5 00:00:00',89),(1005,3,'2011-12-5 00:00:00',87),(1005,4,'2011-12-5 00:00:00',95),
(1005,5,'2011-12-5 00:00:00',84),(1005,6,'2011-12-5 00:00:00',92),(1005,7,'2011-12-5 00:00:00',94),(1005,8,'2011-12-5 00:00:00',78),
(1005,9,'2011-12-5 00:00:00',84),(1005,10,'2011-12-5 00:00:00',86),(1005,11,'2011-12-5 00:00:00',72),(1005,12,'2011-12-5 00:00:00',82),
(1005,13,'2011-12-5 00:00:00',79),(1005,14,'2011-12-5 00:00:00',69),(1005,15,'2011-12-5 00:00:00',86),(1005,16,'2011-12-5 00:00:00',83),
(1006,1,'2011-12-5 00:00:00',99),(1006,2,'2011-12-5 00:00:00',89),(1006,3,'2011-12-5 00:00:00',87),(1006,4,'2011-12-5 00:00:00',95),
(1006,5,'2011-12-5 00:00:00',84),(1006,6,'2011-12-5 00:00:00',92),(1006,7,'2011-12-5 00:00:00',94),(1006,8,'2011-12-5 00:00:00',78),
(1006,9,'2011-12-5 00:00:00',84),(1006,10,'2011-12-5 00:00:00',86),(1006,11,'2011-12-5 00:00:00',72),(1006,12,'2011-12-5 00:00:00',82),
(1006,13,'2011-12-5 00:00:00',79),(1006,14,'2011-12-5 00:00:00',69),(1006,15,'2011-12-5 00:00:00',86),(1006,16,'2011-12-5 00:00:00',83),
(1007,1,'2011-12-5 00:00:00',99),(1007,2,'2011-12-5 00:00:00',89),(1007,3,'2011-12-5 00:00:00',87),(1007,4,'2011-12-5 00:00:00',95),
(1007,5,'2011-12-5 00:00:00',84),(1007,6,'2011-12-5 00:00:00',92),(1007,7,'2011-12-5 00:00:00',94),(1007,8,'2011-12-5 00:00:00',78),
(1007,9,'2011-12-5 00:00:00',84),(1007,10,'2011-12-5 00:00:00',86),(1007,11,'2011-12-5 00:00:00',72),(1007,12,'2011-12-5 00:00:00',82),
(1007,13,'2011-12-5 00:00:00',79),(1007,14,'2011-12-5 00:00:00',69),(1007,15,'2011-12-5 00:00:00',86),(1007,16,'2011-12-5 00:00:00',83),
(1008,1,'2011-12-5 00:00:00',99),(1008,2,'2011-12-5 00:00:00',89),(1008,3,'2011-12-5 00:00:00',87),(1008,4,'2011-12-5 00:00:00',95),
(1008,5,'2011-12-5 00:00:00',84),(1008,6,'2011-12-5 00:00:00',92),(1008,7,'2011-12-5 00:00:00',94),(1008,8,'2011-12-5 00:00:00',78),
(1008,9,'2011-12-5 00:00:00',84),(1008,10,'2011-12-5 00:00:00',86),(1008,11,'2011-12-5 00:00:00',72),(1008,12,'2011-12-5 00:00:00',82),
(1008,13,'2011-12-5 00:00:00',79),(1008,14,'2011-12-5 00:00:00',69),(1008,15,'2011-12-5 00:00:00',86),(1008,16,'2011-12-5 00:00:00',83),
(1009,1,'2011-12-5 00:00:00',99),(1009,2,'2011-12-5 00:00:00',89),(1009,3,'2011-12-5 00:00:00',87),(1009,4,'2011-12-5 00:00:00',95),
(1009,5,'2011-12-5 00:00:00',84),(1009,6,'2011-12-5 00:00:00',92),(1009,7,'2011-12-5 00:00:00',94),(1009,8,'2011-12-5 00:00:00',78),
(1009,9,'2011-12-5 00:00:00',84),(1009,10,'2011-12-5 00:00:00',86),(1009,11,'2011-12-5 00:00:00',72),(1009,12,'2011-12-5 00:00:00',82),
(1009,13,'2011-12-5 00:00:00',79),(1009,14,'2011-12-5 00:00:00',69),(1009,15,'2011-12-5 00:00:00',86),(1009,16,'2011-12-5 00:00:00',83),
(1010,1,'2011-12-5 00:00:00',99),(1010,2,'2011-12-5 00:00:00',89),(1010,3,'2011-12-5 00:00:00',87),(1010,4,'2011-12-5 00:00:00',95),
(1010,5,'2011-12-5 00:00:00',84),(1010,6,'2011-12-5 00:00:00',92),(1010,7,'2011-12-5 00:00:00',94),(1010,8,'2011-12-5 00:00:00',78),
(1010,9,'2011-12-5 00:00:00',84),(1010,10,'2011-12-5 00:00:00',86),(1010,11,'2011-12-5 00:00:00',72),(1010,12,'2011-12-5 00:00:00',82),
(1010,13,'2011-12-5 00:00:00',79),(1010,14,'2011-12-5 00:00:00',69),(1010,15,'2011-12-5 00:00:00',86),(1010,16,'2011-12-5 00:00:00',83),
(1011,1,'2011-12-5 00:00:00',99),(1011,2,'2011-12-5 00:00:00',89),(1011,3,'2011-12-5 00:00:00',87),(1011,4,'2011-12-5 00:00:00',95),
(1011,5,'2011-12-5 00:00:00',84),(1011,6,'2011-12-5 00:00:00',92),(1011,7,'2011-12-5 00:00:00',94),(1011,8,'2011-12-5 00:00:00',78),
(1011,9,'2011-12-5 00:00:00',84),(1011,10,'2011-12-5 00:00:00',86),(1011,11,'2011-12-5 00:00:00',72),(1011,12,'2011-12-5 00:00:00',82),
(1011,13,'2011-12-5 00:00:00',79),(1011,14,'2011-12-5 00:00:00',69),(1011,15,'2011-12-5 00:00:00',86),(1011,16,'2011-12-5 00:00:00',83),
(1012,1,'2011-12-5 00:00:00',99),(1012,2,'2011-12-5 00:00:00',89),(1012,3,'2011-12-5 00:00:00',87),(1012,4,'2011-12-5 00:00:00',95),
(1012,5,'2011-12-5 00:00:00',84),(1012,6,'2011-12-5 00:00:00',92),(1012,7,'2011-12-5 00:00:00',94),(1012,8,'2011-12-5 00:00:00',78),
(1012,9,'2011-12-5 00:00:00',84),(1012,10,'2011-12-5 00:00:00',86),(1012,11,'2011-12-5 00:00:00',72),(1012,12,'2011-12-5 00:00:00',82),
(1012,13,'2011-12-5 00:00:00',79),(1012,14,'2011-12-5 00:00:00',69),(1012,15,'2011-12-5 00:00:00',86),(1012,16,'2011-12-5 00:00:00',83),
(1013,1,'2011-12-5 00:00:00',99),(1013,2,'2011-12-5 00:00:00',89),(1013,3,'2011-12-5 00:00:00',87),(1013,4,'2011-12-5 00:00:00',95),
(1013,5,'2011-12-5 00:00:00',84),(1013,6,'2011-12-5 00:00:00',92),(1013,7,'2011-12-5 00:00:00',94),(1013,8,'2011-12-5 00:00:00',78),
(1013,9,'2011-12-5 00:00:00',84),(1013,10,'2011-12-5 00:00:00',86),(1013,11,'2011-12-5 00:00:00',72),(1013,12,'2011-12-5 00:00:00',82),
(1013,13,'2011-12-5 00:00:00',79),(1013,14,'2011-12-5 00:00:00',69),(1013,15,'2011-12-5 00:00:00',86),(1013,16,'2011-12-5 00:00:00',83),
(1014,1,'2011-12-5 00:00:00',99),(1014,2,'2011-12-5 00:00:00',89),(1014,3,'2011-12-5 00:00:00',87),(1014,4,'2011-12-5 00:00:00',95),
(1014,5,'2011-12-5 00:00:00',84),(1014,6,'2011-12-5 00:00:00',92),(1014,7,'2011-12-5 00:00:00',94),(1014,8,'2011-12-5 00:00:00',78),
(1014,9,'2011-12-5 00:00:00',84),(1014,10,'2011-12-5 00:00:00',86),(1014,11,'2011-12-5 00:00:00',72),(1014,12,'2011-12-5 00:00:00',82),
(1014,13,'2011-12-5 00:00:00',79),(1014,14,'2011-12-5 00:00:00',69),(1014,15,'2011-12-5 00:00:00',86),(1014,16,'2011-12-5 00:00:00',83),
(1015,1,'2011-12-5 00:00:00',99),(1015,2,'2011-12-5 00:00:00',89),(1015,3,'2011-12-5 00:00:00',87),(1015,4,'2011-12-5 00:00:00',95),
(1015,5,'2011-12-5 00:00:00',84),(1015,6,'2011-12-5 00:00:00',92),(1015,7,'2011-12-5 00:00:00',94),(1015,8,'2011-12-5 00:00:00',78),
(1015,9,'2011-12-5 00:00:00',84),(1015,10,'2011-12-5 00:00:00',86),(1015,11,'2011-12-5 00:00:00',72),(1015,12,'2011-12-5 00:00:00',82),
(1015,13,'2011-12-5 00:00:00',79),(1015,14,'2011-12-5 00:00:00',69),(1015,15,'2011-12-5 00:00:00',86),(1015,16,'2011-12-5 00:00:00',83),
(1016,1,'2011-12-5 00:00:00',99),(1016,2,'2011-12-5 00:00:00',89),(1016,3,'2011-12-5 00:00:00',87),(1016,4,'2011-12-5 00:00:00',95),
(1016,5,'2011-12-5 00:00:00',84),(1016,6,'2011-12-5 00:00:00',92),(1016,7,'2011-12-5 00:00:00',94),(1016,8,'2011-12-5 00:00:00',78),
(1016,9,'2011-12-5 00:00:00',84),(1016,10,'2011-12-5 00:00:00',86),(1016,11,'2011-12-5 00:00:00',72),(1016,12,'2011-12-5 00:00:00',82),
(1016,13,'2011-12-5 00:00:00',79),(1016,14,'2011-12-5 00:00:00',69),(1016,15,'2011-12-5 00:00:00',86),(1016,16,'2011-12-5 00:00:00',83),
(1017,1,'2011-12-5 00:00:00',99),(1017,2,'2011-12-5 00:00:00',89),(1017,3,'2011-12-5 00:00:00',87),(1017,4,'2011-12-5 00:00:00',95),
(1017,5,'2011-12-5 00:00:00',84),(1017,6,'2011-12-5 00:00:00',92),(1017,7,'2011-12-5 00:00:00',94),(1017,8,'2011-12-5 00:00:00',78),
(1017,9,'2011-12-5 00:00:00',84),(1017,10,'2011-12-5 00:00:00',86),(1017,11,'2011-12-5 00:00:00',72),(1017,12,'2011-12-5 00:00:00',82),
(1017,13,'2011-12-5 00:00:00',79),(1017,14,'2011-12-5 00:00:00',69),(1017,15,'2011-12-5 00:00:00',86),(1017,16,'2011-12-5 00:00:00',83);

4.2 指定查询字段

-- 查询表中全部内容
SELECT * FROM `student`;
-- 查询表中指定的字段
SELECT `StudentName`,`Phone` FROM `student`;
-- 别名,给结果字段名起一个名字(可以是字段和表)  AS
SELECT `StudentName` AS 学生名,`Phone` AS 电话 FROM `student` AS s;

-- 函数 concat(a,b)
SELECT CONCAT('姓名:',`StudentName`) AS 新名字 FROM `student`;

-- distinct去重数据
SELECT DISTINCT `StudentNo` FROM `result`;

SELECT VERSION();-- 查询系统版本(函数)
SELECT 100*2+9 AS 计算结果;-- 可以用来计算(表达式)
SELECT @@auto_increment_increment; -- 查询自增步长(变量)

-- 学员考试成绩加一分
SELECT `StudentNo`,`StudentResult`+1 AS1分后 FROM `result`;

数据库中的表达式:文本值,列,null,函数,计算表达式,系统变量

select 表达式 from 表

4.3 where条件子句

作用:检索数据中符合条件的值

运算符

and与 or或 not非

SELECT `StudentNo`,`StudentResult` FROM `result`
WHERE `StudentResult`>80 AND `StudentResult`<90;

模糊查询

运算符语法描述
is nulla is null为空,结果为真
is not nulla is not null不为空,结果为真
betweena between b and c若a在b和c之间,为真
likea like bsql匹配,a匹配b,结果为真
ina in (b1,b2,b3…)假设a在b1,b2,b3…的某一个值中,则结果为真

%为匹配0个或多个字符,_为匹配一个字符。 __为匹配两个字符

SELECT `StudentNo`,`StudentName` FROM `student`
WHERE `StudentName` LIKE '张%';

SELECT `StudentNo`,`StudentName` FROM `student`
WHERE `StudentName` LIKE '张_';
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE `StudentNo` IN (1000,1001,1002);

4.4 联表查询

SELECT s.`StudentNo`,`StudentName`,`SubjectNo`,`StudentResult`
FROM `student` AS s
INNER JOIN `result` AS r
WHERE s.`StudentNo` = r.`StudentNo`;-- where可以用on代替
-- join on 连接查询
-- where 等值查询,两个结果是一样的
-- on是先筛选后关联,where是先关联后筛选
操作描述
inner join如果表中至少有一个匹配,就返回行
left join会从左表中返回所有值,即使右表中没有匹配
right join会从右表中返回所有值,即使左表中没有匹配
-- 查询参加考试的学生的信息:学号,学生名字,科目名字,成绩
SELECT `r`.`StudentNo`,`StudentName`,`SubjectName`,`StudentResult`
FROM `result` AS r
LEFT JOIN `subject` AS s
ON r.`SubjectNo`=s.`SubjectNo`
INNER JOIN `student` AS stu
ON r.`StudentNo` = stu.`StudentNo`;


-- 要查询哪些数据 select 后面内容
-- 从哪几个表中查询 from 后面内容
-- 多张表查询,先查两张,慢慢增加

练习:

-- 查询学员所属年级(学号,学生姓名,年级名)
SELECT `StudentNo`,`StudentName`,`gradename`
FROM `student` AS s
LEFT JOIN `grade` AS g
ON s.`gradeId` = g.`gradeid`;

-- 查询科目所属的年级(科目名称,年级名称)
SELECT `SubjectName`,`gradename`
FROM `subject` AS s
LEFT JOIN `grade` AS g
ON s.`GradeId` = g.`gradeid`;

-- 查询参加数据库结构-1考试的学生的信息:学号,学生名字,科目名字,成绩
SELECT s.`StudentNo`,`StudentName`,`SubjectName`,`StudentResult`
FROM `result` AS r
LEFT JOIN `student` AS s
ON s.`StudentNo` = r.`StudentNo`
LEFT JOIN `subject` AS sub
ON r.`SubjectNo` = sub.`SubjectNo`
WHERE `SubjectName` = "数据库结构-1";

4.5 自连接

自己表和自己连接,核心就是:一张表拆成两张一样的表连接

实验数据:

CREATE TABLE `category`(
    `categoryid` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主题id',
    `pid` INT(10) NOT NULL COMMENT '父id',
    `categoryName` VARCHAR(50) NOT NULL COMMENT '主题名字',
    PRIMARY KEY(`categoryid`)
)ENGINE= INNODB DEFAULT CHARSET= utf8;

INSERT INTO `category`(`categoryid`,`pid`,`categoryName`)
VALUES(2,1,'信息技术'),
(3,1,'软件开发'),
(4,3,'数据库'),
(5,1,'美术设计'),
(6,3,'web开发'),
(7,5,'ps技术'),
(8,1,'办公信息');

查询语句:

SELECT c1.`categoryName` AS 父栏,c2.`categoryName` AS 子栏
FROM `category` AS c1,`category` AS c2
WHERE c1.`categoryid`=c2.`pid`;

4.6 分页的排序

排序

-- 排序:升序ASC,降序DESC
-- order by,通过哪个字段排序,怎么排
-- 查询参加数据库结构-1考试的学生的信息:学号,学生名字,科目名字,成绩
SELECT s.`StudentNo`,`StudentName`,`SubjectName`,`StudentResult`
FROM `result` AS r
LEFT JOIN `student` AS s
ON s.`StudentNo` = r.`StudentNo`
LEFT JOIN `subject` AS sub
ON r.`SubjectNo` = sub.`SubjectNo`
WHERE `SubjectName` = "数据库结构-1"
ORDER BY `StudentResult` ASC;

分页

-- 分页
-- 语法:limit 起始索引,页面大小
-- 查询参加数据库结构-1考试的学生的信息:学号,学生名字,科目名字,成绩
SELECT s.`StudentNo`,`StudentName`,`SubjectName`,`StudentResult`
FROM `result` AS r
LEFT JOIN `student` AS s
ON s.`StudentNo` = r.`StudentNo`
LEFT JOIN `subject` AS sub
ON r.`SubjectNo` = sub.`SubjectNo`
WHERE `SubjectName` = "数据库结构-1"
ORDER BY `StudentResult` ASC
LIMIT 8,5;

网页的用法。当前页,总页数,页面大小

每一页的limit怎么写,limit (当前页数-1)*页面大小,页面大小

练习:

-- 查询数据库结构-1课程成绩排名前十的学生,并且分数要大于80分的学生信息
-- (学号,姓名,课程名,分数)
SELECT s.`StudentNo`,`StudentName`,`SubjectName`,`StudentResult`
FROM `student` AS s
INNER JOIN `result` AS r
ON s.`StudentNo`=r.`StudentNo`
INNER JOIN `subject` AS sub
ON r.`SubjectNo` = sub.`SubjectNo`
WHERE `SubjectName` = "数据库结构-1" AND`StudentResult`>=80
ORDER BY `StudentResult` DESC
LIMIT 0,10;

4.7 子查询

本质:在where语句中嵌套一个子查询语句

-- 子查询

-- 查询数据库结构-1的所有考试(学号,科目编号,成绩),降序排列
SELECT `StudentNo`,`SubjectNo`,`StudentResult`
FROM `result`
WHERE `SubjectNo` =(SELECT `SubjectNo` FROM `subject` WHERE `SubjectName`= '数据库结构-1')
ORDER BY `StudentResult` DESC;

-- 分数不小于80分的学生的学号和姓名
SELECT DISTINCT s.`StudentNo`,`StudentName`
FROM `result` AS r
INNER JOIN `student` AS s
ON r.`StudentNo` = s.`StudentNo`
WHERE `StudentResult`>= 80;
-- 在以上基础上增加一个高等数学-2
SELECT s.`StudentNo`,`StudentName`
FROM `result` AS r
INNER JOIN `student` AS s
ON r.`StudentNo` = s.`StudentNo`
WHERE `StudentResult`>= 80 AND `SubjectNo`=(
	SELECT `SubjectNo` FROM `subject` WHERE `SubjectName` = '高等数学-2'
);

-- 不用联表,只用嵌套子查询
SELECT `StudentNo`,`StudentName`
FROM `student`
WHERE `StudentNo` IN (
	SELECT `StudentNo` FROM `result` WHERE `StudentResult`>=80 AND
	`SubjectNo` = (SELECT `SubjectNo` FROM `subject` WHERE `SubjectName` = '高等数学-2')
);

4.8 分组及过滤

-- 查询不同课程的平均分,最高分,最低分 平均分大于80
-- 核心:根据不同的课程分组
SELECT `SubjectName`,AVG(`StudentResult`) AS 平均分,MAX(`StudentResult`),MIN(`StudentResult`)
FROM `result` r
INNER JOIN `subject` s
ON r.`SubjectNo` = s.`SubjectNo`
GROUP BY s.`SubjectName`
HAVING 平均分>80; -- 分组后在加条件

5、MySQL函数

5.1 常见函数

-- 数学运算
SELECT ABS(-8); -- 绝对值
SELECT CEILING(9.4); -- 向上取整
SELECT FLOOR(9.4); -- 向下取整
SELECT RAND(); -- 0-1的随机数
SELECT SIGN(-10); -- 返回一个数的符号
-- 字符串函数
SELECT CHAR_LENGTH('love'); -- 返回字符串的长度
SELECT CONCAT('我','拼接'); -- 拼接字符串
SELECT INSERT("我是一个粉刷匠",1,4,'保护'); -- 从第一个位置替换四个字符为'保护'、
SELECT LOWER('DHJ'); -- 转小写
SELECT UPPER('dsf'); -- 转大写
SELECT INSTR('你是谁','是'); -- 返回第一次指定字符的索引
SELECT REPLACE('起来,不愿做努力的人们','人们','村民'); -- 替换字符串
SELECT SUBSTR('起来,不愿做努力的人们',4,2); -- 返回指定的子字符串
SELECT REVERSE('起来,不愿做努力的人们'); -- 反转字符串

-- 查询姓赵的同学,并替换其姓为申,注意,原数据是不会变的
SELECT REPLACE(`StudentName`,'赵','申') FROM `student`
WHERE `StudentName` LIKE '赵%';

-- 时间和日期函数(记住)
SELECT CURRENT_DATE(); -- 获取当前日期
SELECT CURDATE(); -- 获取当前日期
SELECT NOW(); -- 获取当前时间
SELECT LOCALTIME(); -- 本地时间
SELECT SYSDATE(); -- 系统时间

SELECT YEAR(NOW()); -- 获取当前的年,月日时分秒以此类推

-- 系统
SELECT SYSTEM_USER(); -- 登录用户
SELECT USER(); -- 登录用户
SELECT VERSION(); -- 软件版本

5.2 聚合函数(常用)

-- 统计表中的数据
SELECT COUNT(`StudentName`) FROM `student`; -- 会忽略所有的null值
SELECT COUNT(*) FROM `student`; -- 不会忽略null,本质计算行数和列
SELECT COUNT(1) FROM `student`; -- 不会忽略null,本质计算行数

SELECT SUM(`StudentResult`) AS 总和 FROM `result`;
SELECT AVG(`StudentResult`) AS 平均分 FROM `result`;
SELECT MAX(`StudentResult`) AS 最高分 FROM `result`;
SELECT MIN(`StudentResult`) AS 最低分 FROM `result`;


-- 查询不同课程的平均分,最高分,最低分 平均分大于80
-- 核心:根据不同的课程分组
SELECT `SubjectName`,AVG(`StudentResult`) AS 平均分,MAX(`StudentResult`),MIN(`StudentResult`)
FROM `result` r
INNER JOIN `subject` s
ON r.`SubjectNo` = s.`SubjectNo`
GROUP BY s.`SubjectName`
HAVING 平均分>80; -- 分组后在加条件

5.3 数据库级别的MD5加密(扩展)

插入后加密:update 表名 set 字段名=md5(字段名) where id = 1;

插入时加密 insert into 表名 values(md5(数据));

6、事务

6.1 什么是事务

几个sql成组执行,要么都成功,要么都失败,保证数据的安全性

事务的原则,ACID 原则 原子性,一致性,隔离性,持久性

**原子性:**两个步骤一起成功,或一起失败,不能只发生其中一个动作

**一致性:**针对事务操作前与操作后的状态一致,例如,两个人转帐,转帐前后两人的资金总和应该是不变的

**持久性:**表示事务结束后的数据,不随着外界原因导致数据丢失。例,事务没有提交恢复到原态,一旦提交持久化

**隔离性:**针对多个用户同时操作,主要是排除其他事务对本次事务的影响。

隔离导致的一些问题

**脏读:**一个事务读取到另一个事务未提交的数据

**不可重复读:**在一个事务内读取表中的某一行数据,多次读取结果不同(这个不一定是错误,只是某些场合不对)

**虚读(幻读):**指在一个事务中读取到了别人事务插入的数据,导致前后数据不一致

6.1 执行事务

mysql是默认开启事务,并且是自动执行的

-- mysql是默认开启事务的,并且是自动执行的
SET autocommit = 0; -- 关闭自动提交
SET autocommit = 1; -- 开启自动提交(默认)

-- 手动处理事务步骤

-- 1、关闭自动提交
SET autocommit = 0; 

-- 2、事务开启
 START TRANSACTION -- 标记一个事务的开始
 
-- 3、提交:持久化(成功)
COMMIT
-- 4、回滚:回到原来的样子(失败)
ROLLBACK
-- 5、事务结束
SET autocommit = 1; -- 开启自动提交

-- 保存点(了解)
SAVEPOINT 保存点名 -- 设置一个事务的保存点
ROLLBACK  TO SAVEPOINT 保存点名 --  回滚到保存点
RELEASE SAVEPOINT 保存点名 -- 撤销保存点

转账例子:

-- 创建数据库
CREATE DATABASE shop CHARACTER SET utf8 COLLATE utf8_general_ci;
-- 切换到此表
USE shop;
-- 创建表
CREATE TABLE acount (
	`id` INT(5) NOT NULL AUTO_INCREMENT COMMENT 'id',
	`name` VARCHAR(20) NOT NULL COMMENT '账户名',
	`money` DECIMAL(9,2) NOT NULL COMMENT '金钱',
	PRIMARY KEY (`id`)
)ENGINE = INNODB DEFAULT CHARSET= utf8;
-- 插入数据
INSERT INTO `acount`(`name`,`money`)
VALUES ('A',2000),('B',10000);

-- 模拟转账
SET autocommit = 0; -- 关闭自动提交
START TRANSACTION; -- 开启一个事务
UPDATE `acount` SET `money` = `money` - 500 WHERE `name` = 'A' ;-- A减500
UPDATE `acount` SET `money` = `money` + 500 WHERE `name` = 'B'; -- B加500
COMMIT; -- 提交事务
ROLLBACK; -- 失败回滚
SET autocommit = 1; -- 开启自动提交

7 、索引

7.1 索引的分类

  • 主键索引(primary key)
    • 唯一标识,不能重复,只能一个列作为主键
  • 唯一索引(unique key)
    • 避免重复的列出现,可以重复,多个列可以表示为唯一索引
  • 常规索引(key/index)
    • 默认的,index或key关键字来设置
  • 全文索引(fulltext)
    • 在特定的数据库引擎才有

7.2 索引的使用

在创建表的时候给字段添加索引

CREATE TABLE acount (
	`id` INT(5) NOT NULL AUTO_INCREMENT COMMENT 'id',
	`name` VARCHAR(20) NOT NULL COMMENT '账户名',
	`money` DECIMAL(9,2) NOT NULL COMMENT '金钱',
	PRIMARY KEY (`id`),-- 主键索引
    unique key 'name' ('name'), -- 唯一索引
    key 'money' ('money') -- 默认索引
)ENGINE = INNODB DEFAULT CHARSET= utf8;

创建完毕后增加索引

-- 显示所有的索引
SHOW INDEX  FROM `acount`;

-- 格式ALTER TABLE 表名 ADD FULLTEXT INDEX 索引名(列名);
ALTER TABLE `acount` ADD FULLTEXT INDEX `name`(`name`);

explain 分析sql执行的状况

-- explain 分析sql执行的状况
EXPLAIN SELECT * FROM `acount`;
EXPLAIN SELECT * FROM `acount` WHERE MATCH(`name`) AGAINST('张');

7.3 测试索引

插入100万数据,时犯了大忌,循环竟然没有结束条件SET i=i+1;,导致好几个G的数据,最终导致死机

索引在小数据不太明显

-- 创建表
CREATE TABLE `user_data` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) DEFAULT'' COMMENT'用户昵称',
`sex` TINYINT(4) UNSIGNED DEFAULT '0'COMMENT '性别(0:男;1:女)',
`age` TINYINT(4) DEFAULT'0'  COMMENT '年龄',
`password` VARCHAR(100) NOT NULL COMMENT '密码',
`phone` VARCHAR(20) DEFAULT'' COMMENT'手机号',
`email` VARCHAR(50) NOT NULL COMMENT'用户邮箱',
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

-- 声明函数
DELIMITER $$

CREATE  FUNCTION fun_data()
RETURNS INT
BEGIN
	DECLARE num INT DEFAULT 1000000;
	DECLARE i INT DEFAULT 0;
	WHILE i<num DO
		-- 函数体开始
		INSERT	INTO `user_data`(`name`,`sex`,`age`,`password`,`Phone`,`Email`)
		VALUES(CONCAT('用户',i),
			FLOOR(RAND()*2),
			FLOOR(RAND()*100),
			FLOOR(RAND()*899999+100000),
			CONCAT('18', FLOOR(RAND()*899999999+100000000)),
			CONCAT(FLOOR(RAND()*899999999+100000000),'@qq.com'));
		SET i=i+1;-- 一定不能忘记,不然死循环
		-- 函数体结束
	END WHILE;
	RETURN i;
END;

-- 执行函数
SELECT fun_data();
-- 查询数据量
SELECT COUNT(*) FROM `user_data`;

-- ------------测试加索引的耗时------------------
SELECT	* FROM `user_data` WHERE `name`='用户999999'; -- 耗时1.021 sec

-- 创建一个索引
-- 索引命名:id_表名_字段名
-- 格式:CREATE INDEX 索引名 ON 表名(字段名);
CREATE INDEX id_user_data_name ON user_data(`name`); -- 耗时12.549 sec

SELECT	* FROM `user_data` WHERE `name`='用户999999'; -- 0 sec

7.4 索引原则

- 索引不是越多越好
- 不要对经常变动的数据加索引
- 小数据量的表不需要加
- 索引一般加在经常查询的字段上 

8、权限管理和备份

8.1 用户管理

sqlyog可视化操作

SQL命令

-- 创建一个用户CREATE USER 用户名 IDENTIFIED 密码;
CREATE USER zj IDENTIFIED '123456';

-- 修改密码(当前用户)
SET PASSWORD =PASSWORD('111111');

-- 修改密码(指定用户)
SET PASSWORD FOR zj =PASSWORD('111111');

-- 修改用户名
RENAME USER zj TO zj2;

-- 用户授权*.*是全部的库和表,格式为  (库.表)
-- 授予全部权限
GRANT ALL PRIVILEGES ON *.* TO zj;

-- 查询权限
SHOW GRANTS FOR zj;
-- 查询root账户格式
SHOW GRANTS FOR root@localhost;

-- 撤销权限
REVOKE ALL PRIVILEGES ON *.* FROM zj;

-- 删除用户
DROP USER zj;

8.2 MySql备份

1、用可视化工具导出简单

2、使用命令行cmd

-- 导出单张表格式  mysqldump -h主机 -u用户名 -p密码 库名 表名 >物理磁盘位置
mysqldump -hlocalhost -uroot -p123456 school student >d:/a.sql


-- 导出多张表格式  mysqldump -h主机 -u用户名 -p密码 库名  表名1 表名2 >物理磁盘位置
mysqldump -hlocalhost -uroot -p123456 school student result >d:/b.sql-- 导出整个库格式  mysqldump -h主机 -u用户名 -p密码 库名 >物理磁盘位置
mysqldump -hlocalhost -uroot -p123456 school >d:/b.sql
导入方式
1、先登录
2、再使用source d:/b.sql

9、规范数据库设计

9.1 软件开发中关于数据库的设计

  • 分析需求:分析业务和需要处理的的数据库的需求
  • 概要设计:设计关系图E-R图

9.2 设计数据库的步骤(个人博客)

  • 收集信息,分析需求
    • 用户表(用户登录注销,用户的个人信息,写博客,创建分类)
    • 分类表(文章分类,谁写的)
    • 文章表(文章的信息)
    • 友链表(友链的信息)
  • 标识实体(把需求落实到每个字段上)
表名  (字段)
user (id,username,password,sex,age,sign)
category (id,category_name,create_user_id)
blog (id,title,anthor_id,category_id,content,create_time,update_time,love)
comment (id,blog_id,user_id,content,create_time,user_id_parent)
links (id,links,href,sort)
  • 标识实体直接的关系
    • 写博客:user---->blog
    • 创建分类:user---->category
    • 关注:user----user
    • 友链:links
    • 评论:user-user-blog

9.3三大范式

第一范式,要求数据库的每一列都是不可分割的原子数据项

​ 意思就是这一列不可再分

第二范式,确保表中每一列都和主键相关,而不能只与主键的某一部分相关

​ 前提:要满足第一范式

​ 每张表只描述一件事情

第三范式,确保数据表中的每一列数据都和主键相关,而不能间接相关

​ 前提:满足第一范式和第二范式

规范性和性能问题

但是在阿里规范中,关联查询的表不能超过三张

  • 考虑商业化需求和目标,数据库的性能更加重要
  • 在规范性能的问题时,要适当考虑一下规范性
  • 故意给某些表增加一些冗余字段,使得多表查询变成单表查询

10、JDBC(重点)

10.1 数据库驱动

我们的程序会通过数据库驱动和数据库 打交道

需要导入,mysql-connector-java-5.1.47.jar

Java.sql

javax.sql

10.2 第一个JDBC程序

整体步骤:

  1. 创建一个普通数据库项目
  2. 导入数据库驱动,就是导入jar包mysql-connector-java-5.1.47.jar(把jar包放在项目目录lib文件夹中,右键Add as Library)
  3. 编写测试代码

测试用的数据sql:

CREATE DATABASE jdbcStudy CHARACTER SET utf8 COLLATE utf8_general_ci;

USE jdbcStudy;

CREATE TABLE `users`(
	id INT PRIMARY KEY,
	NAME VARCHAR(40),
	PASSWORD VARCHAR(40),
	email VARCHAR(60),
	birthday DATE
);

INSERT INTO `users`(id,NAME,PASSWORD,email,birthday)
VALUES(1,'zhansan','123456','zs@sina.com','1980-12-04'),
(2,'lisi','123456','lisi@sina.com','1981-12-04'),
(3,'wangwu','123456','wangwu@sina.com','1979-12-04')

java代码

链接步骤:

1、加载驱动

2、连接数据库DriverManager

3、获得执行sql的对象Statement

4、 获得返回的结果集

5、释放连接

package com.daban.test;

import java.sql.*;

public class JdbcFirstDemo {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1、加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2、用户信息和url
        String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true";
        String username = "root";
        String password = "123456";
        //3、连接成功,数据库对象
        Connection connection = DriverManager.getConnection(url,username,password);
        //4、执行sql的对象
        Statement statement = connection.createStatement();
        //5、sql对象去执行sql语句,可能存在返回结果
        String sql ="select * from users";
        ResultSet rs = statement.executeQuery(sql);
        while(rs.next()){
            System.out.println("id="+rs.getObject("id"));
            System.out.println("name="+rs.getObject("name"));
            System.out.println("pwd="+rs.getObject("PASSWORD"));
            System.out.println("email="+rs.getObject("email"));
            System.out.println("birth="+rs.getObject("birthday"));
            System.out.println("------------------------------------");
        }
        //6、释放连接
        rs.close();
        statement.close();
        connection.close();
    }
}

10.3 JDBC对象解释

DriverManager

//DriverManager.registerDriver(new Driver());
Class.forName("com.mysql.jdbc.Driver");//固定解法加载驱动

URL

String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true";

//mysql --3306
jdbc:mysql://主机地址:端口/数据库名?参数1&参数2&参数3

//oralca --1521
jdbc:oracle:thin:@主机地址:端口:sid

Connection

//数据库对象,可以用来操作数据库
Connection connection = DriverManager.getConnection(url,username,password);

Statement

//执行sql的对象
Statement statement = connection.createStatement();

statement.executeQuery();//可以执行查询语句
statement.execute();//可以执行所有语句
statement.executeUpdate();//可以执行更新,插入,删除,返回一个影响的行数

ResultSet

//结果集对象,封装了所有的查询结果
ResultSet rs = statement.executeQuery(sql);

10.4 写一个连接数据库的工具类

第一步、src目录下创建db.properties

driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true
username = root
password = 123456

第二步、创建一个工具类TestJdbcUtils

package com.daban.test.utils;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JdbcUtils {
    private  static String driver = null;
    private  static String url = null;
    private  static String username = null;
    private  static String password = null;
    static {
        InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
        Properties properties = new Properties();
        try {
            properties.load(in);
            driver = properties.getProperty("driver");
            url = properties.getProperty("url");
            username = properties.getProperty("username");
            password = properties.getProperty("password");
            Class.forName(driver);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    //获取连接
    public static Connection getConnection() throws SQLException {
       return DriverManager.getConnection(url,username,password);
    }
    //释放连接
    public static void release(Connection conn, Statement st, ResultSet rs){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(st!=null){
            try {
                st.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}

第三步、写sql测试

package com.daban.test;

import com.daban.test.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestJdbcUtils {
    public static void main(String[] args) {
        Connection connection = null;
        Statement st = null;
        ResultSet rs = null;
        try {
            connection = JdbcUtils.getConnection();
            st = connection.createStatement();
            String sql = "INSERT INTO `users`(id,NAME,PASSWORD,email,birthday)" +
                    "VALUES(5,'zhansan','123456','zs@sina.com','1980-12-04')";
            int i = st.executeUpdate(sql);
            if(i>0){
                System.out.println("插入成功");
            }else {
                System.out.println("插入失败");
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            JdbcUtils.release(connection,st,rs);
        }
    }
}

10.5 SQL注入

package com.daban.test;

import com.daban.test.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestJdbcUtils {
    public static void main(String[] args) {
        //正常登录
       // login("lisi","123456");
        
        //sql注入
        login("' or '1=1","' or '1=1");
        //SELECT `NAME`,`PASSWORD` FROM `users` WHERE `NAME`='' or '1=1' AND`PASSWORD` = '' or '1=1'
        //sql语句where后面的条件为恒等式,也就是满足任何条件的用户都查询,也就是无条件查询
    }

    public static void login(String username,String password){
        Connection connection = null;
        Statement st = null;
        ResultSet rs = null;
        try {
            connection = JdbcUtils.getConnection();
            st = connection.createStatement();
            //SELECT `NAME`,`PASSWORD` FROM `users` WHERE `NAME`='wangwu' AND`PASSWORD` = '123456';
            String sql = "SELECT `NAME`,`PASSWORD` FROM `users` WHERE `NAME`='"+username+ "' AND`PASSWORD` = '"+password+"'";
            System.out.println(sql);
            rs = st.executeQuery(sql);
            while (rs.next()){
                System.out.println(rs.getObject("name"));
                System.out.println(rs.getObject("password"));
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            JdbcUtils.release(connection, st, rs);
        }
    }
}

10.6 PreparedStatement

PreparedStatement可以防止sql注入,效率更好

传递进来的参数当作字符,其中的转义字符会被忽略掉

package com.daban.test;

import com.daban.test.utils.JdbcUtils;

import java.sql.*;

public class TestJdbcUtils {
    public static void main(String[] args) {
        //正常登录
       // login("wangwu","123456");

        //sql注入
        login("' or '1=1","' or '1=1");
        //SELECT `NAME`,`PASSWORD` FROM `users` WHERE `NAME`='' or '1=1' AND`PASSWORD` = '' or '1=1'
        //sql语句where后面的条件为恒等式,也就是满足任何条件的用户都查询,也就是无条件查询
    }

    public static void login(String username,String password){
        Connection connection = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        try {
            connection = JdbcUtils.getConnection();
            //写sql时值用?代替
            String sql = "SELECT `NAME`,`PASSWORD` FROM `users` WHERE `NAME`=? AND `PASSWORD` =?";
            //预编译sql语句
            st = connection.prepareStatement(sql);
            //给预编译的传递值
            st.setString(1,username);
            st.setString(2,password);
            //System.out.println(sql);
            //执行传值后的
            rs = st.executeQuery();
            while (rs.next()){
                System.out.println(rs.getObject("name"));
                System.out.println(rs.getObject("password"));
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            JdbcUtils.release(connection, st, rs);
        }
    }
}

10.7 JDBC事务

步骤:

  • 开启事务connection.setAutoCommit(false);
  • 一组事务执行完毕,提交事务connection.commit();
  • 可以在catch中显示的指定回滚,不指定失败时默认回滚
package com.daban.test;

import com.daban.test.utils.JdbcUtils;

import java.sql.*;

public class TestJdbcUtils {
    public static void main(String[] args) {
        Connection connection = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        try {
            connection = JdbcUtils.getConnection();
            //关闭数据库自动提交会默认开始事务
            connection.setAutoCommit(false);

            String sql = "UPDATE users SET PASSWORD =? WHERE `NAME` =? ";
            st = connection.prepareStatement(sql);
            st.setString(1,"66666");
            st.setString(2,"wangwu");
            st.executeUpdate();
            int x = 1/0;
            st.setString(1,"88888");
            st.setString(2,"wangwu");
            st.executeUpdate();
            //手动提交
            connection.commit();
            System.out.println("修改成功");

        } catch (SQLException throwables) {
            //失败时,默认回滚,可以不写
            throwables.printStackTrace();
            try {
                connection.rollback();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            System.out.println("修改失败");
        }finally {
            JdbcUtils.release(connection, st, rs);
        }
    }
}

10.8 数据库连接池

编写连接池只需要实现一个接口DataSource

使用了这些数据库连接池后,我们在项目开发中,就不需要编写连接数据库的代码了

DBCP

DBCP需要导入两个jar包

  • commons-dbcp-1.4.jar
  • commons-pool-1.6.jar

写一个配置文件,dbcpconfig.properties

#连接设置
driverClassName=com.mysql.JDBC.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true
username=root
password=123456

#<!-- 初始化连接 -->
initialSize=10

#最大连接数量
maxActive=50

#<!-- 最大空闲连接 -->
maxIdle=20

#<!-- 最小空闲连接 -->
minIdle=5

#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60-->
maxWait=60000

#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:【属性名=property;】
#注意:"user""password" 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=utf8

#指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true

#driver default 指定由连接池所创建的连接的只读(read-only)状态。
#如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
defaultReadOnly=

#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_COMMITTED

编写工具类

package com.daban.test.utils;

import org.apache.commons.dbcp.BasicDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JdbcUtils_DBCP {
     public static DataSource dataSource = null;
    static {

        try {
            InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
            Properties properties = new Properties();
            properties.load(in);

            //创建数据源
            dataSource = BasicDataSourceFactory.createDataSource(properties);
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
    //获取连接
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
    //释放连接
    public static void release(Connection conn, Statement st, ResultSet rs){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(st!=null){
            try {
                st.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}

测试方式代码基本一样,只是把工具类名字改一下

C3P0

C3P0要导入两个jar包

  • c3p0-0.9.5.5.jar
  • mchange-commons-java-0.2.19.jar

编写配置文件 c3p0_config.xml

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <!--
c3p0的缺省(默认)配置
如果在代码中"ComboPooledDataSource ds=new ComboPooledDataSource();"这样写就表示使用的是c3p0的缺省(默认)-->
    <default-config>
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?userUnicode=true&characterEncoding=utf8&uesSSL=true&serverTimezone=UTC</property>
        <property name="user">root</property>
        <property name="password">123456</property>

        <property name="acquiredIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </default-config>

    c3p0的命名配置
    如果在代码中"ComboPooledDataSource ds=new ComboPooledDataSource("MySQL");"这样写就表示使用的是mysql的缺省(默认)
    -->
    <named-config name="MySQL">
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true</property>
        <property name="user">root</property>
        <property name="password">123456</property>
        <property name="acquiredIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </named-config>
</c3p0-config>

编写工具类

package com.daban.test.utils;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class JdbcUtils_c3p0 {
     public static DataSource dataSource = null;
    static {
        try {
            //创建数据源
            dataSource = new ComboPooledDataSource("MySQL");
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
    //获取连接
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
    //释放连接
    public static void release(Connection conn, Statement st, ResultSet rs){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(st!=null){
            try {
                st.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值