数据库

一.数据库基础

(一)数据库概念
数据库分类

关系型(用表格存储):MySql , qlServer, Orcle

非关系型(多用键值对存储):Redis,Mongodb

数据库管理系统(DBMS)

用于管理和操作数据库的大型软件,能建立,使用和维护数据库,对数据库进行统一管理和控制,以保证数据库的安全性和完整性。用户通过数据库管理系统访问数据库中表内的数据。

数据库管理系统与数据库,数据表的关系

数据库管理系统管理着多个数据库,一个数据库管理着多张数据表,一张表里面有很多数据

(二)mysql简介

关系型数据库;

以表格形式存储数据;

一个数据库中包含多张表;

(三)基本术语

主键:主键是唯一标识;一个数据表只有一个主键;可以使用主键查询数

据。

外键:用于关联两张表。

复合键:复合键(组合键)将多个列作为一个索引键,一般用于复合索引。

索引:索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可以提高查找效率。

(四)数据类型:
数值类型:

INT/INTEGER:4 Bytes

FLOAT : 4 Bytes

DOUBLE: 8 Bytes

日期类型:

DATE :日期类型,XXXX年XX月XX日

添加默认时间类型的配置:CURRENT_TIMESTAMP

字符串类型:

CHAR:定长字符串,长度一般是0~255

VARCHAR:可变长字符串

(五)命名规则
数据库命名:

英文字母大小写,数字或者下划线;

表命名:

英文字母大小写,数字或者下划线;禁止使用关键字

字段命名:

与表命名类似

(六)数据库的约束

对表中数据进行限制,保证数据正确性,有效性,完整性

约束种类:
主键约束:

唯一标识数据库中每一条数据(id字段类似身份证)

创建:用关键字primary key

PRIMARY KEY (字段名称)  --设置主键

特点:不重复,不为Null(所以通常设置为自动递增)

字段名称 字段类型(长度) AUTO_INCREMENT --设置自动递增

后续添加主键:

alter table 表名 add primary key (字段名称);

删除主键:

alter table 表名 drop primary key;

唯一约束:

表中某一列不能出现重复的值。

格式:字段名称 字段类型 UNIQUE

设置唯一约束

ALTER TABLE 表名 ADD UNIQUE KEY(字段名);
​
ALTER TABLE 表名 MODIFY 字段名 字段类型 UNIQUE;
​
非空约束:

表中某一列不为空

格式:字段名称 字段类型 NOT NULL

id INT(10) NOT NULL;
外键:

外键:在从表中与主表主键对应的那一列,如:用户表中的 roleid。

主表:用来约束别人的表,一方

从表(副表):被别人约束的表,多方

建表时添加外键

语法格式:[CONSTRAINT] [外键约束名称] FOREIGN KEY(外键字段名) REFERENCES 主表名(主键字段名);

CREATE TABLE if NOT EXISTS user_c(
id int(11) PRIMARY KEY auto_increment,
username VARCHAR(22),
password VARCHAR(255),
roleid int(11) NOT NULL,-- 外键对应着主表的主键
constraint roleid_fk foreign key (roleid) references rolelist(roleid)
)

已有表添加外键

ALTER TABLE 从表名称 ADD CONSTRAINT 外键名称 FOREIGN KEY (从表外键字段) REFERENCES 主表名称(主表主键);

删除外键

alter table 表名称 drop foreign key 外键名称;

外键级联

ON UPDATE TRUNCATE:级联更新,更新主表的主键,从表的外键也会同步更新

ON DELETE TRUNCATE:级联删除,删除从表中的与主表对应的数据,主表相应的数据也会被删除

外键删除与修改

CASCADE:父表delete、update的时候,子表会delete、update掉关联记录;

SET NULL:父表delete、update的时候,子表会将关联记录的外键字段所在列设为null,所以注意在设计子表时外键不能设为not null;

RESTRICT:如果想要删除父表的记录时,而在子表中有关联该父表的记录,则不允许删除父表中的记录;

NO ACTION:同 RESTRICT,也是首先先检查外键;

当创建外键约束之后,如果两个字段相互RESTRICT关联,这个时候想删除子表中被约束的数据,(例如:用户表中某用户的角色id为4,这个时候想删除这个角色表中的id为4的角色,直接删除就会出错,必须先删除用户表中被约束的数据,再去删除角色表中的数据)

默认值
id INT(10) NOT NULL DEFAULT 0;

二.数据库查询语句

(一)Mysql语法
  1. 每一条SQL语句都是以分号(英文状态)结束,但是在Navicat中是可以不加分号的;

  2. SQL中是不区分大小写,关键字中认为大小写一样;

  3. 注释:单行注释:--空格 多行注释:/* */

  4. 进入数据库:mysql -u root -p 密码

  5. 反引号``用于表名和字段名

  6. 字段是char 或者varchar时,插入值最好用单引号''

(二)数据库函数
标量函数
  1. UCASE() - 将某个字段转换为大写

    SELECT UCASE(username) FROM `user`
  2. LCASE() - 将某个字段转换为小写

  3. MID(字段,开始,长度) - 从某个文本字段提取字符

  4. LENGTH() - 返回某个文本字段的长度

    SELECT LENGTH(username) FROM `user`
  5. ROUND() - 对某个数值字段进行指定小数位数的四舍五入

    SELECT ROUND(openingprice) FROM gpinfoc
  6. NOW() - 返回当前的系统日期和时间

  7. FORMAT() - 格式化某个字段的显示方式timestampdiff()-时间差,例如:求年龄

    SELECT userid,username,DATE_FORMAT(NOW(),'%Y') - DATE_FORMAT(brithday,'%Y') 年龄 FROM user1;
    聚合函数

聚合函数是将“若干行数据”经过计算后聚合成“一行数据”,(不包含null数据)即空数据不包含在计算范围之内,所有需要注意使用ifnull()

  1. count(col): 表示求指定列的总行数,

  2. max(col): 表示求指定列的最大值

  3. min(col): 表示求指定列的最小值

  4. sum(col): 表示求指定列的和

  5. avg(col): 表示求指定列的平均值

(三)SQL语句
数据定义语句(DDL)

数据库定义语句用于建库建表

数据库创建与删除
-- 创建数据库 CREATE
CREATE DATABASE 库名
-- 删除数据库 DROP
DROP DATABASE 库名
-- 查看所有数据库 
show databases;
-- 查看一个数据库
show create database 库名;
-- 使用数据库
use 库名;
表的创建与删除与修改
-- 创建表
CREATE TABLE IF NOT EXITS 表名;
​
-- 创建表同时设置字段
CREATE TABLE IF NOT EXITS 表名{
    id INT (10),
    name VARCHAR(20) COMMENT '姓名', --COMMENT表示注释
    sex VARCHAR(3)
}
​
-- 添加字段 ADD
ALTER TABLE 表名 ADD 字段名 字段类型;
-- 删除字段 DROP
ALTER TABLE 表名 DROP 字段名;
-- 修改字段 MODIFY或者CHANGE
ALTER TABLE 表名 MODIFY 字段名 字段类型(长度);
ALTER TABLE 表名 CHANGE 原字段名 新字段名 新字段类型;
​
-- 删除数据表内容
TRUNCATE TABLE
数据查询语句(DQL)

用于查询数据

查询数据(SELECT)
-- 查询的语法格式
SELECT 查询列表 FROM 表名 WHERE 条件

(1)查询列表可以包括表中的字段、常量值(相当于增加一列常量值)、表达式、函数(求和);查询常量、表达式、函数时语句后面不用跟from 表名,因为它并不是表示来自哪个表。

(2)查询的结果是一个虚拟的表格

-- 查询表中所有信息
SELECT * FROM 表名;
-- 查询多个字段,用逗号隔开即可
SELECT 字段1,字段2,字段3 FROM  表名;
-- 用WHERE限制查询条件
SELECT * FROM 表名 WHERE 条件
-- 用LIMIT限制查询条数(限制为5条)
SELECT * FROM 表名 WHERE 条件 LIMIT 5
-- 用OFFSET限制偏移量(设置偏移量为2)
SELECT * FROM 表名 WHERE 条件 LIMIT 5 OFFSET 2
SELECT * FROM 表名 WHERE 条件 LIMIT 2,5 -- 与上一条语句是等价的
​
别名
-- 语法格式:SELECT 字段名 as "别名" FROM 表名
SELECT student_name as "姓名" FROM student
​
-- 也可以省略as(但不推荐这种用法)
SELECT student_name "姓名" FROM student
​
去重

查询book列表中得评分,但是我只想知道有哪些评分,查出来的话,会有一些评分重复.所以添加DISTINCT*,*进行去重

-- 语法格式:SELECT DISTINCT 字段名 FROM 表名
SELECT DISTINCT score FROM book
联合

unionunion all 的区别是,union 会自动压缩多个结果集合中的重复结果,而 union all 则将所有的结果全部显示出来,不管是不是重复。

SELECT score FROM book
UNION ALL
SELECT bookname FROM book
+的作用

在数据库中,+只表示相加

SELECT 122+20; -- 数值加法运算
SELECT "222"+20;  -- 其中一个是字符型,会试图将字符型数值转换成数值型,成功就做加法运算
SELECT "john"+20; -- 转化不了数值就直接转化为0
SELECT NULL+20;  -- 只有有一个字符为null,结果就是null

如果想将两个字段加在一起输出,使用concat方法

SELECT CONCAT(username,sex) FROM user1
查询条件

(1)添加查询条件用WHERE语句;

(2)查询条件不止一个的时候,可以用AND或者OR

(3)查询介于两个数值之间的数据用 BETWEEN AND

(4)判断某一个字段的值是否属于列表中的某一项用 IN,如果不在表中使用NOT IN。

(5)判断字段是否为空用 IS NULL,判断不为空用 IS NOT NULL

(6)可以用操作符(>,<,=,!=,>=,<=)来添加查询条件

-- 用WHERE添加查询条件
SELECT * FROM `user` WHERE username='cc'
-- 用AND 同时添加多个条件
SELECT * FROM   book WHERE score LIKE "9.%" AND translater ="无翻译"
-- 用OR添加多个条件,满足其中之一即可
SELECT * FROM cjb WHERE score >90 OR clazz=3
-- 用IN查询数据是否在某个字段中
SELECT * FROM cjb WHERE score in (90,89,99)
-- 用IS NULL 查询字段是否为空
SELECT age,name FROM stu WHERE money IS NULL;
-- 用 IS NOT NULL查询字段是否非空
SELECT age,name FROM stu WHERE money IS NOT NULL;
Like语句(模糊查询)

Like '字符串' ;其中_表示单个占位符;%表示多个占位符,如果没有使用占位符,LIKE与=的效果是一样的

-- 结果是只有一个字符的数据
SELECT book_name FROM book WHERE book_name LIKE '_' 
-- 结果是只有两个字符的数据,且第一个字符是三
SELECT book_name FROM book WHERE book_name LIKE '三_'  
-- 结果是第一个字符为三的数据
SELECT SELECT book_name FROM book WHERE book_name LIKE '三%' 
-- 结果是带有三的数据
SELECT SELECT book_name FROM book WHERE book_name LIKE '%三%' 
-- 结果是书名或者作者带有三的数据(查询结果有两列)
SELECT book_name,author FROM book WHERE CONCAT(book_name,author) LIKE '%三%'
排序

排序使用关键字ORDER BY;升序排序(ASC);倒序排序(DESC);默认是升序排序

-- 语法格式: ORDER   BY  字段名称   ASC/DESC    LIMIT  偏移量 ,限制条数
SELECT * FROM book ORDER BY score DESC LIMIT 1,10 -- 按照评分降序排序

在第一次排序的条件下,还可以进行二次排序

SELECT * FROM book ORDER BY score DESC ,space ASC LIMIT 1,10 -- 先按照评分降序排序,再按照价格升序排序
分组查询

注意:在mysql5.7之后的版本,MySQL默认开启了SQL_MODE[严格模式],对数据进行严格校验,所以需要修改一下配置,

修改配置文件my.ini

在[mysqld]模块下新增一行配置:

sql_mode='STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';

运行后重启,即可生效(net stop mysql)(net start mysql)

分组查询使用关键字 GROUP BY;语法格式: GROUP BY 分组字段

-- 结果是分组中的第一条数据(不严谨,因为评分8.6的书籍有8本,这个表中只有一本)
SELECT * FROM book  GROUP BY score  


 

在分组的列上我们可以使用 COUNT, SUM, AVG,聚合函数

-- 在班级的分组上加SUM求总分
SELECT name,SUM(score) FROM grade GROUP BY clazz
-- 在班级的分组上加AVG求平均分
SELECT name,AVG(score) FROM grade GROUP BY clazz

在分组之后添加条件用HAVING

​
-- 语法格式: SELECT 字段名 FROM  表名  GROUP BY 字段名 HAVING  条件-- 分组条件HAVING 
-- 在评分大于9.0的书籍中,相同出版社里面价格大于100的书籍
SELECT  * FROM book  WHERE score>9.0 GROUP BY press HAVING space>100
-- HAVING 是在分组的基础上进行的筛选,必须是分组里面有的字段,HAVING才能查到
SELECT  space FROM book  WHERE score>9.0 GROUP BY press HAVING space>100
​
SELECT  space,COUNT(space) FROM book  WHERE score>9.0 GROUP BY press HAVING space>100
-- HAVING后面可以加聚合函数
SELECT name, AVG(score) FROM cjb  GROUP BY `name` HAVING AVG(IFNULL(score,0))>80 ORDER BY AVG(IFNULL(score,0)) desc

having和where的区别:

  • 对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,即先过滤再分组;

  • where后面不可以使用聚合函数,having后面可以使用聚合函数。

  • having子句的作用是筛选满足条件的组,即在分组之后过滤数据,即先分组再过滤;

  • where在分组之前就会进行筛选,过滤掉的数据不会进入分组。

连接查询

内连接(等值连接):关键字INNER JOIN; 直接连接两张表,将两张表的数据生成笛卡尔积的数据

-- 查询test_user表和test_role表连接之后,roleid相等的数据,
SELECT * FROM test_user INNER JOIN test_role ON test_user.roleid=test_role.roleid
​
-- 可以使用WHERE添加条件
-- 查询roleid相等且都等于2的数据
SELECT * FROM test_user INNER JOIN test_role ON test_user.roleid=test_role.roleid WHERE test_user.roleid=2

左连接 :关键字LEFT JOIN; 会读取左边数据表的全部数据,即使右边表无对应数据(会将右边数据置为NULL)

-- 左连接 LEFT JOIN ON
SELECT * FROM test_user LEFT JOIN test_role ON test_user.roleid=test_role.roleid
​

右连接: 关键字RIGHT JOIN;会读取右边数据表的全部数据,即使右边表无对应数据(会将左边数据置为NULL)

-- 右连接 RIGHT JOIN
SELECT * FROM test_user RIGHT JOIN test_role ON test_user.roleid=test_role.roleid

隐式内连接与显式内连接
-- 隐式内连接
SELECT * FROM stu,sc WHERE s_id=s_no 
-- 显式内连接 
SELECT * FROM stu INNER JOIN sc ON s_id=s_no 

多连接查询
SELECT * FROM t_student stu INNER JOIN  t_subject sub ON stu.`subject_id` =sub.sub_id LEFT JOIN t_teacher tea ON tea.te_su_id =sub.sub_id
子查询

所谓子查询就是将查询结果作为其他查询的条件;条件分为单行单列(一个值),多行单列(结果集合)和多行多列(表,用于连接)

子查询的用法:使用括号作为子查询的范围

-- 单行单列子查询
-- SELECT book_name FROM book WHERE id=2 -- 作为查询条件
 SELECT * FROM book WHERE book_name=(SELECT book_name FROM book WHERE id=2) 
-- 多行单列子查询
 -- SELECT score FROM book WHERE space>100 GROUP BY score HAVING score>9 -- 作为查询条件
-- 
 SELECT * FROM book WHERE score IN (SELECT score FROM book WHERE space>100 GROUP BY score HAVING score>9)
-- 多行多列子查询
-- SELECT `name`,subject_id AS '课程id' FROM t_student -- 作为查询条件
​
SELECT * FROM t_subject sub RIGHT JOIN (SELECT `name`,subject_id AS '课程id' FROM t_student) AS stu ON stu.`课程id`=sub.sub_id
​
-- 别名的用法:(1)查询字段的别名,(2)结果数据的字段名称(可以调用),(3)表格使用别名
​
-- 例1
SELECT book_name "书名" (别名用法1)FROM book AS "书籍表" (别名用法3)WHERE 书籍表.score IN (SELECT score FROM book WHERE space>100 GROUP BY score HAVING score>9)
-- 例2
SELECT * FROM t_subject sub RIGHT JOIN (SELECT `name`,subject_id AS '课程id(别名用法1) FROM t_student) AS stu(别名用法2) ON stu.`课程id`=sub.sub_id
​
​
​

数据操纵语言(DML)

用于数据库增删改

插入数据(INSERT)
-- 添加数据 
--方式一(适用于字段比较少的情况)
INSERT INTO 表名(字段名1,字段名2,字段名3....) VALUES (值1,值2,值3....) -- 值要与字段对应
​
-- 例子:now() 获取当前时间
INSERT INTO `user` (`user`.username,`user`.`password`,`user`.creat_date) VALUES ("cc","1234",NOW())
​
​
--方式二
INSERT INTO 表名 VALUES (字段名1,字段名2,字段名3....)  -- 这种方式必须按顺序添加每一个字段
​
-- 例子:CURRENT_DATE通now()
INSERT INTO `user` VALUES(NULL,"cl","23423",CURRENT_DATE)
删除数据(DELETE)
-- 删除表中记录
DELETE FROM  表名 WHERE 条件
​
-- 用TRUNCATE也能删除数据,并且会全部删除
TRUNCATE 表名
​

delete,drop,truncate 都有删除表的作用,区别在于:

1、delete 和 truncate 仅仅删除表数据,drop 连表数据和表结构一起删除

2、delete 是 DML 语句,操作完后如果不想提交事务还可以回滚,truncate 和 drop 是 DDL 语句

3、执行的速度上,drop>truncate>delete

4、如果使用truncate进行删除记录,相当于删除表的结构,再创建一张表

逻辑删除与物理删除

逻辑删除并不是真正的删除,其本质是进行修改操作,是将表中对应的状态字段(status)进行修改。

物理删除就是真正意义上的清除,无法恢复。

修改数据(UPDATE)
-- 语法格式
UPDATE 表名 SET 字段名 = 新值 WHERE 更新条件;
-- 例子
UPDATE `user` SET username='cxkas' WHERE userId=3
-- 更新多个字段只需要在修改字段后面使用逗号隔开,写多个字段
-- 语法格式:UPDATE 表名 SET 字段名 = 数据,字段名=数据,... WHERE 条件
UPDATE `user` SET username='cxkas',`password`="jntm" WHERE userId=3
数据控制功能(DCL)

用于设置用户权限

(三) 数据库事务

事务概述

在mysql中,事务是一种机制、一个操作序列,是访问和更新数据库的程序执行单元。事务中包含一个或多个数据库操作命令,会把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么都执行,要么都不执行.

MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你既需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!

  • 在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。

  • 事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。

  • 事务用来管理 insert,update,delete 语句

事务的四大特性(AICD)
1.原子性(Atomicity)

事务的原子性是指事务必须是一个原子的操作序列单元事务中包含的各项操作要么都成功,要么都失败.失败的时候其它已经被执行的操作都将被撤销并回滚,只有所有的操作全部成功,整个事务才算是成功完成.

2.隔离性(Isolation)

事务的隔离性是指在并发环境中,并发的事务是互相隔离的,一个事务的执行不能被其它事务干扰。也就是说,不同的事务并发操作相同的数据时,每个事务都有各自完整的数据空间。一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务是不能互相干扰的

3.一致性(Consistency)

事务的一致性是指事务的执行不能破坏数据库数据的完整性和一致性,一个事务在执行之前和执行之后,数据库都必须处以一致性状态。比如:如果从A账户转账到B账户,不可能因为A账户扣了钱,而B账户没有加钱

4.持久性(Duration)

事务的持久性是指事务一旦提交后,数据库中的数据必须被永久的保存下来。即使服务器系统崩溃或服务器宕机等故障。只要数据库重新启动,那么一定能够将其恢复到事务成功结束后的状态

事务能保证AID,即原子性,隔离性,持久性。但是一致性无法通过事务来保证,一致性依赖于应用层,开发者

事务分类

事务分为隐式事务和显式事务;

隐式事务:在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作,这种事务就叫隐式事务。

显式事务:具有明显的开启和结束标记;即不会自动提交的事务。

-- 开始事务
START TRANSACTION
-- 执行sql语句
INSERT INTO stu VALUES(null,"zhangsan","2000-01-01 00:00:00","男")
-- 提交
COMMIT
-- 回滚:回滚就是不执行事务,回到事务执行前的状态
ROLLBACK

事务并发出现的问题
1.脏读

A事务更新了B事务尚未提交的数据,如果恰巧B事务回滚,那么A事务读到的数据是不被承认的。

解决办法:只允许更改已经提交的事务

2.不可重复度

A事务多次读取了B事务已经提交的更改数据,但每次读取的结果不一样,有可能是在多次读取之间,B事务对数据进行了更新。

解决办法:在读取某个数据的时候,不能进行更新操作

3.幻读

A事务读取B事务提交的新增数据,这时A事务将出现幻读的问题。例:事务A先读取了表的数据,然后事务B又往表中添加了几行数据,导致A事务再次读取表的时候,会发现表的数据发生了变化.就像发生了幻像一样。

解决办法:读取表的时候,不允许数据更新。

幻读和不可重复读很相似,不可重复读是针对于一条数据,而幻读是针对于多条数据

第一类丢失更新

A事务撤销时,把已经提交的B事务的更新数据覆盖了。

第二类丢失更新

A事务覆盖B事务已经提交的数据,造成B事务所做操作丢失.

事务隔离级别:

为了解决多个事务的并发问题,数据库系统提供了四种事务隔离级别供用户选择。

读未提交

允许事务读取未被其他事务提交的变更。(脏读、不可重复读和幻读的问题都会出现)

读已提交

只允许事务读取已经被其他事务提交的变更。(因为只能读取已经被提交的事务,所以就能避免因为读取没提交的数据而产生的脏读)

可重复读

确保事务可以多次从一个字段中读取相同的值,在这个事务持续期间,禁止其他事务对这个字段进行更新(update)。(可以避免脏读和不可重复读,但幻读仍然存在)

串行化(serializable)

确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作,所有并发问题都可避免,但性能十分低下(因为你不完成就都不可以弄,效率太低)

oracle默认的事务隔离级别是:读已提交

mysql的默认事务隔离级别是:可重复读:

mysql索引

索引可以大大提高MySQL的检索速度;索引分单列索引和组合索引。

单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。

组合索引,即一个索引包含多个列。

创建索引时,需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。

过多的使用索引将会造成滥用。因此索引也会有它的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。

建立索引会占用磁盘空间的索引文件。

单列索引
普通索引

MySQL中基本索引类型,没有什么限制,允许在定义索引的列中插入重复值和空值,纯粹为了查询数据更快一 点。

唯一索引

索引列中的值必须是唯一的,但是允许为空值。

主键索引

是一种特殊的唯一索引,不允许有空值。(主键约束,就是一个主键索引)。

组合索引

在表中的多个字段组合上创建的索引,只有在查询条件中使用了这些字段的左边字段时,索引才会被使用,使用组合索引时遵循最左前缀集合。

全文索引

全文索引,只有在MyISAM引擎上才能使用,只能在CHAR,VARCHAR,TEXT类型字段上使用全文索引.

索引数据结构

索引的数据结构使用的是B+树

B+树:只有叶子节点才会存储数据,非叶子节点至存储键值。叶子节点之间使用双向指针连接,最底层的叶子节点形成了一个双向有序链表

[B+树原理]  https://mp.weixin.qq.com/s?__biz=MzU0OTE4MzYzMw==&amp;mid=2247505924&amp;idx=4&amp;sn=eae493ee38fdd204c3524af22fefdf2c&amp;chksm=fbb151faccc6d8ec52026c9393316a5384765caa34828213b4db5e45886c26004162db985633&amp;scene=27 

mysql视图

视图是基于sql语句结果集的可视化的表,视图只是用来查看存储在别处的数据的设施,本身不包含数据,返回的数据也是从其他表检索出来的。

-- CREATE VIEW <视图名> AS (SELECT语句)
​
-- 查看视图
select * from 视图名

mysql触发器

触发器(TRIGGER)是由事件来触发某个操作。这些事件包括insert语句、update语句和delete语句。当数据库系统执行这些事件时,就会激活触发器执行相应的操作。类似于监听器。

CREATE TRIGGER  -- 触发器名称
BEFORE/AFTER  -- (二选一,表示在事件之前执行还是事件之后执行)
UPDATE/INSERT/DELETE -- (三选一,指定在什么事件触发触发器,即增,删,改)
ON 表名称 
FOR EACH ROW  -- (影响所有行) 
#触发器主体
sql语句;
-- 创建触发器   此触发器作用:在对user表执行修改操作的时候执行对gxtime表的添加操作
create trigger t1 before update on user for each row insert into gxtime values(now());

数据库备份与还原

备份:DOS系统下,未登录的时候,cmd

-- 输入以下命令进行保存sql文件: mysqldump -uroot -p密码 数据库名称>保存地址及名称
​
mysqldump -uroot -proot sqlstudy>D:/Desktop/demo.sql

还原:第一步先将数据库的表都删除掉,因为生成的sql文件是不会建数据库的,所以数据库不用删

登录数据库:
mysql -uroot -proot
​
还原到数据库:
mysql -uroot -proot sqlstudy<D:/Desktop/demo.sql

范式

规范的数据库需要满足一些规则来优化数据的设计和存储,这些规则就称为范式。

三大范式
  1. 第一范式(1NF):数据库表的每一列都是不可分割的原子数据项,不能是集合、数组等非原子数据项。即表中的某个列有多个值时,必须拆分为不同的列。简而言之,第一范式每一列不可再拆分,称为原子性。

  2. 第二范式(2NF):在满足第一范式的前提下,表中的每一个字段都完全依赖于主键。谓完全依赖是指不能存在仅依赖主键一部分的列。

  3. 第三范式(3NF):在满足第二范式的前提下,表中的每一列都直接依赖于主键,而不是通过其它的列来间接依赖于主键。

更多推荐