MySQL基础

MySQL

1、连接数据库

命令行连接

mysql -uroot -p123456 --连接数据库

update mysql.user set authentication_string=password('123456') where user='root' and Host='localhost'; --修改密码
flush privileges;  --刷新权限

-----------------------
--所有的语句都使用;结尾
show databases; --查看所有的数据库

mysql>  use school -- 切换数据库 use (数据库名)
Database changed

show tabales; -- 查看数据库中所有的表
described student; -- 显示数据库中所有表的信息/desc

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

exit; --退出连接

--单行注释
/*(多行注释)
asd
asd
*/

数据库xxx语言

DDL 定义

DML 操作

DQL 查询

DCL 控制

2、操作数据库

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

2.1、操作数据库

1、创建数据库

create database [if no exists] westos;

2、删除数据库

drop database if exists westos;

3、使用数据库

--如果表名或字段名是一个特殊字符,就需要带` `
use `westos`;

4、查看数据库

show database;--查看所有的数据库

2.2、数据库的列类型

数值

tinyint 十分小的数据 1个字节

smallint 较小的数据 2个字节

mediumint 中等大小的数据 3个字节

int 标准的整数 4个字节 常用

bigint 较大的数据 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来填充 eg: int(3) , 5–005

auto_increment

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

Null & not null

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

默认 default

  • 设置默认的值

commet

  • 注释

拓展:

--每一个表都必须存在以下五个字段。做项目用的,表示一个记录存在意义
id  -- 主键
'version'  -- 乐观锁
is_delete  -- 伪删除
gmt_create -- 创建时间
gmt_update -- 修改时间 

2.4、创建数据库表(重点)

-- 目标 : 创建一个school数据库
-- 创建学生表(列,字段)  使用SQL创建
-- 学号int 登录密varchar(20) 姓名,性别varchar(2),出生日期(datatime),家庭住址,email

-- 注意点,使用英文(), 表的名称和 字段 尽量使用``括起来
-- AUTO_INCREMENT 自增
-- 字符串的使用用''括起来 eg:comment '注释'
-- 所有的语句后面加, 最后一个不用加
-- 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(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`)
)ENDINE=INNODB DEFAULT CHARSET=utf8

格式

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

常用命令

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

2.5、数据库表的类型

-- 关于数据库引擎
/*
INNODB 默认使用
MYISAM 早些年使用
*/
MYISAMINNODB
事务支持不支持支持
数据行锁定不支持(表锁定)支持(两个都)
外键约束不支持支持
全文索引支持不支持
表空间的的大小较小较大,约2倍MYISAM

常规使用操作:

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

在物理空间存在的位置

所有的数据库文件都存在data目录下

本质还是文件的存储

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

  • INNODB 在数据库表中只有一个*.frm文件,以及上级目录下的ibdata1文件
  • MYISAM对应文件
    • *.frm --表结构的 定义文件
    • *.MYD --数据文件(data)
    • *.MYI --索引文件(index)

设置数据库表的字符集编码

CHARSET=utf8

不设置的话,会是mysql默认的字符集编码(不支持中文)

MySQL的默认编码是Latin1,不支持中文

在my.ini中配置默认的编码

character-set-server=utf8

2.6、修改删除表

修改

-- 修改表名: ALTER TABLE 旧表名 RENAME AS 新表名
ALTER TABLE teacher RENAME AS teacher1
-- 增加表的字段:  ALTER TABLE 表名 ADD 字段名 列属性
ALTER TABLE teacher1 ADD age INT(11)

--ALTER TABLE 表名 MODIFY 字段名 列属性[]
ALTER TABLE teacher1 MODIFY age VARCHAR(11)  --修改约束
-ALTER TABLE 表名 CHANGE 旧字段名 新字段名 列属性[]
ALTER TABLE teacher1 CHANGE age age1 INT(1) --字段重命名


-- 删除表的字段: ALTER TABLE 表名 DROP 字段名
ALTER TABLE teacher1 DROP age1

删除

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

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

3、MySQL数据管理

3.1、外键(了解)

方式一、在创建表的时候,增加约束

CREATE TABLE `grade`(
  `gradeId` INT(10) NOT NULL AUTO_INCREMENT COMMENT '年级id',
  `gradeName` VARCHAR(50) NOT NULL COMMENT '年级名称',
   PRIMARYKEY(`gradeId`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

-- 学生表的gradeId字段 要去引用年级表的gradeId
-- 定义外键key
-- 给这个外键添加约束(执行引用) references 引用

CREATE TABLE IF NOT EXISTS `student`(
   `id` INT(4) NOT NULL AUTO_INCREMENT COMMENT '学号',
    `gradeId` INT(10) NOT NULL AUTO_INCREMENT COMMENT '年级id',
   `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`),
    KEY `FK_gradeId` (`gradeId`),
    CONSTRAINT `FK_gradeId` FOREIGN KEY (`gradeId`) REFERENCES `grade`(`gradeId`)
)ENDINE=INNODB DEFAULT CHARSET=utf8

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

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

CREATE TABLE IF NOT EXISTS `student`(
   `id` INT(4) NOT NULL AUTO_INCREMENT COMMENT '学号',
    `gradeId` INT(10) NOT NULL AUTO_INCREMENT COMMENT '年级id',
   `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`)
)ENDINE=INNODB DEFAULT CHARSET=utf8

--创建表的时候没有外键关系
ALTER TABLE `student`
ADD CONSTRAINT `FK_gradeId` FOREIGN KEY (`gradeId`) REFERENCES `grade`(`gradeId`);

-- ALTER TABLE 从表 ADD CONSTRAINT 约束名 FOREIGN KEY(作为外键的列) REFERENCES 主表(列)

以上操作都是物理外键,数据库级别的外键,不建议使用。

最佳实践

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

3.2、DML语言(记住)

DML语言:数据操作语言

  • insert
  • updat
  • delete

3.3、添加

insert

-- 插入语句(添加)
-- insert into 表名([字段1,字段2,字段3..])values('值1','值2',值3')...;
INSERT INTO `grade`(`gradeName`) VALUES('大一');

-- 由于主键自增我们可以省略(如果不写表的字段,他就会一一匹配)
INSERT INTO `grade` VALUES('大三');

-- 一般写插入语句,我们一定要数据和字段一一对应

-- 插入多个字段
INSERT INTO `grade`(`gradeName`);
VALUES('大二'),('大四');

INSERT INTO `student`(`name`)VALUES('张三');

INSERT INTO `student`(`name`,`pwd`,`sex`)VALUES('张三''123456','男');

INSERT INTO `student`(`name`,`pwd`,`sex`);
VALUES('张三''123456','男'),('李四''123456','女');

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

注意事项:

  • 字段和字段之前使用英文逗号隔开
  • 字段是可以省略的,但是后面的值必须要一一对应
  • 可以同时插入多条数据,VALUES后面的值,需要用,隔开

3.4、修改

update

-- 修改学员名字
UPDATE `student` SET `name`='chan' WHERE id =1;

-- 不指定条件的情况下,会改动所有表
UPDATE `student` SET `name`='chan';

-- 修改多个属性,逗号隔开
UPDATE `student` SET `name`='chan',`email`='123@163.com' WHERE id =1;

语法:UPDATE 表名 set column_name = value,[cloumn_name = value,...] where [条件];

注意:

  • column_name是数据库的列,带上``
  • 条件,筛选的条件,如果没要指定,则会修改所有的列
  • value,是一个具体的值,也可以是一个变量
UPDATE `student` SET `birthday` = CURRENT_TIME WHERE `name`='chan' AND sex='男';

3.5、删除

delete

-- 删除数据
DELETE FROM `student`

-- 删除指定数据
DELETE FROM `student` WHERE id =1;

语法:delete from 表名[where 条件];

TRUNCATE

作用:完全清空一个数据库表,表的结构和索引约束不会变

-- 清空student表
TRUNCATE TABLE `student`;
  • 相同的:都能删除数据,不会删除表结构
  • 不同:
    • TRUNCATE 重新设置自增列 计数器会归零
    • TRUNCATE 不会影响事务

了解:DETELE删除的问题,重启数据库,现象

  • InnoDB 自增列会重1开始(存在内存当中的,断电即失)
  • MyISAM 继续从上一个自增量开始(存在文件中的,不会丢失)

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

4.1、DQL

  • 所有的查询操作都用它 Select
  • 简单的查询,复杂的查询都能做
  • 数据库中最核心的语言
  • 使用频率最高的语句

Select完整的语法:

SELECT

SELECT [ALL | DISTINCT]
{* | table.* | [table.field1[as lias1]],[table.field2[as lias2]],[....]}
FROM table_name [as table_alias]
	[left | right | inner join table_name2] -- 联合查询
	[WHERE ...] -- 指定结果需满足的条件
	[GROUP BY ...] -- 指定结果按照哪几个字段来分组
	[HAVING] -- 过滤分值的记录必须满足的次要条件
	[ORDER BY ...] -- 指定查询记录按一个或多个条件排序
	[LIMIT {[offset,]row_count | row_countOFFSET offset}];
	-- 指定查询的记录从哪条至哪条

注意:[]括号代表可选,{}括号代表必选

4.2、指定查询字段

-- 查询全部的学生 SELETE 字段 FROM 表
SELETE * FROM student

-- 查询指定字段
SELECT `studentNo`,`studentName` FROM student

-- 别名,给结果起一个名字 AS 可以给字段起别名,也可以给表起别名
SELECT `studentNo`, AS 学号 , `studentName` AS 学生姓名 FROM student AS s

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

语法:SELETE 字段,... FROM 表

有的时候,列名字不是那么的见名知意。我们起别名 AS – 字段名 as 别名 | 表名 as 别名

去重 distinct

作用:去除SELECT 查询出来的结果中重复的数据,重复的数据只显示一条

-- 查询一下有哪些同学参加了考试,成绩
SELECT * FROM result -- 查询全部的考试成绩
SELECT  `studentNo` FROM result -- 查询有哪些同学参加了考试
SELECT DISTINCT `studentNo` FROM result -- 发现重复数据,去重

数据库的列(表达式)

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


-- 学员考试成绩 +1 查看
SELECT studentNo`,studentResult`+1 AS '提分后' FROM result;

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

select 表达式 from 表

4.3、where条件字句

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

搜索条件由一个或多个表达式组成,结果为布尔值

逻辑运算符

运算符语法描述
and &&a and b a&&b逻辑与,两个都为真。结果为真
or ||a or b a||b逻辑或,一个为真,结果为真
Not !not a !a逻辑非,真为假,假为真

尽量使用英文字母

-- 查询考试成绩在95-100分之间
SELECT `studentNo` ,`studentResult` FROM result 
WHERE studentResult>=95 AND studentResult<100;

SELECT `studentNo` ,`studentResult` FROM result 
WHERE studentResult>=95 && studentResult<100;

-- 模糊查询 (区间)
SELECT `studentNo` ,`studentResult` FROM result 
WHERE  studentResult BETWEEN 95 AND 100;

-- 除了1000号学生之外的同学的成绩
SELECT `studentNo` ,`studentResult` FROM result 
WHERE studentNo != 1000;

SELECT `studentNo` ,`studentResult` FROM result 
WHERE NOT studentNo = 1000;

模糊查询:比较运算符

运算符语法描述
IS NULLa is null如果操作符为null,结果为真
IS NOT NULLa is not null如果操作符不为 null ,结果为真
BETWEENa between b and c若a 在 b和c之间,结果为真
Likea like bSQL匹配,如果a匹配到b,结果为真8
Ina in (a1,a2,a3…)假设a在a1,或者a2…其中的某一个值中,结果为真
-- =========== 模糊查询 ===========
-- 查询姓刘的同学
-- like结合 %(代表0到任意个字符)  _(一个字符)
SELECT `sutdentNo`,`studentName` FROM `student`
WHERE studentName LIKE '刘%';

-- 查询姓刘的同学,名字后面只有一个字的
SELECT `sutdentNo`,`studentName` FROM `student`
WHERE studentName LIKE '刘_';

-- 查询姓刘的同学,名字后面只有两个字的
SELECT `sutdentNo`,`studentName` FROM `student`
WHERE studentName LIKE '刘__';


-- 查询名字中间有嘉字的  %嘉%
SELECT `sutdentNo`,`studentName` FROM `student`
WHERE studentName LIKE '%嘉%';


-- ====== in (具体的一个或多个值)======
--  查询1001,1002,1003号学员
SELECT `sutdentNo`,`studentName` FROM `student`
WHERE studentNo IN (1001,1002,1003);

-- 查询在北京的学生
SELECT `sutdentNo`,`studentName` FROM `student`
WHERE `Address` IN ('安徽','河南洛阳');

-- ======= null    not null =======
-- 查询地址为空的学生 null ''
SELECT `sutdentNo`,`studentName` FROM `student`
WHERE address='' OR address IS NULL;

-- 查询有出生日期的同学,不为空
SELECT `sutdentNo`,`studentName` FROM `student`
WHERE `birthday` IS NOT NULL;

-- 查询没有出生日期的同学,为空
SELECT `sutdentNo`,`studentName` FROM `student`
WHERE `birthday` IS NULL;

4.4、联表查询

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-osxfjV47-1603975082603)(E:\桌面\images\image-20201018155502032.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HjgD37OY-1603975082605)(E:\桌面\images\timg.jpg)]

操作描述
Inner join如果表中至少有一个匹配,就返回行
left join会从左表中返回所有的值,即使右表中没有匹配(右表字段值返回为null)
right join会从右表中返回所有的值,即使左表中没有匹配(左表字段值返回为null)
-- ======== 联表查询 join =========

-- 查询参加了考试的同学(学号,姓名,科目编号,分数)
SELECT * FROM student;
SELECT * FROM result;

/* 思路
1.分析需求,分析查询的字段来自哪些表(连接查询)
2.确定使用哪种连接查询?7种
确定交叉带你(这两个表中哪个数据是相同的)
判断条件:学生表中 studentNo = 成绩表 studentNo
*/

-- join (连接的表) on (判断的条件) 连接查询
-- where 等值查询

SELECT s.studentNo,studentName,subjectNo,sutdentResult
FROM sutdent AS s
INNER JOIN result AS r
ON s.studentNo = r.studentNo;

-- Right Join 
SELECT s.studentNo,studentName,subjectNo,sutdentResult
FROM sutdent s
RIGHT JOIN result r
ON s.studentNo = r.studentNo;


-- Left Join 
SELECT s.studentNo,studentName,subjectNo,sutdentResult
FROM sutdent s
LEFT JOIN result r
ON s.studentNo = r.studentNo;


-- 查询缺考的同学
SELECT s.studentNo,studentName,subjectNo,sutdentResult
FROM sutdent s
LEFT JOIN result r
ON s.studentNo = r.studentNo
WHERE studentResult IS NULL;



-- 思考(查询了参加考试的同学信息:学号,学生姓名,科目名,分数)
/* 思路
1.分析需求,分析查询的字段来自哪些表,student ,result ,subject(连接查询)
2.确定使用哪种连接查询?7种
确定交叉带你(这两个表中哪个数据是相同的)
判断条件:学生表中 studentNo = 成绩表 studentNo
*/

SELECT s.studentNo,studentName,subjectName,sutdentResult
FROM sutdent s
LEFT JOIN result r
ON s.studentNo = r.studentNo
INNER JOIN `subject` sub
ON r.subjectNo=sub.subjectNo;



-- 我要查询哪些数据 select。。
-- 从哪几个表查 FROM 表 xxx join 连接的表  on  交叉条件
-- 假设存在一种多张表查询,慢慢来,先查询两张表然后再慢慢增加8

自连接

自己的表和自己连接,核心:一张表拆为两张一样的表即可

-- 查询父子信息:把一张表看为两个一模一样的表
SELECT a.`categoryName` AS '父栏目',b.`categoryName` AS '子栏目'
FROM `category` AS a ,`category` AS b
WHERE a.`categoryId` =b.`pid`;

4.5、分页和排序

排序

-- ================ 分页 limit 和 排序 order by ===============
-- ORDER BY 通过哪个字段排序,怎么排
-- 排序: 升序 ASC ,降序 DESC
SELECT s.studentNo,studentName,subjectName,sutdentResult
FROM sutdent s
LEFT JOIN result r
ON s.studentNo = r.studentNo
INNER JOIN `subject` sub
ON r.subjectNo=sub.subjectNo
ORDER BY  sutdentResult ASC;  -- or DESC


分页

-- 100万条数据
-- 为什么要分页?
-- 缓解数据库压力,给人体验更好   瀑布流

-- 分页,每页只显示五条数据
-- 语法:limit 起始页,页面的大小
-- 网页应用:当前,总的页数,页面的大小
-- LIMIT 0,5 1-5
-- LIMIT 1,5 2-6
-- LIMIT 6,5 7-11
SELECT s.studentNo,studentName,subjectName,sutdentResult
FROM sutdent s
LEFT JOIN result r
ON s.studentNo = r.studentNo
INNER JOIN `subject` sub
ON r.subjectNo=sub.subjectNo
ORDER BY  sutdentResult ASC
LIMIT 0,5;

-- 第一页,limit 0,5
-- 第二页,limit 5,5
-- 第三页,limit 10,5
-- 第n页, limit (n-1)*pagesize,pagesize
-- 【pagesize ;页面大小】
-- 【(n-1)*pagesize:起始值】
-- 【n:当前页】
-- 【数据总数/页面大小 = 总页数】向上取整

语法:limit(查询起始值下标,pagesize)

4.6、子查询

where(值是固定的)

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

where(子查询。。。)

理解:需要显示多个表数据用联表查询,只需一个表数据用子查询。

4.7、分组和过滤

-- 查询不同课程的平均分,最高分,最低分,平均分大于80
SELECT `subjectName`, AVG(studentResult), MAX(studentResult), MIN(studentResult)
FROM `result` r
INNER JOIN `subject` sub
ON r.`subjectNo`=sub.`subjectNo`
GROUP BY r.subjectNo -- 通过什么字段分组
HAVING AVG(studentResult)>80;

5、MySQL 函数

5.1、常用函数

-- 数学运算
SELECT ABS (-8) -- 绝对值
SELECT CEILING (9.4) -- 向上取整
SELECT FLOOR (9.4)-- 向下取整
SELECT RAND () -- 返回一个0*1之间的随机数
SELECT SIGN (-10) -- 判断一个数的符合 0-0  负数返回-1 ,正数返回1

-- 字符串函数
SELECT CHAR_LENGTH('毕业即失业') -- 字符串长度
SELECT CONCAT('我','没','工作') -- 拼接字符串
SELECT INSERT('helloword',1,2,'java') -- 查询,替换 从某个位置开始替换某个长度
SELECT LOWER ('Chan') -- 变成小写
SELECT UPPER ('chan') -- 变成大写
SELECT INSTR ('chan','c') -- 返回第一次出现的索引
SELECT REPLACE ('chan','ch','aa') -- 替换指定字符

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

-- 系统
SELECT SYSTEM_USER()
SELECT USER ()
SELECT VERSION ()

-- 数值函数
 abs(x)            -- 绝对值 abs(-10.9) = 10
 format(x, d)    -- 格式化千分位数值 format(1234567.456, 2) = 1,234,567.46
 ceil(x)            -- 向上取整 ceil(10.1) = 11
 floor(x)        -- 向下取整 floor (10.1) = 10
 round(x)        -- 四舍五入去整
 mod(m, n)        -- m%n m mod n 求余 10%3=1
 pi()            -- 获得圆周率
 pow(m, n)        -- m^n
 sqrt(x)            -- 算术平方根
 rand()            -- 随机数
 truncate(x, d)    -- 截取d位小数
 
 -- 时间日期函数
 now(), current_timestamp();     -- 当前日期时间
 current_date();                    -- 当前日期
 current_time();                    -- 当前时间
 date('yyyy-mm-dd hh:ii:ss');    -- 获取日期部分
 time('yyyy-mm-dd hh:ii:ss');    -- 获取时间部分
 date_format('yyyy-mm-dd hh:ii:ss', '%d %y %a %d %m %b %j');    -- 格式化时间
 unix_timestamp();                -- 获得unix时间戳
 from_unixtime();                -- 从时间戳获得时间
 
 -- 字符串函数
 length(string)            -- string长度,字节
 char_length(string)        -- string的字符个数
 substring(str, position [,length])        -- 从str的position开始,取length个字符
 replace(str ,search_str ,replace_str)    -- 在str中用replace_str替换search_str
 instr(string ,substring)    -- 返回substring首次在string中出现的位置
 concat(string [,...])    -- 连接字串
 charset(str)            -- 返回字串字符集
 lcase(string)            -- 转换成小写
 left(string, length)    -- 从string2中的左边起取length个字符
 load_file(file_name)    -- 从文件读取内容
 locate(substring, string [,start_position])    -- 同instr,但可指定开始位置
 lpad(string, length, pad)    -- 重复用pad加在string开头,直到字串长度为length
 ltrim(string)            -- 去除前端空格
 repeat(string, count)    -- 重复count次
 rpad(string, length, pad)    --在str后用pad补充,直到长度为length
 rtrim(string)            -- 去除后端空格
 strcmp(string1 ,string2)    -- 逐字符比较两字串大小

5.2、聚合函数

函数名称描述
COUNT()计数
SUM()求和
AVG()平均值
MAX()最大值
MIN()最小值
查询一个表中有多少记录
SELECT COUNT(`birthday`) FROM student;-- count(字段),会忽略所有的null值
SELECT COUNT(*) FROM student; -- count(*),不会忽略null值   本质:计算行数 查全部列
SELECT COUNT(1) FROM student; -- count(1),不会忽略null值   本质:计算行数 查第一列

5.3、数据库级别的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,'kuangshen','123456'),(2,'qinjiang','456789')
  
-- 如果我们要对pwd这一列数据进行加密,语法是:
update testmd5 set pwd = md5(pwd);

-- 如果单独对某个用户(如kuangshen)的密码加密:
INSERT INTO testmd5 VALUES(3,'kuangshen2','123456')
update testmd5 set pwd = md5(pwd) where name = 'kuangshen2';

-- 插入新的数据自动加密
INSERT INTO testmd5 VALUES(4,'kuangshen3',md5('123456'));
-- 查询登录用户信息(md5对比使用,查看用户输入加密后的密码进行比对)
SELECT * FROM testmd5 WHERE `name`='kuangshen' AND pwd=MD5('123456');

6、事务

6.1、什么是事务

要么都成功,要么都失败

什么是事务

  • 事务就是将一组SQL语句放在同一批次内去执行
  • 如果一个SQL语句出错,则该批次内的所有SQL都将被取消执行
  • MySQL事务处理只支持InnoDB和BDB数据表类型

6.2、事务的原则

事务的ACID原则 百度 ACID

原子性(Atomic)

  • 要么都成功,要么都失败。
  • 整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(ROLLBACK)到事务开始前的状态,就像这个事务从来没有执行过一样。

一致性(Consist)

  • 事务前后的数据完整性要保持一致。
  • 一个事务可以封装状态改变(除非它是一个只读的)。事务必须始终保持系统处于一致的状态,不管在任何给定的时间并发事务有多少。也就是说:如果事务是并发多个,系统也必须如同串行事务一样操作。其主要特征是保护性和不变性(Preserving an Invariant),以转账案例为例,假设有五个账户,每个账户余额是100元,那么五个账户总额是500元,如果在这个5个账户之间同时发生多个转账,无论并发多少个,比如在A与B账户之间转账5元,在C与D账户之间转账10元,在B与E之间转账15元,五个账户总额也应该还是500元,这就是保护性和不变性。

隔离性(Isolated)

  • 隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据

持久性(Durable)

  • 事务一旦提交则不可逆转,被持久化到数据库
  • 表示事务结束后的数据不会随着外界原因导致数据丢失
  • 在事务完成以后,该事务对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
  • 事务没有提交,恢复到原状
  • 事务已经提交,持久化到数据库

6.3、事务的隔离级别

脏读

指一个事务读取了另一个事务未提交的数据。

不可重复读

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

幻读

指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。

6.4、事务语法

基本语法

-- 使用set语句来改变自动提交模式
SET autocommit = 0;   /*关闭*/
SET autocommit = 1;   /*开启,默认*/

-- 注意:
--- 1.MySQL中默认是自动提交
--- 2.使用事务时应先关闭自动提交

-- 开始一个事务,标记事务的起始点
START TRANSACTION  

-- 提交一个事务给数据库
COMMIT

-- 将事务回滚,数据回到本次事务的初始状态
ROLLBACK

-- 还原MySQL数据库的自动提交
SET autocommit =1;

-- 保存点
SAVEPOINT 保存点名称 -- 设置一个事务保存点
ROLLBACK TO SAVEPOINT 保存点名称 -- 回滚到保存点
RELEASE SAVEPOINT 保存点名称 -- 删除保存点

测试

/*
课堂测试题目

A在线买一款价格为500元商品,网上银行转账.
A的银行卡余额为2000,然后给商家B支付500.
商家B一开始的银行卡余额为10000

创建数据库shop和创建表account并插入2条数据
*/

CREATE DATABASE `shop`CHARACTER SET utf8 COLLATE utf8_general_ci;
USE `shop`;

CREATE TABLE `account` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(32) NOT NULL,
`cash` DECIMAL(9,2) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO account (`name`,`cash`)
VALUES('A',2000.00),('B',10000.00)

-- 转账实现
SET autocommit = 0; -- 关闭自动提交
START TRANSACTION;  -- 开始一个事务,标记事务的起始点
UPDATE account SET cash=cash-500 WHERE `name`='A';
U PDATE account SET cash=cash+500 WHERE `name`='B';
COMMIT; -- 提交事务
# rollback;
SET autocommit = 1; -- 恢复自动提交

7、索引

MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。

7.1、索引的分类

  • 主键索引(PRIMARY KEY)
    • 唯一标识,不可重复
    • 最常见的索引类型
    • 确保数据记录的唯一性
    • 确定特定数据记录在数据库中的位置
  • 唯一索引 (UNIQUE KEY)
    • 避免同一个表中某数据列中的值重复
    • 可以多个列标识为唯一索引
  • 常规索引 (KEY/INDEX)
    • 默认的,index/key 关键字来设置
    • 快速定位特定数据,提高这个字段的查询效率
  • 全文索引 (FULLTEXT)
    • 快速定位数据
    • 只能用于CHAR , VARCHAR , TEXT数据列类型
    • 适合大型数据集
/*
#方法一:创建表时
    CREATE TABLE 表名 (
               字段名1 数据类型 [完整性约束条件…],
               字段名2 数据类型 [完整性约束条件…],
               [UNIQUE | FULLTEXT | SPATIAL ]   INDEX | KEY
               [索引名] (字段名[(长度)] [ASC |DESC])
               );


#方法二:CREATE在已存在的表上创建索引
       CREATE [UNIQUE | FULLTEXT | SPATIAL ] INDEX 索引名
                    ON 表名 (字段名[(长度)] [ASC |DESC]) ;


#方法三:ALTER TABLE在已存在的表上创建索引
       ALTER TABLE 表名 ADD [UNIQUE | FULLTEXT | SPATIAL ] INDEX
                            索引名 (字段名[(长度)] [ASC |DESC]) ;
                           
                           
#删除索引:DROP INDEX 索引名 ON 表名字;
#删除主键索引: ALTER TABLE 表名 DROP PRIMARY KEY;


#显示索引信息: SHOW INDEX FROM student;
*/

/*增加全文索引*/
ALTER TABLE `school`.`student` ADD FULLTEXT INDEX `studentname` (`StudentName`);

/*EXPLAIN : 分析SQL语句执行性能*/
EXPLAIN SELECT * FROM student WHERE studentno='1000';

/*使用全文索引*/
-- 全文搜索通过 MATCH() 函数完成。
-- 搜索字符串作为 against() 的参数被给定。搜索以忽略字母大小写的方式执行。对于表中的每个记录行,MATCH() 返回一个相关性值。即,在搜索字符串与记录行在 MATCH() 列表中指定的列的文本之间的相似性尺度。
EXPLAIN SELECT *FROM student WHERE MATCH(studentname) AGAINST('love');

/*
开始之前,先说一下全文索引的版本、存储引擎、数据类型的支持情况

MySQL 5.6 及以后的版本,MyISAM 和 InnoDB 存储引擎均支持全文索引;
只有字段的数据类型为 char、varchar、text 及其系列才可以建全文索引。
测试或使用全文索引时,要先看一下自己的 MySQL 版本、存储引擎和数据类型是否支持全文索引。
*/

7.2、索引原则

索引准则

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

索引的数据结构

-- 我们可以在创建上述索引的时候,为其指定索引类型,分两类
hash类型的索引:查询单条快,范围查询慢
btree类型的索引:b+树,层数越多,数据量指数级增长(我们就用它,因为innodb默认支持它)

-- 不同的存储引擎支持的索引类型也不一样
InnoDB 支持事务,支持行级别锁定,支持 B-tree、Full-text 等索引,不支持 Hash 索引;
MyISAM 不支持事务,支持表级别锁定,支持 B-tree、Full-text 等索引,不支持 Hash 索引;
Memory 不支持事务,支持表级别锁定,支持 B-tree、Hash 等索引,不支持 Full-text 索引;
NDB 支持事务,支持行级别锁定,支持 Hash 索引,不支持 B-tree、Full-text 等索引;
Archive 不支持事务,支持表级别锁定,不支持 B-tree、Hash、Full-text 等索引;

8、用户管理

使用SQLyog 创建用户,并授予权限演示

img

基本命令

/* 用户和权限管理 */ ------------------
用户信息表:mysql.user

-- 刷新权限
FLUSH PRIVILEGES

-- 增加用户 CREATE USER kuangshen IDENTIFIED BY '123456'
CREATE USER 用户名 IDENTIFIED BY [PASSWORD] 密码(字符串)
  - 必须拥有mysql数据库的全局CREATE USER权限,或拥有INSERT权限。
  - 只能创建用户,不能赋予权限。
  - 用户名,注意引号:如 'user_name'@'192.168.1.1'
  - 密码也需引号,纯数字密码也要加引号
  - 要在纯文本中指定密码,需忽略PASSWORD关键词。要把密码指定为由PASSWORD()函数返回的混编值,需包含关键字PASSWORD

-- 重命名用户 RENAME USER kuangshen TO kuangshen2
RENAME USER old_user TO new_user

-- 设置密码
SET PASSWORD = PASSWORD('密码')    -- 为当前用户设置密码
SET PASSWORD FOR 用户名 = PASSWORD('密码')    -- 为指定用户设置密码

-- 删除用户 DROP USER kuangshen2
DROP USER 用户名

-- 分配权限/添加用户
GRANT 权限列表 ON 表名 TO 用户名 [IDENTIFIED BY [PASSWORD] 'password']
  - all privileges 表示所有权限
  - *.* 表示所有库的所有表
  - 库名.表名 表示某库下面的某表

-- 查看权限   SHOW GRANTS FOR root@localhost;
SHOW GRANTS FOR 用户名
   -- 查看当前用户权限
  SHOW GRANTS; 或 SHOW GRANTS FOR CURRENT_USER; 或 SHOW GRANTS FOR CURRENT_USER();

-- 撤消权限
REVOKE 权限列表 ON 表名 FROM 用户名
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 用户名    -- 撤销所有权限

权限解释

-- 权限列表
ALL [PRIVILEGES]    -- 设置除GRANT OPTION之外的所有简单权限
ALTER    -- 允许使用ALTER TABLE
ALTER ROUTINE    -- 更改或取消已存储的子程序
CREATE    -- 允许使用CREATE TABLE
CREATE ROUTINE    -- 创建已存储的子程序
CREATE TEMPORARY TABLES        -- 允许使用CREATE TEMPORARY TABLE
CREATE USER        -- 允许使用CREATE USER, DROP USER, RENAME USER和REVOKE ALL PRIVILEGES。
CREATE VIEW        -- 允许使用CREATE VIEW
DELETE    -- 允许使用DELETE
DROP    -- 允许使用DROP TABLE
EXECUTE        -- 允许用户运行已存储的子程序
FILE    -- 允许使用SELECT...INTO OUTFILE和LOAD DATA INFILE
INDEX     -- 允许使用CREATE INDEX和DROP INDEX
INSERT    -- 允许使用INSERT
LOCK TABLES        -- 允许对您拥有SELECT权限的表使用LOCK TABLES
PROCESS     -- 允许使用SHOW FULL PROCESSLIST
REFERENCES    -- 未被实施
RELOAD    -- 允许使用FLUSH
REPLICATION CLIENT    -- 允许用户询问从属服务器或主服务器的地址
REPLICATION SLAVE    -- 用于复制型从属服务器(从主服务器中读取二进制日志事件)
SELECT    -- 允许使用SELECT
SHOW DATABASES    -- 显示所有数据库
SHOW VIEW    -- 允许使用SHOW CREATE VIEW
SHUTDOWN    -- 允许使用mysqladmin shutdown
SUPER    -- 允许使用CHANGE MASTER, KILL, PURGE MASTER LOGS和SET GLOBAL语句,mysqladmin debug命令;允许您连接(一次),即使已达到max_connections。
UPDATE    -- 允许使用UPDATE
USAGE    -- “无权限”的同义词
GRANT OPTION    -- 允许授予权限


/* 表维护 */

-- 分析和存储表的关键字分布
ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE 表名 ...
-- 检查一个或多个表是否有错误
CHECK TABLE tbl_name [, tbl_name] ... [option] ...
option = {QUICK | FAST | MEDIUM | EXTENDED | CHANGED}
-- 整理数据文件的碎片
OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ...

9、MySQL备份

数据库备份必要性

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

MySQL数据库备份方法

  • mysqldump备份工具
  • 数据库管理工具,如SQLyog
  • 直接拷贝数据库文件和相关配置文件

mysqldump客户端

作用 :

  • 转储数据库
  • 搜集数据库进行备份
  • 将数据转移到另一个SQL服务器,不一定是MySQL服务器

img

-- 导出
1. 导出一张表 -- mysqldump -uroot -p123456 school student >D:/a.sql
  mysqldump -u用户名 -p密码 库名 表名 > 文件名(D:/a.sql)
2. 导出多张表 -- mysqldump -uroot -p123456 school student result >D:/a.sql
  mysqldump -u用户名 -p密码 库名 表1 表2 表3 > 文件名(D:/a.sql)
3. 导出所有表 -- mysqldump -uroot -p123456 school >D:/a.sql
  mysqldump -u用户名 -p密码 库名 > 文件名(D:/a.sql)
4. 导出一个库 -- mysqldump -uroot -p123456 -B school >D:/a.sql
  mysqldump -u用户名 -p密码 -B 库名 > 文件名(D:/a.sql)

可以-w携带备份条件

-- 导入
1. 在登录mysql的情况下:-- source D:/a.sql
  source 备份文件
2. 在不登录的情况下
  mysql -u用户名 -p密码 库名 < 备份文件

10、三大范式

问题 : 为什么需要数据规范化?

不合规范的表设计会导致的问题:

  • 信息重复

  • 更新异常

  • 插入异常

    • 无法正确表示信息
  • 删除异常

    • 丢失有效信息

三大范式

第一范式 (1st NF)

第一范式的目标是确保每列的原子性,如果每列都是不可再分的最小数据单元,则满足第一范式

原子性:保证每一列不可再分

第二范式(2nd NF)

第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。

第二范式要求每个表只描述一件事情

第三范式(3rd NF)

如果一个关系满足第二范式,并且除了主键以外的其他列都不传递依赖于主键列,则满足第三范式.

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

规范化和性能的关系

为满足某种商业目标 , 数据库性能比规范化数据库更重要

在数据规范化的同时 , 要综合考虑数据库的性能

通过在给定的表中添加额外的字段,以大量减少需要从中搜索信息所需的时间

通过在给定的表中插入计算列,以方便查询

11、JDBC

url:mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=utf8&useSSL=true

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值