目录

  • 视图
    • 视图常用操作
    • 创建视图的完整语法
    • 不可更新的视图
  • 索引
    • 索引的优缺点
    • 常见的几种索引
    • 常用的索引操作
    • 常见的索引方式
    • mysql对使用了索引的sql语句的优化
    • 联合索引的最左匹配原则
    • 索引的最佳实践
      • 哪些字段适合创建索引
      • 创建索引的注意点
      • sql语句中合理运用索引
  • 主键
  • 外键关联策略

视图

视图是一张虚表,将查询结果集保存起来,作为视图使用。实际存在的表叫作基本表。

视图的作用

  • 提高安全性。grant授权用户只能操作视图,通过视图来操作基本表,可以保护基本表中的数据
  • 提高查询性能。视图只是基本表的一部分,查视图比查全表快。尤其是多表查询的时候,查视图一张表比连接多张表查询要快很多

视图常用操作

-- 创建视图,as指定结果集,假设cs系的id是1
create view view_dep_cs as (select * from tb_student where dep_id=1);  -- 可以把这个视图作为cs系学生信息表来使用-- 修改视图定义,用新结果集覆盖原来的结果集。如果视图不存在,会自动创建
create or replace view view_dep_cs as (select id,name from tb_student where dep_id=1);  -- 从视图查询数据
select * from view_dep_cs where name='chy';  --查询cs系名字是chy的学生-- 删除视图
drop view view_dep_cs;

创建视图的完整语法

create [algorithm=merge] view view_dep_cs as (select * from tb_student where dep_id=1) [with check option] ;

algorithm指定视图执行机制,有3个可选的值

1、merge 合并

不创建临时表,执行时会先用视图定义替换视图名,每次都是操作基本表,并不会提高查询性能,但可以增改删查。

2、temptable 临时表

把结果集保存为临时表,每次操作的都是临时表,可以提高查询性能,但只读,不能增删改。

3、undefined 未定义
不指定algorithm就是undefined,使用数据库设置的默认值,mysql默认使用merge。

如果使用merge,还可以设置一个可选参数:with check option 检查条件。

创建视图时设置了条件where dep_id=1,即视图中的记录都是dep_id=1的。

如果指定了with check option,往视图中插入、更新记录时,都要满足记录的dep_id=1这个条件,否则不执行操作;如果不指定with check option,则不要求dep_id=1。

使用merge时往往要设置with check option。

不可更新的视图

即使使用merge,也不一定可以进行增删改,as指定视图数据来源,如果视图来源中使用了一下任一项,则创建的视图只读(只能查询)、不能增删改

  • 聚合函数
  • group by子句
  • having子句
  • distinct关键字
  • union运算符
  • from来源于多个表或者来源于不可更新的视图

一句话:不是直接来源于一个基本表的视图,则该视图只读、不能更新视图数据。

索引

不使用索引时,要操作某些记录,需要遍历整张表来找到匹配的记录,时间开销大。

索引相当于数据表的目录,根据目录可直接定位到章节,根据索引可直接定位到数据表的记录,无需遍历整张表。

索引的优缺点

  • 极大提高了检索速度,尤其是记录数很多的时候(优)
  • 索引也是一张表,要占硬盘空间,有额外的空间开销(缺)
  • 对基本表进行增改删时会同步到索引(维护索引),有额外的时间、资源开销(缺)

相较于优点,索引的缺点微不足道。

常见的几种索引

  • 单值索引:索引中只包含数据表的一列(一个字段)
  • 唯一索引:索引中列的值唯一,一般是数据表的主键列
  • 联合索引:也叫作符合索引,索引中包含数据表的多个列
  • 全文索引:只能对MyISAM引擎的表使用,且索引中的列要是char、varchar、text等文本类型
  • 覆盖索引:如果索引中已经包含了查询sql要用到的所有字段,则会直接在索引中进行查询,不再回表。如果不是覆盖索引,则先查索引定位记录在表中的位置,再回表查询。

常用的索引操作

create index index_ts on tb_student(id,name);  -- on指定使用哪张表的哪些字段来创建索引。经常使用学号、姓名定位学生(记录),所以使用这2列创建索引show index from tb_student;  -- 查看某个表上所有的索引drop index index_ts on tb_student;  -- 删除索引

索引、视图都可以在数据库管理工具(比如Navicat)中直接操作。索引是在 “设计表” 中操作的。

常见的索引方式

1、b+树

eg. 以id字段创建索引,假设有7条记录,id 1~7

查找id=7的记录的地址:4 -> 6 -> 7

2、hash  通过hash值直接定位记录位置

eg. 使用id字段建立索引,查找id=7的记录:计算7的hash值 -> 根据hash值直接确定记录在表中的位置。

b+树要一级一级地找,hash直接定位,效率远高于b+树。但一般都是使用b+树,因为大多数存储引擎都支持b+树,hash只有memory存储引擎支持。

mysql对使用了索引的sql语句的优化

mysql会对使用了索引的sql语句进行优化,主要优化点如下

  • 自动调整同级别and条件的顺序,把使用了索引的字段放前面,尽量走索引。不要过度依赖于mysql自身的优化,尽量把走索引的条件写在前面。
  • 走索引的字段使用in限定范围时,in()中的值可以乱序。
  • 如果使用in()的字段走的是唯一索引,且()中只有一个值时,会自动优化为=等值判断。
--eg. username、tel都加了唯一索引, age没加索引--mysql会自动调整同级别and条件的顺序、尽量用到索引、选择合适的索引,用and连接时条件时条件可以乱序
where age>18 and username='xxx'--使用了or后,同级别的条件不会走索引,慎用or--三个字段都不会走索引
where username='xxx' and tel='xxx' or age>18
--三个字段都不会走索引,or左边的()作为整体看待不会走索引,()里面的各字段自然不会走索引
where (username='xxx' and tel='xxx') or age>18
--or所在级别的条件tel、age不会走索引,但username会走索引
where username='xxx' and (tel='xxx' or age>18)--模糊查询尽量使用前缀匹配,只有前缀匹配的模糊查询才会走索引--username会走索引
where username like 'x%'
--以下2种的username都不会走索引
where username like '%x%'
where username like '%xx'

联合索引的最左匹配原则

联合索引的最左匹配原则:使用联合索引时,会从联合索引中最左边的字段向右匹配,直到遇到没有使用到联合索引中的字段,或者遇到<、>、between之类的范围限定。

--eg. username、tel、email三个字段建立联合索引--只会用到联合索引的username字段,没有涉及tel到tel就断了,不会用到联合索引中的email字段
where username='xxx' and email='xxx'--只会用到联合索引的username字段,遇到范围限定like直接断了
where username='xxx' and tel like '%888%' and email='xxx'

索引的最佳实践

使用好索引包括2个方面:设计、建立合理的索引, sql语句中合理运用索引。

哪些字段适合创建索引
  • 主键
  • 外键
  • 频繁作为条件的字段。eg. 经常要用where name=’ ',那就给name字段创建索引
  • group by分组使用的字段
  • order by排序使用的字段
  • 统计(聚合函数)使用的字段

添加主键时,会自动给主键列创建唯一索引(Unique);添加外键时,会自动给外键列创建普通索引(Normal)。

创建索引后,从表中查找匹配的记录时数据库会自动使用合适的索引。

创建索引的注意点

1、记录少的表不必建立索引,一般以1千行记录为界限。

建立索引有额外的空间开销,增改删时维护索引也有额外的时间开销,记录数少时全表扫描的性能相对较高,没有必要创建索引。

2、频繁增改删的字段,维护索引开销大,不适合用于创建索引。

3、区分度低的字段建立索引没有多大意义,尽量选择区分度高(列值重复少)的字段建立索引;列值较长的字段不适合作为索引,就算要作为索引,也尽量只取列值的前缀作为索引。

4、联合索引会覆盖其中包含的单列索引,存在联合索引时再建立其中的单列索引没有意义。

5、联合索引遵循最左匹配原则,设计联合索引时,尽量将最左字段设置为值区分度高、使用频率高的字段。

6、一张表建立的索引不宜太多,一般不超过5个索引。

一张表建立太多的索引,空间占用多,数据库会花费更多的时间在索引的选择上,且增删改需要同时维护几个索引,对性能的影响较大。

7、及时删除废弃的、没有必要的索引,避免维护索引带来的不必要开销。

sql语句中合理运用索引

字段加了索引后,sql语句使用索引时需要注意以下几点

1、数据库字段为字符串类型时,sql语句中该字段的值加不加引号都行,但加了引号才会走索引,不加引号则不会走索引。

--值没有加引号,username加了索引也不会走索引
select ... from user where username=xxx;--username会走索引
select ... from user where username='xxx';

2、where子句中,比较运算符左边的列参与了数学运算,则该列不会走索引;参与了函数调用的列不管是放在比较运算符的哪边,都不会走索引。

--比较运算符>=左边的age参与了数学运算,不会走索引
select ... from user where age-18>=0--可以将数学运算移到右边 (以下2个sql的age都会走索引)
select ... from user where age>=0+18
--或者把要走索引的列移到比较运算符的右边
select ... from user where 0+18<=age

3、使用联合索引时,考虑到最左匹配原则,尽量把条件中联合索引中的字段放在范围限定的前面,且字段顺序尽量与联合索引中的字段顺序保持一致,保证尽可能多的使用联合索引中的字段。

主键

mysql创建表时,如果没有指定主键,且存在 整型+not null+自增 的字段,则该字段必须设置为主键才合法。

mysql允许创建表时不指定主键,未指定主键时mysql会自动把 整型+not null 的字段作为主键,如果不存在这样的字段,InnoDB会自动生成一个隐式主键,这个隐式主键我们看不到。

尽量手动给每个表设置主键,保证主键可控。

外键关联策略

eg. tb_order通过外键user_id关联tb_user的主键id,当update、delete tb_user的id时,如何处理与之对应的tb_order中的记录?

设计外键时,mysql提供了4种外键关联策略

1、RESTRICT 限制(默认)

如果有外键关联了tb_user的id,则tb_user不能删除被关联的记录、不能更新关联记录id字段的值(会报错)。

如果要删除记录、更新id字段的值,需要先切断关联关系,比如先删除tb_order中与之关联的记录、或者把相关记录外键字段的值置为null。

2、CASCADE 级联

删除tb_user中的记录时,会自动删除tb_order中与之关联的记录;修改tb_user中id字段的值时,会自动修改tb_order中与之关联的记录的外键字段的值(同步变化)。

3、NO ACTION 不做处理

删除、更新tb_user中的user_id字段的值时,tb_order中与之关联的记录不作任何处理。此种策略需要存储引擎支持,如果存储引擎不支持,会自动换为RESTRICT。

4、SET NULL 置为NULL

删除tb_user的记录,或者更新id字段的值,会自动将tb_order中与之关联的记录的外键字段的值置为NULL。

这种方式有一个要求:设计tb_order时,外键字段不能用NOT NULL约束。

关联数据的更新、删除逻辑应该由我们在代码中控制,更可控,而非交由数据库自动处理,所以一般不设置外键,或者设置外键后使用 NO ACTION 策略。

MySQL 视图、索引、外键关联策略相关推荐

  1. JPA关系映射系列一:one-to-one外键关联

    2019独角兽企业重金招聘Python工程师标准>>> SpringDataJPA是Spring Data的一个子项目,通过提供基于JPA的Repository极大的减少了JPA作为 ...

  2. mysql 删除表数据_主外键关联表的数据删除策略

    说个题外话,我从来没想过会被拼多多这款软件所魔怔,他的这种社交营销的能力,实在是太强了,在怂恿之下,开始给儿子拼个这个, 各位有空帮砍下,https://w.url.cn/s/AzlPAB9,或者扫下 ...

  3. mysql 外键关联

    mysql 外键关联 什么是外键: 外键是一个特殊的索引,用于关联两个表,只能是指定内容. 如我将新建一个daka的表,然后将此表的class_id 与另外一个class的表的cid字段关联 clas ...

  4. MySQL如何同时删除主外键关联的两张表中的数据

    1. 编写目的 介绍一种方法,解决如下问题:如何同时删除两张相关联的表的记录. 比如说表a的外键fk依赖于表a的id,现在我们需要删除id=5的两条数据. 2. 主要方法 为了简单,推荐更改表a的外键 ...

  5. MySQL — 外键关联操作

    目录 文章目录 目录 MySQL 的外键约束 创建表时定义外键(References,参照) 修改原有表的外键约束 删除外键约束 参考文档 MySQL 的外键约束 注意,MySQL 的 InnoDB ...

  6. MySQL外键关联(一对多)MySQL连接查询

    MySQL外键关联(一对多) 外键说明 什么是外键? 1)表A中有字段(如身份证号)做了主键,表B中也有这个字段(身份证号),这里的身份证号一定来自表A同样字段里的内容,但再B表中身份证号对应id可以 ...

  7. mysql不能删除外键吗,MySQL不能删除外键约束所需的索引

    MySQL不能删除外键约束所需的索引 我需要改变现有的数据库添加一列. 因此我也想更新UNIQUE字段来包含这个新列. 我试图删除当前的索引,但不断收到错误MySQL Cannot drop inde ...

  8. mysql支持UUID做外键_Mysql中以uuid为外键插入多条数据,怎样实现同一个二级分类外键关联的数据为同一个uuid的值...

    打开我的navicat,然后找到我的teacher表,选中它,然后点击菜单栏上32313133353236313431303231363533e4b893e5b19e31333431366237的'd ...

  9. Mysql中的外键分析(什么是外键,为什么要用外键,添加外键,主外键关联删除)

    有一个东西一直在我脑海中是个很烦的东西,但是这东西不搞清楚会阻碍自己的前进.自己做项目demo永远只能用一张表... 所以今天还是学习了下外键希望能够搞明白一些... 百度上搜索外键的作用" ...

  10. 宋体查询1.mysql数据库复习加强 2.mysql事务触发器 3.mysql 索引外键加强 4.zendstudio 的安装使用 5.svn版本控制器的使用-java教程...

    上班之余抽点间时出来写写博文,希望对新接触的朋友有帮助.今天在这里和大家起一学习一下宋体查询 1.mysql数据库温习增强 1,导出mysql数据库里ecshop到d盘 mysqldump 指令和 m ...

最新文章

  1. WebView宽度自适应
  2. springboot项目打包部署服务器
  3. 多标签文本分类 [ALBERT](附代码)
  4. mysql不需要安装_MySQL免安装版 配置
  5. npm run dev 在本地调试出现跨域问题解决方法
  6. 自适应响应式炫酷汽车配件类网站源码 html5高端大气汽车网站织梦模板
  7. VisualSVN Server 修改用户密码
  8. X86 CPU特性之(3)-kaiser
  9. drupal8 表单_Drupal 8如何实现面向未来
  10. 2021 CVPR | 基于渐进感受局部区域推理的全方位监督点云分割
  11. 搭建自己的病毒扫描系统clamav-原版教程
  12. 强制更改wifi名前缀CMCC
  13. Inno Setup打包的exe程序加上【unins.exe】卸载程序
  14. 基于javaweb的客户信息管理系统搭建
  15. Alfa与申威【江南所】
  16. java即时通讯 开源_java开源即时通讯软件服务端openfire源码构建
  17. 【程序设计训练】棋盘
  18. java-php-python--数字相册管理系统-点赞演示2021计算机毕业设计
  19. notepad++使用一行多个关键字的与搜索,同时搜索多个关键词的或搜索
  20. 白苹果了怎么办_iOS 13如何降级?iOS13降级失败怎么办?

热门文章

  1. C语言课设-单位车辆调度管理
  2. 数据流分析之Reaching Definition Analysis
  3. 苹果手机锁屏后无线重新连接服务器,iphone11锁屏自动断开wifi怎么办 苹果11手机热点自动断开解决方法...
  4. 九爷带你了解 nginx优化
  5. Android一步步实现无痕埋点(3)-------虎躯一震
  6. 如何下载股票的历史收盘价 股票历史收盘价下载方法
  7. RAP2环境部署(nginx代理模式)及运维
  8. OnlyOffice快速入门
  9. RRP拷贝目录内的所有文件及子目录到指定目录
  10. 浩辰3D软件入门教程:如何创建零件?