MySQL

  • 1、初识MySQL
    • 1.1 为什么学习数据库
    • 1.2 什么是数据库
    • 1.3 数据库分类
    • 1.4 MySQL
    • 1.5 安装MySql
    • 1.6 SQLyog
    • 1.7 连接数据库
  • 2. 操作数据库
    • 2.1 操作数据库
    • 2.2 数据库的列类型
    • 2.3 数据库的字段属性(重点)
    • 2.4 创建数据库表
    • 2.5 MyISAM 和 InnoDB的区别
    • 2.6 修改和删除表
  • 3. MySQL数据管理
    • 3.1 外键(了解即可)
    • 3.2 DML语言
    • 3.3 添加
    • 3.4 修改
    • 3.5 删除
  • 4. DQL查询数据(最重点)
    • 4.2 指定查询字段
    • 4.3 Where条件子句
    • 4.4 联表查询
    • 4.5 自连接
    • 4.6 分页和排序
    • 4.7 子查询
  • 5. MySQL函数
    • 5.1 常用函数
    • 5.2 聚合函数(常用)
    • 5.3 数据库级别的MD5加密(扩展)
  • 6. 事务
    • 6.1 什么是事务
  • 7. 索引
    • 7.1 索引的分类
    • 7.2 SQL编程创建100万条数据测试索引
    • 7.3 索引原则
  • 8. 权限管理
    • 8.1 用户管理
    • 8.2 MySql备份
  • 9. 规范数据库设计
    • 9.1 为什么需要设计
    • 9.2 数据库的三大范式
  • 10. JDBC(重点)
    • 10.1 数据库驱动
    • 10.2 JDBC
    • 10.3 第一个JDBC程序
    • 10.4 statement对象
    • 10.5 PrepareStatement对象
    • 10.6 使用IDEA连接数据库
    • 10.7 JDBC操作事务
    • 10.9 数据库连接池

sql语句笔记

1、初识MySQL

JavaEE:企业级Java开发 Web
前端(页面:展示,数据!)
后台(连接点:连接数据库JDBC,链接前端(控制,控制视图跳转,和给前端传递数据))
数据库(存数据, Text, Excel, word)

1.1 为什么学习数据库

数据库是所有软件体系中最核心的存在。

1.2 什么是数据库

数据库(DB,DataBase)
概念: 数据仓库,软件,安装在操作系统(window,linux,mac…)之上!SQL,可以存储大量的数据。500万
作用:存储数据,管理数据

1.3 数据库分类

关系型数据库:

  • MySQL, Oracle, Sql Server, DB2, SQLite
  • 通过表和表之间,行和列之间的关系进行数据的存储, 学院信息表,考勤表

非关系型数据库:

  • Redis,MongDB
  • 非关系型数据库,对象存储,通过对象的自身的属性来决定。

DBMS(数据库管理系统)

  • 数据库的管理软件,科学有效的管理我们的数据。维护和获取数据;
  • MySQL,数据库管理系统

1.4 MySQL

是个关系型数据库管理系统。
MySQL是最好的RDBMS(Relational Database Management System,关系数据库管理系统)应用软件之一。
开源的数据库软件。
体积小,速度快,总体拥有成本低,招人成本低,所有人都必须会。

5.7版本稳定,8.0

安装建议:
1、尽量不要使用exe,注册表
2、尽可能使用压缩包安装~

1.5 安装MySql

D:\software\mysql-5.7.19\bin>mysqld -install
Service successfully installed.
D:\software\mysql-5.7.19\bin>mysqld --initialize-insecure --user=mysqlD:\software\mysql-5.7.19\bin>net start mysql
MySQL 服务正在启动 .
MySQL 服务已经启动成功。D:\software\mysql-5.7.19\bin>mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.19 MySQL Community Server (GPL)Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> update mysql.user set authentication string=password('123456') where user='root' and Host = 'localhost';
ERROR 1064 (42000):
mysql> update mysql.user set authentication_string=password('123456') where user='root' and Host = 'localhost';
Query OK, 1 row affected, 1 warning (0.00 sec)mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
D:\software\mysql-5.7.19\bin>net stop mysql
MySQL 服务正在停止.
MySQL 服务已成功停止。D:\software\mysql-5.7.19\bin>net start mysql
MySQL 服务正在启动 .
MySQL 服务已经启动成功。D:\software\mysql-5.7.19\bin>mysql -u root -p
Enter password: ******
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.19 MySQL Community Server (GPL)Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql>

1.6 SQLyog

SQLyog的下载、安装、破解、配置(MySQL可视化工具安装)

1.7 连接数据库

命令行连接

mysql -u root -p --连接数据库update mysql.user set authentication_string=password('123456') where user='root' and Host = 'localhost'; -- 修改用户密码flush privileges;  ---刷新权限---------------------------------------------show datebase -- 查看所有的数据库
use school --切换数据库 use 数据库名
show tables;  --  查看数据库中所有的表
describe student;  -- 显示数据库中所有的表的信息
create database westos; -- 创建一个数据库
exit; -- 退出连接-- 单行注释/*
多行注释
*/

2. 操作数据库

操作数据库 > 操作数据库中的表 > 操作数据库中的表的数据

2.1 操作数据库

1、创建数据库

CREATE DATABASE [IF NOT EXISTS] westos;

2、删除数据库

DROP DATABASE [IF EXISTS] westos

3、使用数据库

--tab键的上面,如果你的表名或者字段名是一个特殊字符,就需要带USE `school`

4、查看数据库

SHOW DATABASES --查看所有的数据库

2.2 数据库的列类型

数值

  • tinyint 十分小的数据,一个字节
  • smallint 较小的数据 , 两个字节
  • mediumint 中等大小的数据 3个字节
  • int 标准的整数, 四个字节
  • big 较大的数据 , 8个字节
  • float 浮点数 4个字节
  • double 浮点数 8个字节(精度问题)
  • decimal 字符串形式的浮点数 金融计算的时候,一般是使用decimal

字符串

  • char 字符串,固定大小 0~255
  • varchar 可变字符串 0~65535 常用的变量 String
  • tinytext 微型文本 2^8-1
  • text 文本串 2^16-1 保存大文本

时间日期
java.util.Date

  • date YYYY-MM-DD,日期
  • time HH:mm:ss 时间格式
  • datetime YYYY-MM-DD HH:mm:ss 最常用的时间格式
  • timestamp 时间戳,1970.1.1 到现在的毫秒数
  • year 年份表示

null

  • 没有值,未知
  • 注意,不要使用null进行运算,结果为null

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

Unsigned:

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

zerofill:

  • 0填充的
  • 不足的位数,使用0类填充, int(3) , 5 —005

自增:

  • 通常理解为自增,自动在上一条记录的基础上+1(默认)
  • 通常用来设计唯一的主键~index,必须是整数类型
  • 可以自定义设计主键自增的起始站和步长

非空 NUll not null

  • 假设设置为not null,如果不给他赋值,就会报错
  • null,如果不填写值,默认就是null

默认:

  • 设置默认的值
  • sex,默认值为男,

扩展:
每一个表都必须存在以下五个字段,未来做项目用的,表示一个记录存在的意义

id 主键
version 乐观锁
is delete 伪删除
gmt create 创建时间
gmt update 修改时间

2.4 创建数据库表

--  目标:创建一个schoo1数据库
--   创建学生表(列,字段)使用SQL创建
--   学号 int 登录密码varchar(20)姓名,性别varchar(2),出生日期(datatime),家庭住址,email-- 注意点,使用英文(),表的名称和字段尽量使用 '' 括起来
--  AUTO INCREMENT 自增
-- 字符串使用单引号括起来!
-- 所有的语句后面加,(英文的),最后一个不用加
-- PRIMARYKEY主键,一般一个表只有一个唯一的主键!CREATE TABLE IF NOT EXISTS `student1`(`id` INT(4) NOT NULL AUTO_INCREMENT COMMENT '学号',`name` VARCHAR (30) NOT NULL DEFAULT '匿名' COMMENT '姓名',`pwd` VARCHAR(20) NOT NULL DEFAULT '123456' COMMENT '登录密码',`sex` VARCHAR(2) NOT NULL DEFAULT '' COMMENT '性别' ,`birthday` DATETIME DEFAULT NULL COMMENT '出生日期',`address` VARCHAR(100) DEFAULT NULL COMMENT  '家庭住址',`email` VARCHAR(50) DEFAULT NULL COMMENT '邮箱',PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;

格式

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

2.5 MyISAM 和 InnoDB的区别

 SHOW CREATE DATABASE school  -- 查看创建数据库的语句
SHOW CREATE TABLE student  -- 查看student数据表的定义语句
DESC student -- 显示表的结构

INNODB 默认使用
MYISAM 早些年使用

常规使用操作:

  • MYISAM 节约空间, 速度较快
  • INNODB 安全性高,事务的处理,多表多用户操作

在物理空间存储的位置:
所有的数据库文件都存在data目录下;一个文件夹对应一个数据库
本质还是文件的存储!

MySQL引擎在物理文件上的区别

设置数据库表的字符集编码
CHARSET=utf8;
不设置的话会是sql默认的字符集编码

2.6 修改和删除表

修改


-- 修改表   ALTER TABLE 旧表名 RENAME AS 新表名
ALTER TABLE student1 RENAME AS student_first
-- 增加表的字段 ALTER TABLE 表名 ADD 字段名 属性
ALTER TABLE student_first ADD age INT(11)
-- 修改表的字段
-- ALTER TABLE  表名  MODIFY 字段名 列属性  -- 修改约束
ALTER TABLE student_first MODIFY age VARCHAR(11)  -- 修改约束-- ALTER TABLE 表名 CHANGE 旧名字 新名字 列属性[]  -- 字段重命名
ALTER TABLE student_first CHANGE age age1 INT(1)  -- 字段重命名-- 删除表的字段 ALTER TABLE 表名 DROP 字段名
ALTER TABLE student_first DROP age

删除

-- 删除表(如果表存在再删除)
DROP TABLE IF EXISTS student

所有的创建和删除操作尽量加上判断,以免报错

注意:

  • `` 字段名,使用这个包裹
  • 注释 – /**/
  • sql关键字大小写不敏感,建议大家写小写
  • 所有的符号全部用英文!

3. MySQL数据管理

3.1 外键(了解即可)

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

删除有外键关系的表的时候,必须要先删除引用别人的表(从表),再删除被引用的表(主表)

方式二, 创建表成功后,添加外键约束

CREATE TABLE `grade`(`gradeid` INT(10) NOT NULL AUTO_INCREMENT COMMENT 'grade id',`gradename` VARCHAR(50) NOT NULL COMMENT '年级',PRIMARY    KEY(`gradeid`)
)ENGINE = INNODB DEFAULT CHARSET=utf8CREATE TABLE IF NOT EXISTS `student1`(`id` INT(4) NOT NULL AUTO_INCREMENT COMMENT '学号',`name` VARCHAR (30) NOT NULL DEFAULT '匿名' COMMENT '姓名',`pwd` VARCHAR(20) NOT NULL DEFAULT '123456' COMMENT '登录密码',`sex` VARCHAR(2) NOT NULL DEFAULT '' COMMENT '性别' ,`birthday` DATETIME DEFAULT NULL COMMENT '出生日期',`gradeid` INT(10)NOT NULL COMMENT '学生的年级',`address` VARCHAR(100) DEFAULT NULL COMMENT  '家庭住址',`email` VARCHAR(50) DEFAULT NULL COMMENT '邮箱',PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;-- 创建表的时候, 没有外键关系
ALTER TABLE `student1`
ADD CONSTRAINT `FK_gradeid` FOREIGN KEY (`gradeid`) REFERENCES `grade`(`gradeid`);
-- ALTER TABLE 表 ADD CONSTRAINT 约束名 FOREIGN KEY(作为外键的列)REFERENCES 那个表(哪个字段)

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

最佳实践

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

3.2 DML语言

DML语言:数据操作语言
• Insert
• update
• delete

3.3 添加

-- 插入数据(添加)
-- insert into 表名([字段名1 , 字段名2, 字段名3]) values ('值1','值2','值3')
-- insert into 表名(字段名1) values ('值1'),('值2'),('值3')
INSERT INTO `grade`(`gradename`) VALUES ('大四')-- 由于主键自增我们可以省略(如果不写表的字段,他就会一一匹配)
INSERT INTO `grade` VALUES('大三')-- 一般写插入语句,我们一定要保证数据和字段一一对应。-- 插入多个字段
INSERT INTO `grade`(`gradename`)  VALUES ('大四'),('大三'),('大二')

语法: insert into 表名([字段名1 , 字段名2, 字段名3]) values ('值1','值2','值3')

注意事项:

  1. 字段和字段之间使用英文逗号隔开
  2. 字段是可以省略的,但是后面的值必须要要一一对应,不能少
  3. 可以同时插入多条数据,VALUES后面的值,需要使用,隔开即可VALUES

3.4 修改

update 修改谁(条件) set原来的值=新值

-- 修改学员名字
UPDATE `student_first` SET `name` = '狂神' WHERE id = 1;-- 不指定条件的情况下, 会改动所有表
UPDATE `student_first` SET `name` = '007' ;-- 修改多个属性,逗号隔开
UPDATE `student_first` SET `name` = '狂神',`email` = '000@163.com' WHERE id = 1;-- 语法
-- UPDATE 表名 SET  colnum_name = value,[colnum_name = value] WHERE 条件;

UPDATE 表名 SET colnum_name = value,[colnum_name = value] WHERE 条件;

注意:

  • colnum_name 是数据库的列,尽量带上``
  • 条件,筛选的条件,如果没有指定,则会修改所有的列
  • value,是一个具体的值,也可以是一个变量
  • 多个设置的属性之间,使用英文逗号隔开
UPDATE `student` SET `birthday` = CURRENT_TIME WHERE `name` ='长江7号' AND `sex`='女'

3.5 删除

delete
delete from 表名 [where 条件]

-- 删除数据
DELETE FROM `student_first`
-- 删除指定数据数据
DELETE FROM `student_first` WHERE id=1;-- 清空 truncate
TRUNCATE `student_first`

delete是dml语言,truncate是ddl语言

  • 相同点:都能删除数据,都不会删除表结构
  • 不同:
    • TRUNCATE重新设置自增列计数器会归零
    • TRUNCATE不会影响事务
-- 测试delete和truncate的区别CREATE TABLE `test`(
`id` INT(4) NOT NULL AUTO_INCREMENT,
`coll` VARCHAR(20) NOT NULL,
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8INSERT INTO `test`(`coll`) VALUES ('1'),('2'),('3')
DELETE FROM `test` -- 不会影响自增
TRUNCATE TABLE `test` -- 自增会归零

4. DQL查询数据(最重点)

之前写过,参考这篇文章,接下来补充移动点
sql语句笔记

4.2 指定查询字段

SELECT VERSION()--查询系统版本 (函数)
SELECT 100*3-1AS 计算结果 --用来计算(表达式)
SELECT e@auto increment increment --查询自增的步长 (变量)

4.3 Where条件子句

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

4.4 联表查询

4.5 自连接


4.6 分页和排序

分页:limit
排序:order by
为什么要分页? 缓解数据库压力,给人的体验更好,瀑布流

4.7 子查询

5. MySQL函数

5.1 常用函数

-- 数学类函数
SELECT ABS(-8)  -- 绝对值
SELECT CEILING(9.4)  -- 向上取整
SELECT FLOOR(9.4)   -- 向下取整
SELECT RAND()   -- 返回一个0~1之间的随机数
SELECT SIGN(10) -- 判断一个数的符号,   负数返回-1,正数返回1
-- 字符串函数
SELECT CHAR_LENGTH('4455')  -- 字符串长度
SELECT CONCAT('','','')  -- 拼接字符串
SELECT  INSERT('我爱编程helloword',1,2,'超级热爱')    -- 插入,替换
SELECT LOWER('JHHJ')  -- 转小写
SELECT UPPER('dfs')   -- 转大写
SELECT INSTR('kuangshen','h') -- 查询 第一次出现的位置
SELECT REPLACE('坚持就能成功','坚持','努力')   -- 坚持替换为努力-- 时间和日期函数(记住)
SELECT CURRENT_DATE() -- 获取当前日期
SELECT CURDATE()      -- 获取当前日期
SELECT NOW()-- 获取当前时间
SELECT SYSDATE()  -- 获取系统时间-- 系统
SELECT USER()

5.2 聚合函数(常用)

count(字段)   --  会忽略所有的null值
sum()
avg()
max()
min()

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

MD5由MD4、MD3、MD2改进而来,主要增强算法复杂度和不可逆性。MD5算法因其普遍、稳定、快速的特点,仍广泛应用于普通数据的加密保护领域。

CREATE TABLE `testmd5`(
`id`  INT(4) NOT NULL,
`name` VARCHAR(20) NOT NULL,
`pwd` VARCHAR(50) NOT NULL,
PRIMARY KEY(`id`)
)ENGINE = INNODB DEFAULT CHARSET=utf8-- 明文密码
INSERT INTO testmd5 VALUES (1,'s','132456'),(2,'a','132456'),(3,'b','132456')-- 加密
UPDATE testmd5 SET pwd=MD5(pwd) WHERE id = 1-- 插入的时候加密
INSERT INTO testmd5 VALUES (1,'s',MD5('132456')-- 如何校验:将用户传递进来的密码,进行md5加密,然后进行对比加密后的值

6. 事务

6.1 什么是事务

将一组SQL放在一个批次中去执行~

事务原则:ACID 原子性,一致性,隔离性,永久性

  • 原子性:要么都成功,要么都失败.
  • 一致性:事务的前后数据完整性要保证一致
  • 持久性:事务一旦提交则不可逆,被持久化到数据库中
  • 隔离性:事务的隔离性是多个用户并发访问数据库时,数据库为每个用户开启的事务,不能被其他事务的操作所干扰。

事务的并发问题:

  • 脏读,指一个事务读取了另一个事务未提交的数据
  • 不可重复读:在一个事务内读取表中的某一行数据,多次读取结果不同。
  • 虚读(幻读):在一个事务中读取到了别的事务插入的数据,导致前后读取不一致
    事务的隔离级别:
-- =============事务============
-- mysql是默认开启事务自动提交的
SET autocommit = 0 /* 关闭 */
SET autocommit = 1 /* 开启(默认的) */ -- 手动处理事务
SET autocommit = 0   -- 关闭自动提交-- 事务开启
START TRANSACTION  -- 标记一个事务的开始,从这个之后的sql都在同一个事务内INSERT xx
INSERT xx-- 提交: 持久化()成功
COMMIT
-- 回滚:  回到原来的样子(失败)
ROLLBACK
-- 事务结束
SET autocommit = 1 -- 开启自动提交-- 了解
SAVEPOINT 保存点  -- 设置一个事务的保存点
ROLLBACK TO SAVEPOINT   -- 回滚到保存点
RELEASE SAVEPOINT -- 删除保存点

模拟事务

--
CREATE DATABASE shop CHARACTER SET utf8 COLLATE utf8_general_ci
USE shopCREATE TABLE `account`(`id` INT(3) NOT NULL AUTO_INCREMENT,`name` VARCHAR(30) NOT NULL,`money` DECIMAL(9,2) NOT NULL,PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8INSERT INTO account(`name`,`money`)
VALUES ('A',2000.00),('B', 10000.00)-- 模拟转账:事务
SET
autocommit = 0; -- 关闭自动提交
START TRANSACTION ; -- 开启一个事务
UPDATE account SET money=money-500 WHERE `name`='A'; -- a减500
UPDATE account SET money=money+500 WHERE `name`='B'; -- b加500COMMIT;  -- 提交事务,就被持久化了
ROLLBACK;  -- 回滚SET autocommit = 1;  -- 开启自动提交

7. 索引

MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。
提取句子主干,就可以得到索引的本质:索引是数据结构。

7.1 索引的分类

在一个表中,主键索引只能有一个,唯一索引可以有多个

  • 主键索引 (PRIMARY KEY)。唯一的标识,主键不可重复,只能有一个列作为主键

  • 唯一索引 (UNIQUE KEY)。避免重复的列出现,唯一索引可以重复,多个列都可以标识位唯一索引

  • 常规索引(KEY / INDEX) 默认的,index。key关键字 来设置

  • 全文索引(FullTEXT) 在特定的数据库引擎下才有,MyISAM,快速定位数据

-- 显示所有的索引信息
SHOW INDEX FROM `student_first`-- 增加一个全文索引
-- 此处前面的是给索引起的名字,后面是被加上索引的列的名字(字段名)
ALTER TABLE school.`student_first` ADD FULLTEXT INDEX `email`(`email`)-- explain 分析sql执行的状况
EXPLAIN SELECT * FROM student_first; -- 非全文索引-- id表名字段名
-- CREATE INDEX 索引名 on表(字段)
CREATE INDEX id_app_user_name ON app_user('name');

7.2 SQL编程创建100万条数据测试索引

CREATE TABLE `app_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 NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT = 'app用户表'-- 插入100条数据
DELIMITER $$ -- 写函数之前, 必须要写 标志
CREATE FUNCTION mock_data()
RETURN INT
BEGINDECLARE num INT DEFAULT 1000000;DECLARE    i INT DEFAULT 0;WHILE i < num DO-- 插入语句INSERT INTO app_user(`name`,`email`,`phone`,`gender`,`password`,`age`)VALUES (CONCAT('用户',i),'13245679@qq.com',CONCAT('18',FLOOR(RAND()*(999999999100000000)+100000000)),FLOOR(RAND()*2),UUID(),FLOOR(RAND()*100))SET i = i + 1;END WHILE
END;-- id表名字段名
-- CREATE INDEX 索引名 on表(字段)
CREATE INDEX id_app_user_name ON app_user('name');

索引在小数据量的时候,用户不大,但是在大数据的时候,区别十分明显~

7.3 索引原则

MySQL索引背后的数据结构及算法原理

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

索引的数据结构
Hash类型的索引
Btree: innoDB的默认索引

8. 权限管理

8.1 用户管理

SQL yog

命令操作

-- 创建用户
CREATE USER kuangshen IDENTIFIED BY '123456'-- 修改当前用户密码
SET PASSWORD = PASSWORD('11111')-- 修改指定用户密码SET PASSWORD FOR kuangshen = PASSWORD('123456')-- 重命名
RENAME USER kuangshen TO kuangshen2-- 用户授权 GRANT ALL PRIVILEGES 全部的全家 , 库.表
-- ALL PRIVILEGES除了给别人授权
GRANT ALL PRIVILEGES ON *.* TO kuangshen-- 查看权限
SHOW GRANTS FOR kuangshen  -- 查看指定用户的权限
SHOW GRANTS FOR root@localhost-- 撤销权限
REVOKE ALL PRIVILEGES ON *.* FROM kuangshen-- 删除用户
DROP USER kuangshen

8.2 MySql备份

为什么要备份:

  • 保证重要的数据不丢失
  • 数据转移

MySQL数据库备份的方式

  • 直接拷贝物理文件
  • 在可视化工具中手动导出
  • 使用命令行 mysqldump 命令行使用

9. 规范数据库设计

9.1 为什么需要设计

当数据比较复杂的时候,我们就需要设计了
糟糕的数据库设计:

  • 数据冗余,浪费空间
  • 数据库插入和删除都会麻烦、异常【屏蔽使用物理外键】
  • 程序性能差

糟糕的数据库设计:

  • 节省内存空间
  • 保证数据库的完整性
  • 方标我们开发系统

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

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

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

  1. 手机信息,分析需求
    - 用户表(用户登录注销,用户的个人信息,写博客,创建分类)
    - 分类表(文章分类,谁创建的)
    - 文章表(文章的信息)
    - 评论
    - 友链表(友链信息)
    - 自定义表(系统信息,某个关键字,或者一个主字段)
  2. 标识实体(把需求落地到某个字段)
  3. 标识实体之间的关系
    - 写博客user —> blog
    - 创建分类 user —> category
    - 关注 user —> user
    - 友链 links
    - 评论 user-user-blog

9.2 数据库的三大范式

为什么信息需要规范化?

  • 信息重复
  • 更新导致异常
  • 插入异常 无法正常显示信息
  • 删除异常 丢失有效的信息

三大范式:
第一范式(1NF):要求数据库表的每一列都是不可分割的原子数据项。

  • 原子性,不可再分

第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)

  • 第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。
  • 每张表只描述一件事情

第三范式(3NF):在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)

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

规范性 和性能问题
关联查询的表不得超过三张表

  • 考虑商业化的需求和目标(成本,用户体验)数据库的性能更加重要
  • 在规范性能问题的时候,需要适当的考虑以下 规范性
  • 故意给某些表增加一些冗余的字段(从多表查询中变为单表查询)
  • 故意增加一些计算列(从大数据降低为小数据量的查询:索引)

– 业务级别的MySQL学习
– 运维级别的MySQL学习

10. JDBC(重点)

10.1 数据库驱动

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

10.2 JDBC

SUN公司为了简化开发人员的(对数据库的统一)操作,提供了一个(Java操作数据库的)规范,俗称JDBC
这些规范的实现由具体的厂商去实现
对于开发人员来说,我们只需要掌握JDBC接口的操作即可


java.sql
javax.xql
还需要导入一个数据库驱动包 mysql-connector-java-5.1.47.jar

10.3 第一个JDBC程序

创建测试数据库

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','zhangsan','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')
  1. 创建一个普通项目
  2. 导入数据库驱动
  3. 编写测试代码
package com.yu.lesson01;
import java.sql.*;
// 我的第一个JDBC程序
public class JdbcFirstDemo {public static void main(String[] args) throws ClassNotFoundException, SQLException {// 1. 加载驱动Class.forName("com.mysql.cj.jdbc.Driver"); // 固定写法,加载驱动// 2. 用户信息和urlString url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true";String username = "root";String password = "123456";// 2. 连接成功,数据库对象       Connection 代表数据库Connection connection = DriverManager.getConnection(url, username, password);// 4. 执行sql对象   statement 执行sql的对象Statement statement = connection.createStatement();// 4. 执行sql对象  去执行SQL可能存在的结果,查看返回结果String sql = "SELECT * FROM users";ResultSet resultSet = statement.executeQuery(sql); // 返回的结果集,结果集中封装了我们全部的查询出来的结果while(resultSet.next()){System.out.println("id = " + resultSet.getObject("id"));System.out.println("name = " + resultSet.getObject("NAME"));System.out.println("pwd = " + resultSet.getObject("PASSWORD"));System.out.println("email = " + resultSet.getObject("email"));System.out.println("brith = " + resultSet.getObject("birthday"));}//  6.释放连接resultSet.close();statement.close();connection.close();}}

步骤总结:

  1. 加载驱动
  2. 连接数据库DriverManager
  3. 获的执行sql的对象statement
  4. 获得返回的结果
  5. 释放连接
// 1. 加载驱动// DriverManager.registerDriver(new com.mysq1.jdbc.Driver());Class.forName("com.mysql.cj.jdbc.Driver"); // 固定写法,加载驱动// 2. 用户信息和urlString url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true";String username = "root";String password = "123456";// 2. 连接成功,数据库对象       Connection 代表数据库Connection connection = DriverManager.getConnection(url, username, password);// 4. 执行sql对象   statement 执行sql的对象Statement statement = connection.createStatement();// 4. 执行sql对象  去执行SQL可能存在的结果,查看返回结果String sql = "SELECT * FROM users";ResultSet resultSet = statement.executeQuery(sql); // 返回的结果集,结果集中封装了我们全部的查询出来的结果while(resultSet.next()){System.out.println("id = " + resultSet.getObject("id"));System.out.println("name = " + resultSet.getObject("NAME"));System.out.println("pwd = " + resultSet.getObject("PASSWORD"));System.out.println("email = " + resultSet.getObject("email"));System.out.println("brith = " + resultSet.getObject("birthday"));}//  6.释放连接resultSet.close();statement.close();connection.close();}}

connection 数据库自动提交, 事务提交, 事务回滚。

   connection.rollback();connection.commit();connection.setAutoCommit();

Statement 执行SQL的对象 查新操作,更新操作
PrepareStatement 执行SQL的对象

    statement.executeQuery();  // 查询操作返回 ResultSetstatement.execute();      // 执行任何的SQLstatement.executeUpdate()   // 更新、插入、删除,都是用这个,返回一个受影响的行数

ResultSet 查询的结果集:封装了所有的查询结果

resultSet.getObject(); // 在不知道列类型的情况下使用,
// 如果知道列的类型 就使用指定类型
resultSet.getString();
resultSet.getInt();
resultSet.getFloat();
resultSet.getDate();

遍历指针

resultSet.beforeFirst(); //  移动到最前面
resultSet.afterLast(); //  移动到最后面
resultSet.next();   // 移动到下一个数据
resultSet.previous();    // 移动到前一行
resultSet.absolute(row) ;  //  移动到指定行

释放资源

        //  6.释放连接resultSet.close();statement.close();connection.close();

10.4 statement对象

Jdbc中的statemient对象用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过这个对象向数据库发送增删改查语句即可。
Statement对象的executeUpdate方法,用于向数据库发送增、删、改的sql语句,executeUpdate执行完后,将会返回一个整数(即增删改语句导致了数据库几行数据发生了变化)。
Statement.executeQuery方法用于向数据库发送查询语句,executeQuery方法返回代表查询结果的ResultSet对象。



package com.yu.lesson2;import com.yu.lesson2.utils.JdbcUtils;import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;public class TestInsert {public static void main(String[] args) {Connection conn = null;Statement st = null;ResultSet rs = null;try {conn = JdbcUtils.getConnection(); // 获取数据库连接st = conn.createStatement(); // 获得SQL的执行对象String sql = "INSERT INTO users(id, `NAME`,`PASSWORD`,`email`,`birthday`)" +"VALUES(5,'kuangshen','13456','132456@QQ.com','2020-1-1')";int i = st.executeUpdate(sql);if(i>0){System.out.println("插入成功");}} catch (SQLException throwables) {throwables.printStackTrace();}finally {JdbcUtils.release(conn, st, rs);}}
}

查询

package com.yu.lesson2;import com.mysql.cj.protocol.Resultset;
import com.yu.lesson2.utils.JdbcUtils;import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;public class TestSelect {public static void main(String[] args) {Connection conn = null;Statement st =null;ResultSet re = null;try {conn = JdbcUtils.getConnection();st = conn.createStatement();String sql = "select * from users where id = 1";re = st.executeQuery(sql); // 查询完毕会返回一个结果集while (re.next()){System.out.println(re.getString("NAME"));}} catch (SQLException throwables) {throwables.printStackTrace();}finally {JdbcUtils.release(conn,st,re);}}
}

sql注入
sql存在漏洞,会被攻击导致数据泄露,SQL会被拼接or

package com.yu.lesson2;import com.yu.lesson2.utils.JdbcUtils;import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;public class SQL注入 {public static void main(String[] args) {login("kuangshen","13456");login("'or  ' 1=1 ","123456");}public static void login(String username, String password){Connection conn = null;Statement st =null;ResultSet re = null;try {conn = JdbcUtils.getConnection();st = conn.createStatement();String sql = "select * from users where `NAME` = '"+username+"' and `password` = '"+password+"'";re = st.executeQuery(sql); // 查询完毕会返回一个结果集while (re.next()){// 口诀:先SQL原型,替换为单引,中间加双引,中间加双加号,中间加变量。System.out.println(re.getString("NAME"));System.out.println(re.getString("password"));}} catch (SQLException throwables) {throwables.printStackTrace();}finally {JdbcUtils.release(conn,st,re);}}}

10.5 PrepareStatement对象

可以防止sql注入,并且效率更高。

其本质把传递进来的参数当作字符,假设其中存在转义字符,比如说’直接会被转义

增删改

package com.yu.lesson03;import com.yu.lesson2.utils.JdbcUtils;import java.sql.*;public class TestInsert {public static void main(String[] args) {Connection conn = null;PreparedStatement st = null;try {conn = JdbcUtils.getConnection();// 区别// 使用? 占位符代替参数String sql = "INSERT INTO users(id, `NAME`,`PASSWORD`,`email`,`birthday`)VALUES(?,?,?,?,?)";st = conn.prepareStatement(sql);// 预编译,先写sql,然后不执行//手动给参数赋值st.setInt(1,6);st.setString(2,"qinjian");st.setString(3,"kjjjljk");st.setString(4, "132456798@qq.com");// 注意点  sql。Date 数据库                java.sql.Date()//              util。date java          new Date().getTime() 获得时间戳st.setDate(5, new java.sql.Date(new java.util.Date().getTime()));// 执行int i = st.executeUpdate();if(i > 0){System.out.println("传入成功");}} catch (SQLException throwables) {throwables.printStackTrace();}finally {JdbcUtils.release(conn,st,null);}}
}

查询

package com.yu.lesson03;import com.yu.lesson2.utils.JdbcUtils;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class TestSelect {public static void main(String[] args) {Connection conn = null;PreparedStatement st = null;ResultSet rs = null;try {conn = JdbcUtils.getConnection();// 区别// 使用? 占位符代替参数String sql = "select * from users where id = ?";st = conn.prepareStatement(sql);// 预编译,先写sql,然后不执行//手动给参数赋值st.setInt(1,3);// 传递参数// 执行rs = st.executeQuery();if(rs.next()){System.out.println(rs.getString("NAME"));}} catch (SQLException throwables) {throwables.printStackTrace();}finally {JdbcUtils.release(conn,st,null);}}
}

10.6 使用IDEA连接数据库


一定要先导包
jdbc:mysql://localhost:3366?serverTimezone=UTC


连接成功后可以选择数据库

10.7 JDBC操作事务

要么都成功,要么都失败
ACID原则:原子性,一致性,隔离性,持久性

package com.yu.lesson04;import com.yu.lesson2.utils.JdbcUtils;import java.sql.*;public class TestTransaction {public static void main(String[] args) {Connection conn = null;PreparedStatement st =null;ResultSet rs = null;try {conn = JdbcUtils.getConnection();//关闭数据库的自动提交事务, 自动会开启事务conn.setAutoCommit(false);String sql1 = "update account set money = money -100  where name = 'A'";conn.prepareStatement(sql1);st.executeUpdate();String sql2 = "update account set money = money + 100 where name = 'B'";conn.prepareStatement(sql2);st.executeUpdate();// 业务完毕提交事务conn.commit();System.out.println("成功");} catch (SQLException throwables) {try {conn.rollback();  // 如果失败则回滚事务} catch (SQLException e) {e.printStackTrace();}throwables.printStackTrace();}finally {JdbcUtils.release(conn,st,rs);}}
}

10.9 数据库连接池

数据库—执行完毕—释放
连接–释放 十分浪费资源

池化技术:准备一些预先的资源,过来就连接预先准备好的。
最小连接数: 100 按常用连接数弄
最大连接数: 业务最高承载上限
排队等待
等待超时:100ms

编写连接池,实现一个接口 DateSource

开源数据源实现

DBCP
C3P0
Druid: 阿里巴巴

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

DBCP

需要用到的jar包,commons-dbcp-1.4、 commons-pool-1.6、commons-logging-1.2.jar

#连接设置
driverClassName=com.mysql.cj.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.yu.lesson05.utils;import com.yu.lesson2.utils.JdbcUtils;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;public class JdbcUtils_DBCP {private static  BasicDataSource dataSource = null;static {try{// 这里是通过类获取反射对象,然后获取反射对象的类加载器,调用类加载器的获取资源的方法。一步一步来的InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");Properties properties = new Properties();properties.load(in);// 创建数据源  工厂模式--》 创建try {dataSource = BasicDataSourceFactory.createDataSource(properties);} catch (Exception e) {e.printStackTrace();}}catch (IOException  e){e.printStackTrace();}}// 获取连接public static Connection getConnection()throws java.sql.SQLException{return dataSource.getConnection(); // 从数据源获取连接}//  释放连接资源public static void release(Connection cnn, 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(cnn != null){try {cnn.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}
}
package com.yu.lesson05;import com.yu.lesson05.utils.JdbcUtils_DBCP;
import com.yu.lesson2.utils.JdbcUtils;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;public class TestDBCP {public static void main(String[] args) {Connection conn = null;PreparedStatement st = null;try {//conn = JdbcUtils.getConnection();conn = JdbcUtils_DBCP.getConnection();// 区别// 使用? 占位符代替参数String sql = "INSERT INTO users(id, `NAME`,`PASSWORD`,`email`,`birthday`)VALUES(?,?,?,?,?)";st = conn.prepareStatement(sql);// 预编译,先写sql,然后不执行//手动给参数赋值st.setInt(1,22);st.setString(2,"qinjian");st.setString(3,"kjjjljk");st.setString(4, "132456798@qq.com");// 注意点  sql。Date 数据库                java.sql.Date()//              util。date java          new Date().getTime() 获得时间戳st.setDate(5, new java.sql.Date(new java.util.Date().getTime()));// 执行int i = st.executeUpdate();if(i > 0){System.out.println("传入成功");}} catch (SQLException throwables) {throwables.printStackTrace();}finally {JdbcUtils_DBCP.release(conn,st,null);}}
}

无论使用什么数据源,本质还是一样的,DataSource接口不会变,方法就不会变

【学习笔记】SQL数据库相关推荐

  1. oracle protocol=beq 不可用,学习笔记:Oracle数据库坏块 深入研究obj$坏块导致exp/expdp不能执行原因...

    天萃荷净 深入研究Oracle坏块obj$导致exp/expdp不能执行导出的原因 上篇(案例:Oracle出现obj$坏块exp/expdp导出不能导出的解决办法ORA-01578 ORA-0111 ...

  2. 家族关系查询系统程序设计算法思路_【学习笔记】数据库基础 - 查询优化

    目录 什么是数据库查询优化? 影响查询优化的因素 优化策略概述 查询优化的总体思路 语义优化 -- 内容等价性 语法优化(逻辑层优化)---语法等价性 执行优化(物理层优化) 查询优化在DBMS中的位 ...

  3. oracle中如何格式化输出,【学习笔记】数据库日期时间格式化输出案例

    天萃荷净 分享一篇关于开发DBA在工作中常用到的日期时间格式化输出方法案例,含:mysql.sql server.oracle 3种数据库日期时间格式化输出 1.mysql数据库时间格式化输出 DAT ...

  4. 数据挖掘学习笔记——GEO数据库:芯片数据分析

    数据挖掘 数据挖掘学习笔记--GEO数据库:芯片数据分析 文章目录 数据挖掘 一.芯片基础知识 1.1.背景 二.GEO数据库概述 2.1.基础简介 2.2.检索页面展示 三.GSE项目的三种下载方式 ...

  5. JavaWeb学习笔记(数据库、SQL语句、数据查询语法、完整性约束、编码、备份和恢复数据、多表查询)

    数据库.SQL语句.数据查询语法.完整性约束.编码.备份和恢复数据.多表查询 JavaWeb学习笔记 数据库 数据库概念 基本命令 启动和关闭mysql服务器 客户端登录退出mysql SQL语句 S ...

  6. Python学习笔记:数据库2

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  7. Qt学习笔记之数据库

    一.数据库简介 1.1.数据和数据库(DB) 用计算机进行数据处理,首先就要把信息以数据形式存储到计算机中,故数据是可以被计算机接受和处理的符号.根据所表示的信息特征不同,数据有不同的类别,如数字.文 ...

  8. web安全学习笔记--sql语句(sql注入基础上)

    一.基础知和表内操作语法 1.sql语句对大小写不敏感!!! SELECT - 从数据库表中获取数据:select * from (columns/tables/databases); UPDATE ...

  9. 【Python学习笔记】数据库应用

    #本文一切代码及理论均来自于郑秋生.夏敏捷二位老师主编<Python项目案例发 从入门到实践>一书,本人仅做微改.创作本文的目的仅为总结本人的学习过程和成果,借此巩固.可能存在许多疏漏之处 ...

  10. 小菜鸡的学习笔记——sql注入之sqli-lab边学边练

    结合sqli-lab靶场的sql注入学习笔记<持续更新> 第一关 Way1:字符型联合注入 Way2:报错型注入 第二关:get数值型联合注入 第三关:字符型闭合注入 第四关:字符型闭合注 ...

最新文章

  1. 面试题:mysql 一棵 B+ 树能存多少条数据?
  2. python 运行部分代码_改改Python代码,运行速度还能提升6万倍
  3. Leetcode题目:Balanced Binary Tree
  4. Spring.NET 学习总结
  5. C语言 编写程序:请将Fibonacci数列前30项中的偶数值找出来,存储到一维数组中。其中,Fibonacci数列如下:1,1,2,3,5,8,13,21,34...该数列除前两项之外,其他任意
  6. CyanogenMod源码编译模拟器
  7. 面对想法简单客户的有效需求分析
  8. python生成配置文件config_Python configparser模块封装及构造配置文件
  9. 如何用while循环输出十行十列变色★☆
  10. 20145231熊梓宏 《网络对抗》 实验四 恶意代码分析
  11. linux程序网络验证,【redhat5.5】linux的LDAP认证服务器的配置及客户端pam网络验证实例...
  12. 强大的离线字典《Colordict》+多种词库下载地址
  13. 三阶魔方还原步骤图_3阶魔方教程 1~7步骤,三阶魔方顶层还原图解
  14. 关于 IP 属地的一些科普
  15. 精通使用K米短信教程
  16. UFS Power Management 介绍
  17. proteus三输入与非门名字_proteus元件名称中文名说明
  18. LOL召唤师信息查询工具(可查服务器、段位、胜点,隐藏分、战斗力)
  19. 数据库——ODBC连接
  20. 【计算机基础04】Excel知识

热门文章

  1. excel2019如何做下拉菜单选项(数据源不占用原表上的单元格)
  2. C语言之strcat函数
  3. Redis(狂神说 )学习使用笔记
  4. python3 列表长度_3种在Python中查找列表长度的简便方法
  5. L1、L2正则VS L1、L2 loss
  6. OpenCV--0016:图像ROI与ROI操作
  7. 机器学习 06:SMO 算法
  8. 页面报404错误有哪些原因?
  9. 达梦数据库的连接(四种方式-亲测可用)达梦数据库的几大小助手工具
  10. 粗览Activiti Modeler操作和源代码