跳转到内容

搜索仅适用于生产版本。 尝试构建并预览网站以在本地测试。

MySQL 学习笔记

​ DataBase(DB)。按照一定格式存储数据的一些文件的组合。

​ 顾名思义:存储数据的仓库,实际上就是一堆文件,这些文件中存储了具有特定格式的数据。

​ 数据库中最基本的单元是表:table

​ 任何一张表都有行和列:

​ 行(row):被称为数据/记录

​ 列(column):被称为字段(每个字段有字段名、数据类型、约束等属性)

​ DataBaseManagement(DBMS)。数据库管理系统是专门用来管理数据库中的数据的,数据库管理系统可以对数据当中的数据进行增删改查。

​ 常见的数据库管理系统:MySQL、Oracle、MS SqlServer、DB2、sybase等

​ 一套标准语言,在数据库管理系统中使用。

​ 结构化查询语言,通过编写SQL语句,然后DBMS负责执行SQL语句,最终来完成数据库中的增删改查。

​ DBMS-->执行-->SQL-->操作-->DB

​ MySQL服务启动

​ 在cmd命令中输入:

net stop MySQL
net start MySQL
模板:
net start [服务名称]
net stop [服务名称]
mysql -u root -p
exit
show databases;
use [数据库名称];
create database [数据库名称];
show tables;
select version();
select database();
\c
source [sql路径];
desc [表名];
describe [表名];

​ SQL语句有很多,分为:

  • DQL:数据库查询语言,含有select关键字
  • DML:数据库操作语言,主要操作表中的数据
    • insert
    • delete
    • update
  • DDL:数据定义语言,create、drop、alter,主要操作表的结构
  • TCL:事务控制语言,事务提交(commit)和事务回滚(rollback)
  • DCL:数据控制语言,如授权grant、撤销授权revoke。。。

​ 查询一个字段:select 字段名 from 表名;

​ 其中要注意:1、select和from都是关键字。

​ 2、字段名和表名都是标识符

​ 强调:

​ 1. 对于SQL语句来说,是通用的。

​ 2. 所有的SQL语句以“;”结尾。

​ 3. 另外SQL语句不区分大小写,都行。

​ 查询两个字段,或者多个字段:使用逗号隔开“,”。

  • 可以把每个字段都写上   select a,b,c,d,e,f... from tablename;

  • 使用*, 这种方式的缺点: 1. 效率低;2. 可读性差。

    ​ 因此,在实际开发中不建议使用,可以在DOS命令窗口中想快速的看一看全表数据可以采用这种方式。

​ 使用as关键字,as可以省略

select [字段名] as [别名] from [表名];

​ 注意:只是将显示的查询结果列名显示为【别名】,原表列名不变。   记住:select语句是永远都不会进行修改操作的。(因为只负责查询)。

​ 假设起别名的时候,别名里面有空格时,在别名处加上单引号或者双引号

语法格式:

select
字段1,字段2,字段3....
from
表名
where
条件;

条件需要放到where语句后。支持的运算符:

转移字符:\

​ 排序采用 order by 子句,order by 后面跟上排序字段,排序字段可以放多个,多个采用逗号间隔,默认采用升序。如果存在 where 子句,那么 order by 必须放到 where 语句的后面。

​ 默认为升序,asc

​ 降序,desc

​ 如果采用多个字段排序,如果根据第一个字段排序重复了,会根据第二个字段排序。

select
...
from
...
where
...
order by
...

​ 数据处理函数又被称为单行处理函数。单行处理函数的特点:一个输入对应一个输出。

  和单行处理函数相对的是:多行处理函数。(多行处理函数特点:多个输入,对应1个输出!)

concat函数:进行字符串的拼接

trim函数:去首尾空格,不会去除中间的空格

str_to_date函数:

date = str_to_date('1981-02-20','%Y-%m-%d');
date = str_to_date('02-20-1981','%m-%d-%Y');

date_format函数:

date_format(date, '%Y-%m-%d %H:%i:%s');
日期格式的说明:%Y:代表 4 位的年份
          %y:代表 2 位的年份
          %m:代表月, 格式为(01……12)
          %c:代表月, 格式为(1……12)
          %H:代表小时,格式为(00……23)
          %h: 代表小时,格式为(01……12)
          %i: 代表分钟,格式为(00……59)
          %r:代表 时间,格式为 12 小时(hh:mm:ss [AP]M)
          %T:代表 时间,格式为 24 小时(hh:mm:ss)
          %S:代表 秒,格式为(00……59)
          %s:代表 秒,格式为(00……59)

format函数:设置千分位Format([字段],0)

​ 保留小数位,以两位小数为例:Format([字段],2)

round函数:四舍五入

ifnull函数:将null转化为一个具体值,ifnull([字段],[转化值])

select后面可以跟某个表的字段名(可以等同看做变量名),也可以跟字面量/字面值

在所有数据库当中,只要有NULL参与的数学运算,最终结果就是NULL。

case进行匹配,when后接条件,then后接操作

​ 分组函数又称为多行处理函数。

​ 多行处理函数的特点:输入多行,最终输出一行。

​ 注意:1、分组函数在使用的时候必须先进行分组,然后才能用。如果没有对数据进行分组,整张表默认为一组。

​ 2、分组函数自动忽略空值,不需要手动的加 where 条件排除空值。

​ 3、分组函数不能直接使用在 where 关键字后面。

  • 分组函数自动忽略NULL,你不需要提前对NULL进行处理。
  • count(*):统计表当中的总行数。(只要有一行数据count则++,因为每一行记录不可能都为NULL,一行数据中有一列不为NULL,则这行数据就是有效的。) count(具体字段):表示统计该字段下所有不为NULL的元素的总数。
  • 分组函数不能够直接使用在where子句中。
  • 所有的分组函数可以组合起来一起用。

​ 分组查询主要涉及到两个子句,分别是:group byhaving。   在实际的应用中,可能有这样的需求,需要先进行分组,然后对每一组的数据进行操作,这个时候我们需要使用分组查询。

重点结论: 在一条select语句当中,如果有group by语句的话,select后面只能跟参加分组的字段以及分组函数,其它的一律不能跟。

​ 如果想对分组数据再进行过滤需要使用 having 子句。使用having可以对分完组之后的数据进一步过滤。having不能单独使用,having不能代替wherehaving必须和group by联合使用。

分组函数的执行顺序:1、根据条件查询数据;2、分组;3、采用having 过滤,取得正确的数据。

一个完整的select语句格式如下:

select 字段
from 表名
where ……
group by ……
having ……(就是为了过滤分组后的数据而存在的,不可以单独的出现)
order by ……

 以上语句的执行顺序:

​ 1、首先执行 from 从某种表中查询数据;

​ 2、执行 where 语句过滤原始数据;

​ 3、执行 group by 进行分组;

​ 4、执行 having 对分组数据进行操作;

​ 5、执行 select 选出数据;

​ 6、执行 order by 排序。

原则:1、能在 where 中过滤的数据,尽量在 where 中过滤,效率较高。

​ 2、having 的过滤是专门对分组之后的数据进行过滤的。

distinct:把查询结果去除重复记录。注意:原表数据不会被修改,只是查询结果去重。(distinct只能出现在所有字段的最前方

​ 从一张表中单独查询,称为单表查询。跨表查询,多张表联合起来查询数据,被称为连接查询

  • 根据语法的年代分类:

    SQL92:1992年的时候出现的语法 SQL99:1999年的时候出现的语法(重点)

  • 根据表连接的方式分类:

    • 内连接

      等值连接

      非等值连接

      自连接

    • 外连接

      左外连接

      右外连接

    • 全连接

​ 当两张表进行连接查询,没有任何条件限制的时候,最终查询结果条数,是两张表条数的乘积,这种现象被称为:笛卡尔积现象

注意: 通过笛卡尔积现象得出,表的连接次数越多,效率越低,所以要尽量避免表的连接次数。

​ 条件是等量关系。

  • SQL92语法
select
e.ename,d.dname
from
emp e, dept d
where
e.deptno = d.deptno;

SQL92的缺点:结构不清晰,表的连接条件和后期进一步筛选的条件,都放到了where后面。

  • SQL99语法
select
e.ename,d.dname
from
emp e
join
dept d
on
e.deptno = d.deptno;

也可以写成

select
e.ename,d.dname
from
emp e
inner join //inner可以省略(带着inner可读性更好!!!一眼就能看出来是内连接)
dept d
on
e.deptno = d.deptno; // 条件是等量关系,所以被称为等值连接。

SQL99的优点:表连接的条件是独立的,连接之后,如果还需要进一步筛选,再往后继续添加where

SQL99的语法:

select
...
from
a
join
b
on
a和b的连接条件
where
筛选条件

条件不是等值

技巧: 一张表看成两张表。

“自连接”:只有一张表连接,具体的查询方法,把一张表看作两张表即可。

​ 带有right的是右外连接,又叫做右连接。   带有left的是左外连接,又叫做左连接。LEFT JOIN 关键字会从左表那里返回所有的行,即使在右表中没有匹配的行。   任何一个右连接都有左连接的写法,任何一个左连接都有右连接的写法。

​ 左外连接(左连接)和右外连接(右连接)的区别:左连接以左面的表为准和右边的表比较,和左表相等的不相等都会显示出来,右表符合条件的显示,不符合条件的不显示;右连接恰恰相反。

语法:

select
...
from
a
join
b
on
a和b的连接条件
join
c
on
a和c的连接条件
right join
d
on
a和d的连接条件

子查询就是嵌套的 select 语句,可以理解为子查询是一张表。 ​ select语句中嵌套select语句,被嵌套的select语句称为子查询。

语法:

select
..(select).
from
..(select).
where
..(select).
  • where中的子查询:在 where 语句中使用子查询,也就是在 where 语句中加入 select 语句。
  • from中的子查询:在 from 语句中使用子查询,可以将该子查询的查询结果看做一张临时表。
  • select中的子查询:对于select后面的子查询来说,这个子查询只能一次返回1条结果,多于1条,就报错了。

union合并查询结果集。 ​ union 可以合并集合(相加)

union的效率要高一些。对于表连接来说,每连接一次新表,则匹配的次数满足笛卡尔积,成倍的翻。但是union可以减少匹配的次数。在减少匹配次数的情况下,还可以完成两个结果集的拼接。

注意事项

  • union在进行结果集合并的时候,要求两个结果集的列数相同。
  • MySQL可以,oracle语法严格 ,不可以,报错。要求:结果集合并时列和列的数据类型也要一致。

​ MySQL 提供了 limit,主要用于提取前几条或者中间某几行数据。

​ 例如,select * from table limit m,n ,其中 m 是指记录开始的 index,从 0 开始,表示第一条记录;n 是指从第 m+1 条开始,取 n 条

​ select * from tablename limit 2,4 即取出第 3 条至第 6 条,4 条记录。 ​ limit 的作用:将查询结果集的一部分取出来,通常使用在分页查询当中。分页的作用是为了提高用户的体验,因为一次全部都查出来,用户体验差。

  • 完整用法:limit startIndex, length      startIndex是起始下标,length是长度。      起始下标从0开始。
  • 缺省用法:limit 5; 这是取前5。

  ★ 每页显示3条记录    ⋄ 第1页:limit 0,3 [0 1 2]    ⋄ 第2页:limit 3,3 [3 4 5]    ⋄ 第3页:limit 6,3 [6 7 8]    ⋄ 第4页:limit 9,3 [9 10 11]

  ★ 每页显示pageSize条记录    ⋄ 第pageNo页:limit (pageNo - 1) * pageSize , pageSize

select
...
from
...
where
...
group by
...
having
...
order by
...
limit
...

执行顺序:

  1. from

           2. where        3. group by        4. having        5. select        6. order by        7. limit

​ 建表的语法格式:(建表属于DDL语句,DDL包括:create drop alter)

create table 表名(
字段名1 数据类型,
字段名2 数据类型,
字段名3 数据类型
);

​ 表名: 建议以 t_ 或者 tbl_ 开始,可读性强,见名知意。   字段名: 见名知意。   表名和字段名都属于标识符。

  创建表的时候,表中有字段,每一个字段有:字段名、字段数据类型、字段长度限制、字段约束

varchar(最长255):可变长度的字符串。          比较智能,节省空间。          会根据实际的数据长度动态分配空间。

优点: 节省空间。 缺点: 需要动态分配空间,速度慢。

char(最长255):定长字符串。        不管实际的数据长度是多少,分配固定长度的空间去存储数据。使用不恰当的时候,可能会导致空间的浪费。

  优点: 不需要动态分配空间,速度快。   缺点: 使用不当可能会导致空间的浪费。

int(最长11):数字中的整数型。等同于java的int。

bigint:数字中的长整型。等同于java中的long。

float:单精度浮点型数据。

double:双精度浮点型数据。

date:短日期类型。

datetime:长日期类型。

clob:字符大对象(Character Large OBject)。     最多可以存储4G的字符串。比如:存储一篇文章,存储一个说明。     超过255个字符的都要采用CLOB字符大对象来存储。

blob:二进制大对象(Binary Large OBject)。      专门用来存储图片、声音、视频等流媒体数据。      往BLOB类型的字段上插入数据的时候,例如插入一个图片、视频等,需要使用IO流才行。

create table [表1] as select * from [表2];

**原理:**将一个查询结果当做一张表新建!

​ 这个可以完成表的快速复制!

​ 表创建出来,同时表中的数据也存在了!

drop [表名]
delete from [表名]
  • delete语句删除数据的原理:(delete属于DML语句!)  ⋄ 表中的数据被删除了,但是这个数据在硬盘上的真实存储空间不会被释放!  ⋄ 这种删除缺点是:删除效率比较低。  ⋄ 这种删除优点是:支持回滚,后悔了可以再恢复数据!
  • truncate语句删除数据的原理:(truncate属于DDL操作)  ⋄ 这种删除效率比较高,表被一次截断,物理删除。  ⋄ 这种删除缺点:不支持回滚。  ⋄ 这种删除优点:快速。
truncate table [表名];//truncate是删除表中的数据,表还在!
insert into 表名(字段名1,字段名2,字段名3...) values(值1,值2,值3);
insert into t_user(字段名1,字段名2) values(值1,值2),(值1,值2),(值1,值2),(值1,值2);
insert into [表1] select * from [表2];

注意:

​ 1、insert语句但凡是执行成功了,那么必然会多一条记录。

​ 2、没有给其它字段指定值的话,默认值是NULL。

update 表名 set 字段名1=值1,字段名2=值2,字段名3=值3... where 条件;

注意: 没有条件限制会导致所有数据全部更新。

delete from 表名 where 条件;

注意: 没有条件,整张表的数据会全部删除!

​ 约束对应的英语单词:constraint。 ​ 在创建表的时候,我们可以给表中的字段加上一些约束,来保证这个表中数据的完整性、有效性!   约束的作用就是为了保证表中的数据有效!

  • 非空约束:not null,约束的字段不能为NULL。 not null只有列级约束,没有表级约束!

  • 唯一性约束:unique,约束的字段不能重复,但是可以为NULL。

  • 主键约束: primary key (简称PK)

    • 主键约束: 就是一种约束

    • 主键字段: 该字段上添加了主键约束,这样的字段叫做主键字段

    • 主键值: 主键字段中的每一个值都叫做主键值。

    每个表应该具有主键,主键可以标识记录的唯一性,主键分为单一主键和复合(联合)主键,单一主键是由一个字段构成的,复合(联合)主键是由多个字段构成的。

    主键:每一行记录的唯一标识。一张表,主键约束只能添加1个(主键只能有1个)主键值建议使用int、bigint、char等类型,不建议使用varchar来做主键。主键值一般都是数字,一般都是定长的。

    主键分类:

    • 单一主键:由一个字段构成。
    • 复合主键: 由多个字段构成。
    • 自然主键:主键值是一个自然数,和业务没关系。
    • 业务主键:主键值和业务紧密关联,例如拿银行卡账号做主键值。

    在mysql当中,有一种机制,可以帮助我们自动维护一个主键值。auto_increment表示自增,从1开始,以1递增。

  • 外键约束:foreign key(简称FK)

    • 外键约束: 一种约束(foreign key)。
    • 外键字段: 该字段上添加了外键约束。
    • 外键值: 外键字段当中的每一个值。

    外键主要是维护表之间的关系的,主要是为了保证参照完整性,如果表中的某个字段为外键字段,那么该字段的值必 须来源于参照的表的主键。

  • 检查约束:check(mysql不支持,oracle支持)

  存储引擎是MySQL中特有的一个术语,其它数据库中没有。(Oracle中有,但是不叫这个名字)   存储引擎是一个表存储/组织数据的方式。不同的存储引擎,表存储数据的方式不同。

​ 展示创建表 t_student 时的mysql语句:show create table t_student;

​ 在建表的时候可以在最后小括号的“)“的右边使用:ENGINE来指定存储引擎;CHARSET来指定这张表的字符编码方式。建表时指定存储引擎,以及字符编码方式。

  结论: mysql默认的存储引擎是:InnoDB       mysql默认的字符编码方式是:utf8

CREATE TABLE `t_student` (
`no` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`cno` int(11) DEFAULT NULL,
PRIMARY KEY (`no`),
KEY `cno` (`cno`),
CONSTRAINT `t_student_ibfk_1` FOREIGN KEY (`cno`) REFERENCES `t_class` (`classno`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8

​ 查看mysql支持哪些存储引擎:show engines \G

  • MyISAM存储引擎 它管理的表具有以下特征:

    • 使用三个文件表示每个表:

    • 格式文件 — 存储表结构的定义(mytable.frm)

    • 数据文件 — 存储表行的内容(mytable.MYD)

    • 索引文件 — 存储表上索引(mytable.MYI):索引是一本书的目录,缩小扫描范围,提高查询效率的一种机制。

    • 可被转换为压缩、只读表来节省空间 注意:对于一张表来说,只要是主键,或者加有unique约束的字段上会自动创建索引。 MyISAM存储引擎的特点:可被转换为压缩、只读表来节省空间。 MyISAM不支持事务机制,安全性低。

  • InnoDB存储引擎 这是mysql默认的存储引擎,同时也是一个重量级的存储引擎。 InnoDB支持事务,支持数据库崩溃后自动恢复机制。 InnoDB存储引擎最主要的特点:非常安全。 它管理的表具有下列主要特征:

    • 每个 InnoDB 表在数据库目录中以.frm 格式文件表示   - InnoDB 表空间 tablespace 被用于存储表的内容(表空间是一个逻辑名称。表空间存储数据+索引。)   - 提供一组用来记录事务性活动的日志文件   - 用 COMMIT(提交)、SAVEPOINT 及ROLLBACK(回滚)支持事务处理   - 提供全 ACID 兼容   - 在 MySQL 服务器崩溃后提供自动恢复   - 多版本(MVCC)和行级锁定   - 支持外键及引用的完整性,包括级联删除和 InnoDB最大的特点就是支持事务,以保证数据的安全。效率不是很高,并且也不能压缩,不能转换为只读,不能很好的节省存储空间。
  • MEMORY存储引擎 使用 MEMORY 存储引擎的表,其数据存储在内存中,且行的长度固定,这两个特点使得 MEMORY 存储引擎非常快。 MEMORY 存储引擎管理的表具有下列特征:

    • 在数据库目录内,每个表均以.frm 格式的文件表示。

    • 表数据及索引被存储在内存中。(目的就是快,查询快!)

    • 表级锁机制。

    • 不能包含 TEXT 或 BLOB 字段。

    MEMORY 存储引擎以前被称为 HEAP 引擎。 MEMORY引擎的优点:查询效率是最高的,不需要和硬盘交互。 MEMORY引擎的缺点:不安全,关机之后数据消失,因为数据和索引都是在内存当中。

  一个事务其实就是一个完整的业务逻辑,是一个最小的工作单元,不可再分。

​ 什么是一个完整的业务逻辑:假设转账,从A账户向B账户中转账10000,将A账户的钱减去10000(update语句),将B账户的钱加上10000(update语句),这就是一个完整的业务逻辑。

  以上的操作是一个最小的工作单元,要么同时成功,要么同时失败,不可再分。这两个update语句要求必须同时成功或者同时失败,这样才能保证钱是正确的。

​ 只有DML语句才会有事务这一说,其它语句和事务无关。因此,只有insert、delete、update这三个语句和事务有关系,其它都没有关系。因为只有以上的三个语句是数据库表中数据进行增、删、改的。   只要操作一旦涉及到数据的增、删、改,那么就一定要考虑安全问题,数据安全第一位!

事务: 就是批量的DML语句同时成功,或者同时失败!

​ InnoDB存储引擎提供一组用来记录事务性活动的日志文件。

​ 在事务的执行过程中,每一条DML的操作都会记录到“事务性活动的日志文件”中。   在事务的执行过程中,我们可以提交事务,也可以回滚事务。

  提交事务: 清空事务性活动的日志文件,将数据全部彻底持久化到数据库表中。提交事务标志着,事务的结束,并且是一种全部成功的结束。commit; 语句

  回滚事务: 将之前所有的DML操作全部撤销,并且清空事务性活动的日志文件。回滚事务标志着,事务的结束,并且是一种全部失败的结束。rollback; 语句(回滚永远都是只能回滚到上一次的提交点!)

自动提交:每执行一条DML语句,则提交一次!(关闭自动提交机制:start transaction;

  • 回滚事务:先执行命令start transaction;,直接rollback回滚即可。
  • 提交事务:先执行命令start transaction;,输入SQL语句,然后commit即可。
  • 原子性

    说明事务是最小的工作单元,不可再分。

  • 一致性 所有事务要求,在同一个事务当中,所有操作必须同时成功,或者同时失败,以保证数据的一致性。

  • 隔离性 A事务和B事务之间具有一定的隔离。

    隔离级别:

    • 读未提交: read uncommitted(最低的隔离级别),即没有提交就读到。

      • 什么是读未提交?事务A可以读取到事务B未提交的数据。
      • 这种隔离级别存在的问题就是:脏读现象(Dirty Read)!我们称读到了脏数据。
      • 这种隔离级别一般都是理论上的,大多数的数据库隔离级别都是二档起步!
    • 读已提交: read committed,即提交之后才能读到。

      • 什么是读已提交?事务A只能读取到事务B提交之后的数据。
      • 这种隔离级别解决了什么问题?解决了脏读的现象。
      • 这种隔离级别存在什么问题?不可重复读取数据。
      • 什么是不可重复读取数据呢?在事务开启之后,第一次读到的数据是3条,当前事务还没有结束,可能第二次再读取的时候,读到的数据是4条,3不等于4称为不可重复读取。
      • 这种隔离级别是比较真实的数据,每一次读到的数据是绝对的真实。
      • oracle数据库默认的隔离级别是:read committed。
    • 可重复读: repeatable read,即提交之后也读不到,永远读取的都是刚开启事务时的数据。

      • 什么是可重复读取?事务A开启之后,不管是多久,每一次在事务A中读取到的数据都是一致的。即使事务B将数据已经修改,并且提交了,事务A读取到的数据还是没有发生改变,这就是可重复读。
      • 可重复读解决了什么问题?解决了不可重复读取数据。
      • 可重复读存在的问题是什么?可能会出现幻影读。每一次读取到的数据都是幻象,不够真实!早晨9点开始开启了事务,只要事务不结束,到晚上9点,读到的数据还是那样!读到的是假象,不够绝对的真实。
      • mysql中默认的事务隔离级别就是这个!
    • 序列化/串行化: serializable(最高的隔离级别),这是最高隔离级别,效率最低。

      • 解决了所有的问题。
      • 这种隔离级别表示事务排队,不能并发!
      • 类似于synchronized,线程同步(事务同步)
      • 每一次读取到的数据都是最真实的,并且效率是最低的。
  • 持久性 事务最终结束的一个保障。事务提交,就相当于将没有保存到硬盘上的数据保存到硬盘上!

    select @@tx_isolation
    set global transaction isolation level read [级别];//设置完后退出再进

  索引(index)是在数据库表的字段上添加的,是为了提高查询效率存在的一种机制。一张表的一个字段可以添加一个索引,当然,多个字段联合起来也可以添加索引。索引相当于一本书的目录,是为了缩小扫描范围而存在的一种机制。

MySQL在查询方面主要就是两种方式:

  • 全表扫描。
  • 根据索引检索。

注意: 在实际中,汉语字典前面的目录是排序的,按照a b c d e f…排序。为什么排序呢?因为只有排序了才会有区间查找这一说!(缩小扫描范围,其实就是扫描某个区间!)   在mysql数据库当中索引也是需要排序的,并且这个索引的排序和TreeSet数据结构相同。TreeSet(TreeMap)底层是一个自平衡的二叉树!   在mysql当中,索引是一个B-Tree数据结构。遵循左小右大原则存放,采用中序遍历方式遍历取数据。

  1. 在任何数据库当中,主键上都会自动添加索引对象,id字段上自动有索引,因为id是PK。另外在mysql当中,一个字段上如果有unique约束的话,也会自动创建索引对象。

          2. 在任何数据库当中,任何一张表的任何一条记录在硬盘存储上都有一个硬盘的物理存储编号。       3. 在mysql当中,索引是一个单独的对象,不同的存储引擎以不同的形式存在,在MyISAM存储引擎中,索引存储在一个.MYI文件中。在InnoDB存储引擎中,索引存储在一个逻辑名称叫做tablespace的当中。在MEMORY存储引擎当中,索引被存储在内存当中。不管索引存储在哪里,索引在mysql当中都是一个树的形式存在。(自平衡二叉树:B-Tree)

创建索引: create index emp_ename_index on emp(ename);       给emp表的ename字段添加索引,起名为 emp_ename_index

删除索引: drop index emp_ename_index on emp;       将emp表上的emp_ename_index索引对象删除。

查看SQL语句是否使用索引来进行检索

Section titled “查看SQL语句是否使用索引来进行检索”
explain
  • 失效的第1种情况: 使用模糊查询的时候,条件以“%”开始。
  • 失效的第2种情况: 使用or的时候会失效,如果使用or,那么要求or两边的条件字段都要有索引,才会走索引。如果其中一边有一个字段没有索引,那么另一个字段上的索引也会失效,所以这就是为什么不建议使用or的原因。
  • 失效的第3种情况: 使用复合索引的时候,没有使用左侧的列查找,则索引失效。什么是复合索引?两个字段,或者更多的字段联合起来添加一个索引,叫做复合索引。
  • 失效的第4种情况:where当中索引列参加了运算,索引失效。
  • 失效的第5种情况:where当中索引列使用了函数。

索引是各种数据库进行优化的重要手段,优化的时候优先考虑的因素就是索引。

  • 单一索引: 一个字段上添加索引。
  • 复合索引: 两个字段或者更多的字段上添加索引。
  • 主键索引: 主键上添加索引。
  • 唯一性索引: 具有unique约束的字段上添加索引。

视图(view):站在不同的角度去看待同一份数据。

create view view_name as ;
drop view view_name;

方便,简化开发,利于维护。面向视图对象进行增删改查,对视图对象的增删改查,会导致原表被操作!

注意:视图对应的语句只能是DQL语句,但是视图对象创建完成之后,可以对视图进行增删改查等操作。

   增删改查,又叫做:CRUD。CRUD是在公司中程序员之间沟通的术语,一般我们很少说增删改查,一般都说CRUD。

  • C:Create(增)
  • R:Retrive(查:检索)
  • U:Update(改)
  • D:Delete(删)
//数据的导入
//创建数据库之后
source [sql文件路径]
//数据的导出
mysqldump [数据库名] [表名]>[路径]\[名称].sql -uroot -p

数据库设计范式: 数据库表的设计依据,教我们怎么进行数据库表的设计。

  • 第一范式: 要求任何一张表必须有主键,每一个字段原子性不可再分。
  • 第二范式: 建立在第一范式的基础之上,要求所有非主键字段完全依赖主键,不要产生部分依赖。
  • 第三范式: 建立在第二范式的基础之上,要求所有非主键字段直接依赖主键,不要产生传递依赖。

设计数据库表的时候,按照以上的范式进行,可以避免表中数据的冗余,空间的浪费。

一对多: 一对多,两张表,多的表加外键!

多对多: 多对多,三张表,关系表两个外键!

一对一: 一对一放到一张表中不就行了吗?为啥还要拆分表?

  在实际的开发中,可能存在一张表字段太多,太庞大,这个时候要拆分表。   一对一怎么设计?    总结:一对一,外键唯一!

 数据库设计三范式是理论上的,实践和理论有的时候有偏差,最终的目的都是为了满足客户的需求,有的时候会拿冗余换执行速度。因为在sql当中,表和表之间连接次数越多,效率越低(笛卡尔积)。  有的时候可能会存在冗余,但是为了减少表的连接次数,这样做也是合理的,并且对于开发人员来说,sql语句的编写难度也会降低。