文章目录
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 早期使用
*/
| MyISAM | InnoDB | |
|---|---|---|
| 事务支持 | 不支持 | 支持 |
| 数据行锁定 | 不支持 | 支持 |
| 外键约束 | 不支持 | 支持 |
| 全文索引 | 支持 | 不支持 |
| 表空间大小 | 较小 | 较大,约为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 AS 加1分后 FROM `result`;
数据库中的表达式:文本值,列,null,函数,计算表达式,系统变量
select 表达式 from 表
4.3 where条件子句
作用:检索数据中符合条件的值
运算符
and与 or或 not非
SELECT `StudentNo`,`StudentResult` FROM `result`
WHERE `StudentResult`>80 AND `StudentResult`<90;
模糊查询
| 运算符 | 语法 | 描述 |
|---|---|---|
| is null | a is null | 为空,结果为真 |
| is not null | a is not null | 不为空,结果为真 |
| between | a between b and c | 若a在b和c之间,为真 |
| like | a like b | sql匹配,a匹配b,结果为真 |
| in | a 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程序
整体步骤:
- 创建一个普通数据库项目
- 导入数据库驱动,就是导入jar包mysql-connector-java-5.1.47.jar(把jar包放在项目目录lib文件夹中,右键Add as Library)
- 编写测试代码
测试用的数据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();
}
}
}
}


4805

被折叠的 条评论
为什么被折叠?



