求指教EXCEL基操

我们已经知道了SQL是操作数据库的语言,那么数据库是什么?数据库(database)是 保存一个文件或者一组文件的容器;这样说你可能还不懂,可以比喻为数据是一个图书馆,图书馆里面收藏有好多书,我们可以认为数据库就是能够存储数据的容器;其实数据库很常见,你每天都在操作数据库,比如你看手机,上网,微信聊天,其实背后都在操作数据库,只是展现操作数据库的形式不一样而已;

2.2 数据库管理系统

数据库里面有好多的数据,就像图书管一样有好多的书,书是由图书管理员进行管理,那么什么东西能够管理数据库呢?没错就是数据库管理系统(Database Manage System),比如 mysql, Access、DB2、Informix、 Server、Oracle、Sybase以及其他数据库系统;

表是一种结构化的文件可以用来存储特定类型的数据;这么说你可能没听懂,我们再举个例子,表就像图书馆里面的图书架子,每个书架都放了好多书;再不懂也没关系,你总用过excel吧,excel表格里面的标签页 (sheet) 我们就可类比数据表,表存放的就是特定类型的数据,跟excel的sheet一样;重点是每个表的表名是唯一,不可重复;

列是表中的一个字段,一个表由多个列组成;每个列都由特定的数据类型,只能存放指定数据类型的数据;听不懂没关系,我们类比excel,excel中的sheet也是由多个列组成,每个列都有指定的数据类型,比如文本,数字,日期类型;那数据库的表跟excel的结果是类似的;

数据类型就是限定表中的每个列只能存储特定类型的数据,常见的数据类型有整型,数字,文本,字符串,日期等等。

行就是表中的一条记录,类比excel,很容易理解;

主键就是每行的唯一标识,其特性是主键,不能为空,不能重复,不能修改;主键我们可以类比身份证号,每个身份证号都是唯一不可重复的;

行号指表中每个行的行号

如果是初学者,建议去网上寻找安装Mysql的文章安装,以及使用navicat连接数据库,以后的示例基本是使用mysql数据库管理系统;

需要建立一张学生表,列分别是id,名称,年龄,学生信息;本示例中文章篇幅原因SQL注释略;

sql 都是由许多关键字(keyword)组成的语句,关键字是数据库的保留字,用户不能将其当作建表的表名,字段等;表中的数据检索使用select关键字作为开头进行查询数据库表的信息;

select 是 查询 的意思 , name 代表表中的字段 ,from 表示来自哪张表,其后面的student就是表;连起来的意思就是查询字段是name的数据来自表student;

多sql语句一起执行使用封号(;)隔开,在拼写语句时表的关键字都建议使用大写,表的字段和表名使用小写;为了容易阅读建议将sql分成多行(由于文章篇幅原因就不分了);sql语言也是使用英文字母,不要开中文,以免造成符号错误不容易发现;sql语句默认不区分大小写;

查询字段 名字,年龄来自表student;多个列检索时使用逗号(,)隔开;

通配符 (*)表示返回表中的所有列,如果不是必须建议不要使用通配符,会影响数据库性能;

distinct 表示区分,意指检索出来的行是唯一(去重),其放在列的最前面;如果使用了关键字distinct,其作用于后面的所有列(由于本示例数据没有重复示例,结果就不是很清晰);

TOP 2 表示限制返回前2行

表示查询列名称来自学生表 限制条数1,偏移值1;意思就是查询学生表中的第二行数据;offset表示跳跃或者偏移;

表示查询字段名称来自学生表,限制2条,偏移1条;注意顺序;

检索字段名称,年龄来自学生表按照列年龄排序;注意默认是升序,ORDER BY 子句通常在语句末尾;

查询名称,年龄来自学生表,按照年龄降序,名称升序进行排序;关键字 DESC(descending) 意指降序,字母默认Z-A; ASC(ascending)意指升序,字母默认A-Z;多列情况下,每个列后面指定使用DESC,使用逗号(,)隔开,如果不写,默认升序;

按位指查询字段的位置,2 对应字段age,1对应字段name;结果和4.2一致;

sql 语句中过滤条件(filter condition)的关键字是 WHERE,其使用方式是跟在表名之后;

根据不同的数据库管理系统,其支持的操作符略有不同,所以下文较多重复意思的操作符,应查阅官方文档说明,哪些操作符是支持使用的数据库管理系统;

查询所有字段来自学生表 条件是 学生名称是 jeff;注意 非表字段,表名,关键字,使用2个单引号('')括起来,里面存放的是我们输入的数据;

多条件过滤时使用 AND 或者 OR 子句;AND连接表达式表示过滤条件都为真的数据;OR连接表达式表示匹配过滤条件任意一个;

查询所有字段来自学生表,条件是 学生年龄大于等于18 并且 学生年龄小于 23;

检索所有字段来自学生表,条件是 学生年龄大于等于18,或者学生年龄小于23;

在使用OR 和 AND 的时候应该明确过滤条件,然后使用小括号括起来,由于数据库管理系统是根据顺序执行,如果不使用小括号很容易造成语义错误;查询所有字段来自学生表 过滤条件 年龄大于 18 并且 (年龄小于23 或者 id 大于2)的数据;

BETWEEN 表示范围查询,查询所有字段来自学生表,过滤条件学生年龄在18至23之间;

查询所有字段来自学生表,过滤条件 学生年龄 为空;数据库表不填充数据默认为空(NULL),当然你也可以给指定类型的列设置默认值;

查询所有字段来自学生表 ,过滤条件 年龄 是 18 或者 23 或者 25 ;IN是个范围查询,匹配小括号中指定的任意值,其功能跟OR类似,一个IN 就相当于好多个OR;

通配符是组成匹配模式的特殊字符串;如果有用过正则表达式的同学肯定不陌生,这个与其类似;检索文本的通配符是用在关键词Like 后面;

查询所有字段来自学生表,过滤条件 名字匹配以you开头的字符串后面匹配任意个任意字符;%通配符代表任意个任意字符串,0也算在内,但不包括null;

查询所有列来自学生表,过滤条件学生的名称匹配中间必须出现一次字母i,字母i的前后可以匹配任意个任意字符串;

通配符 _ 代表匹配一个字符串;在Access数据库中不是 _ 而是 ?;

查询所有列来自学生表,过滤条件 学生名称 匹配模式 youku 后面一个为任意字符串;

通配符 [] 表示匹配指定一个位置一个字符;其里面可以存放多个字符,关系是or,模式匹配时只占用一个位置,Access,SQL SERVER 支持;

函数 concat 就是将多个字符子串拼接成一个字符串;不同的数据库管理系统其使用的方式略有差别,应查阅官方文档;在 mysql 中使用 concat函数;在postgresql中使用 || ;在 Access和 sql server中使用 +;

7.2 去除空白字符串

RTRIM(STR) 函数是去掉右边的字符串;TRIM(STR)是去掉字符串两边的空白字符;LTRIM(STR)是去掉字符串左边的空白字符;

别名(alias)是可以给字段,或者表起别名;当多表操作出现重复字段时使用别名是个很好的选择;别名可以使用AS关键字,虽然其是可省略,但平时我们最好加上它增强阅读性;

操作符说明*乘+加-减/除

# 八 聚集函数的使用

先声明一下,下面的库表只是简易的学习示例,不是生产的设计,不要深究,此文我们的目的是学习sql的检索不是库表设计;初学者最好跟着作者的文章一步一步敲一遍,如果没有使用过sql的可以查阅作者SQL系列专栏;

聚集函数的定义就是讲一些行的数据运行某些函数,返回一个期望值;下面讲述的是开发中经常使用到的聚集函数;

avg函数也就是计算行的数量,通过计算这些行的特定列值和,计算出平均值(特定列值之和/行数=平均值);使用时注意其会忽略列值为NULL的行;

语句分析:查询价格平均值来自商品表(5+4+3)/3=4;

查询总行数来自商品表;

max函数返回特定列值的最大值;忽略特定列为NULL的行;

查询价格的最大值来自商品表;

返回特定列的最小值;忽略特定列为NULL的行;

查询价格的最小值来自商品表;

返回特定列的和;忽略特定列为NULL的行;

查询价格的总和来自商品表;

分组定义就是按照特定的列进行分组查询,使用 GROUP BY 子句进行分组查询;注意点:SELEC后面的列必须出现在group by 子句后面,否则报语法错误;通常 group by 子句的位置是where 条件之后,order by 子句之前;

先根据商品名称分为三组 苹果 ,梨 , 香蕉 ;再根据不同的分组求和,因为我们表中的数据只有这三条所以就是每行的值;

查询 条数来自 订单表 根据客户id分组,过滤条件 条数大于2;注意 having 与 where其实差别不大,通常我们讲where当作标准的过滤条件,having用作分组过滤条件;注意有的数据库管理系统having不支持别名作为分组过滤条件中的一部分;

语句分析 查询 行数 来自 订单表 根据 客户id分组,根据 行数排序;注意点是经过分组后结果看似经过排序,其实并不能确保是排序后的结果,所以要排序一定要使用order by子句;

子查询的定义是在查询中嵌套查询;注意子查询只能返回单列,若企图返回多列会报语法错误;

联结表也就是我们通常意义上的关联表查询,主要功能是能在多表中使用一条sql检索出期望值,但实际库表中是存在的,只在查询期间存在;其主要分为内联结和外连接使用的 join 关键字;联结表会返回一对多,一对一,多对多关系;联结表不建议超过三张表以上;

查询 用户名来自用户表,查询订单名称来自订单表,根据 订单表的客户id 等于 客户表的客户id做为联结条件;也就是说会查询出两张表根据userId为等值条件的 userName 和 orderName 的 数据;

注意点 :简单联结中where子句后面 必须 要带上 两张表的联结关系,否则会出现笛卡尔集(比如3行数据联结另一张表3行数据会产生3*3=9条)

内连接(inner join) 又称等值联结,其查询结果跟之前的简单联结一致;

跟之前的简单联结稍微不同的是 等值条件 是放在 on 关键字后面,在等值条件后面还可以进行 where 子句过滤条件查询;

自然联结与标准的联结不同就是只返回值唯一的列,不会返回重复的列;

右外联结是指 相对于 OUTER JOIN 右边的表,那么这会查询出右边表的所有数据 和根据等值条件匹配左边表的数据,如果左边表的数据不匹配,那么其返回列的值是NULL充当;

左外联结是指 相对于 OUTER JOIN 左边的表,那么这会查询出左边表的所有数据 和根据等值条件匹配右边表的数据,如果右边表的数据不匹配,那么其返回列的值是NULL充当;

左外联结和右外联结其实没什么不同,只是查询表顺序不一致,我们通过置换 表的相对位置就可以查询出一样的结果;

组合查询是指可以执行多条SELECT 语句,其查询的结构是一致的,返回查询结果,通常我们称为复合操作或者并(union)

union 关联的字段或者聚合函数在两张表中必须是相同的,其默认会讲结果进行去重处理;如果不去重可以使用 union all

语句分析:等同于讲客户表和订单表的用户id都合并为一个并集查询出来,而且不去重;如果对组合语句进行排序,默认是会作用于组合后的数据字段排序,而不是作用于其中的一条查询语句;

插入数据库记录也就是使用 INSERT 关键字,能将一条语句插入数据库,高级的可以组合 SELECT 关键字 实现 插入查询的结果集,插入整张表;

13.1 插入一条完整数据

插入 数据 到 user 表 字段分别是 id, name , telephone; 值 分别是 2 , zszxz , 1327; 这是插一条完整的语句,虽然INTO可以忽略不写,但不建议这么做,原因是在数据库管理系统间会出现移植性问题;还有字段也可以忽略不写,但也不建议这么做,这容易造成插入数据出错;字段的位置和值的位置是一 一对应;如果有的位置没值可以使用NULL代替;

13.2 插入部分数据

13.3 插入检索数据

插入检索的数据也就是能将查询的结果插入进另一张表;我们可以使用 INSERT SELECT 关键组合成一条语句实现;

插入数据到 user 表, 字段分别是 id, name ,值是查询字段 id ,name 来自 student 表,条件是 id 等于 4;可以看见我们插入数据的列根查询的列名称是匹配对应的,其实只要列顺序一致即可,不过为了不出错,建议使用名称匹配;

复制表即,检索一张表的数据全部插入另一张表;有两种方法,但是不同的数据库管理系统支持不同,具体的看下文;

查询字段 id, name 插入 student_copy 表,来自 student 表;注意 这条语句会帮我们自动创建表 student_copy,由于作者使用的是mysql做演示,这条sql执行失败,原因是其不支持这种方式;如果是想复制整张表可以使用通配符 * ;

更新数据库的行使用 UPDATE 关键字;更新操作是个很危险的操作,在每次执行前都应该检查是否丢了 where 子句;

更新 student_copy 表, 设置 字段 age 值为null;可以看见表中所有的学生年龄都是Null; 如果有多个字段需要更新,使用 逗号隔开;

14.2 更新特定的行

14.3 更新来自查询的结果集

删除表中的行可以使用 DELETE 关键字 ,可以删除特定的行或者全部;使用时请先看是否丢了where子句;

15.1 删除整张表数据

15.2 删除特定的行

15.3 更新和删除的建议

  1. 每次进行操作前检查是否丢失 where 子句;
  2. 每次操作前最好先使用 select 语句验证;

十六 SQL 分类操作

sql 对数据库的操作分为如下三种类型,如果都学会这三种SQL语言熟练对数据库操作,说明你已经对数据库登堂入室,如果再学会数据库高级操作,说明你对数据库就有一定的使用经验,如果你还学会对数据库进行优化,分表分库,读写分离等操作,说明你使用数据库已经到专家级别;

  1. DCL:数据控制语言(Data Control Language),对权限、事务等的控制。比如:grant(授权)revoke(取回权限),commit,roolback等; 事物在上篇已经说明,不会在本篇提及;

数据库的基本操作如下,也就是我们日常使用的操作

数据库表的日常操作如下

其中 TEMPORARY 表示临时表;中括号内容都表示可选,在正规的数据库版本管理开发会经常使用到;

字段的修饰如下 数据类型

表选项一般就是指定数据库引擎和字符集:

常见的alter操作如下:

增加一列(追加至末尾)

增加一列到指定字段名后

修改字段名的 数据类型

修改表字段的数据类型,并且移动至第一列

修改表字段的数据类型,并且移动至指定字段后面

视图其实就是一张虚表,其本质上SQL的检索语句,所以其不储存任何的数据成分;我们使用视图有什么好处呢?

  • 简化查询SQL,直接对视图进行查询,不用管视图具体生成的细节;
  • 可以使用表的部分成为视图,保护数据,开放用户权限时,可以只开放视图,而不开放实体表;
  • 修改数据结构,可以直接对已有的表建立视图,使用不同的表名,字段名称;

我们对视图的操作只能停留在查询上,如果是单表生成的视图还可以进行插入数据;如果是多表关联生成的视图,插入不会起作用;切记任何时候进行关联的时候如果关联3张表以上就是不符合规范,严重的拖累查询性能,视图也是如此,使用复杂的嵌套视图和多表关联也会极大的降低查询性能;

  • 视图是虚表,其有表的部分特性;视图名 唯一 ,与表名类似;
  • 如果非管理员用户,创建视图必须有创建权限;
  • 视图本质是查询语句,故视图可以嵌套,可以与其它表进行联结;
  • 视图不能有索引和触发器

小伙伴们要记得使用视图之前要看看自己的MYSQL版本,5.0以上支持;

  • 创建视图 与创建表类似 , create view 语句用于创建视图

新建简单的视图示例如下,使用 order 表 的 id , order_name , year 三个字段组成视图;as 后面就是查询语句,也可以是子查询,多表关联等复杂的查询语句;

查询视图,其使用本质与查询表一样;示例如下

向视图中插入数据,插入的数据实际在实体表 order 表中切记;

视图的本质上查询语句,故可以对一些简单的数据统计做成视图是个不错的选择;其次如果是开放权限给第三方公司,使用视图查询部分实体表的数据作为开放的表也是对视图的合理应用;最后,也可以将简单的表联结做成视图,简化开发;

由于视图的本质是查询语句,你可以理解为其前世就是查询,今生就是虚表,徒有其“表”,名不副实,只拥有表的部分功能;

18.1 储存过程的概念

我们经常使用的SQL查询语句都是单条语句,如果要使用多条语句达到一个目的就显得力不从心了,储存过程就是使用多条语句完成业务的操作,你可以理解为linux脚本编程类似,window的批处理文件那样;简单的定义储存过程就是多条SQL的集合;

我们使用储存过程能够简化复杂的单条SQL,相比于单条复杂的SQL极大提高了性能;如果表结构发生变化只需要改变储存过程使用到SQL语句的表名,如果业务逻辑发生变化,只需要跳转储存过程即可,具有很强的灵活性;建立一次储存过程,即可使用,不用反复建立,保证开发人员使用到都是相同的储存过程,保证数据可靠性;总之使用储存过程,简单,灵活,安全可靠,性能好;

18.2 存储过程语法

其是通过标签可以实现;iterate 表示迭代, leave表示离开
tip : 如果你是用命令行学习,在写多行SQL的时候 使用 // 可以实现换行哟!

18.3 储存过程示例

我们准备表如下,一个订单明细表;

查看订单明细的所有订单名称,示例如下,跟普通的查询语句没区别;

现在我们需要查询oid为动态的所有订单明细名称,由于考虑到oid为动态,就是需要用户自己输入,故将oid作为入参;

调用储存过程,只查询oid为1的用户的订单明细名称

带入参和出参的存储过程示例

查询任意用户的订单明细的所有金额;定义入参订单id 为 order_id , 输出总金额为 total;

上节的储存过程都是单条SQL,这次我们开始使用控制流程,实现复杂的储存过程;

知识追寻者对输入的 order_id 自动加5 ,然后判断 var 是否 小于7 ,如果是就查询订单明细价格,否则查询订单明细价格总和;

对 变量 var 进行判断,如果 var <7 就执行 查询价格语句,并且var 进行自增;

如下语句实现的效果与上面if语句实现效果一致;

repeat 与 while 的不同之处就是 ,while 在 执行之前检查条件,其实执行之后检查条件;

此时会输出2组相同结果;

游标的本质就是查询后的结果集;当我们对查询的结果集进行前一行或者后一行类似的操作时就可以使用到游标

  • 其次,打开游标;open 游标名称
  • 然后,对查询的结果集 即游标进行 检索行至变量提供使用
  • 最后关闭游标;close 游标名称

查询oid为1 的订单明细名称 的结果集作为游标;

打开游标后抓取每行将结果赋值给变量name

打印结果如下,只有一条数据,说明上述方式只在游标中抓取到一条数据,而且是表里面行号最小的行;

将 查询oid为1的 结果集赋值给游标;通过游标抓取每行 将 订单明细名称和价格分别赋值给变量 name 和 detail_price; 在 循环无法继续时 会出现 SQLSTATE '02000' ; 即此通过 变量 continue 时设置 done 为1 代表 true,此时循环结束,跳出循环;

-- 结束标志变量(默认为假) -- 指定游标循环结束时的返回值 -- 根据游标当前指向的一条数据 -- 判断游标的循环是否结束

美中不足的是会多遍历最后一行,如果要精细处理还是需要自定义标志位进行跳出循环;

触发器是指当表发生改变的时候触发的动作;听起来有点抽象,举个栗子,当你往表中插入数据的时候,此时表发生了改变,现在想要在每次插入数据之前检测所有的入参是否都是小写,此时就可以用触发器来检测;经过上面的分析知道使用一个基本的触发器,至少表要发生改变,还要满足一个被触发的事件;

表发生改变通常指 增删改,其动作可以发生在增删改 之前或者之后;触发事件就是我们需要写的储存过程;

20.2 触发器的基本语法

tip : 触发器是依赖于表创建,没有表就没有触发器,比如视图,临时表都不是真实的表,它们是没有触发器;一般来说每个表都有触发器的限制,一般最多支持6个不同类型的触发器;由于使用触发器会频繁的改变表的每行,故其十分影响性能,特别对一些更新频率比较快的大表,如果设置触发器就非常占用系统资源;一般来说触发器用在表变动较小的小表, 不使用触发器就立即删除;

创建触发器; 创建一个触发器 getPrice 作用于 oder_detail 表的每行,每当 插入数据之后就查询这条订单明细的价格赋值给变量 @price ;小伙伴可能会疑惑 NEW 是何物,其是一张虚表,记录者被插入数据的行;故我们能在NEW表中获取每次插入的数据;

检测插入触发器; 插入一条数据,使用查询语句查询变量 显示为 20;

将之前的插入的SQL语句进行修改价格,并查询价格,此时价格为30;NEW虚表储存的是即将更新的数据;

将 更新触发器的NEW表改为OLD表

此时查询 价格为30,说明OLD表触发的是原始数据值;

tip :更新触发器主要是要搞懂OLD存放原始数据,NEW存放即将更新的数据;NEW表可以设置更改值,二OLD表是只读;

将 更新触发器改为 delete 触发器, 之前我们省略了 begin, end 如果是多条执行语句则需要加上;

查询价格为40,OLD表存放的是将要被删除的数据;

有关用户账号的信息储存mysql的MYSQL数据库,故如果需要查看用户信息,则需要进入MYSQL库;

user表储存了所有的登陆账号;使用mysql库查询user表中的user;

22.1 查看用户权限

示例:查看用户zszxz 拥有的权限

查询出一条权限,但 USAGE 表示 根本没有权限;

示例 给用户zszxz 分配 zszxz 库中的所有表的查询权限;

示例:撤销 用户 zszxz 对 zszxz库里面所有表的查询操作;

使用授权,撤销权限时可以参考如下权限列表;

MYSQL 的层级大概可以分为3类;第一层 为 连接层,只要负责MYSQL的数据库连接,安全认证的功能;

第二层是MYSQL的核心层面,其主要功能包括,MYSQL的查询,缓存,执行计划,优化等都在第二层实现;

第三层是引擎层,为MYSQL指定不同的引擎将达到不同的数据操作效果;

MYSQL 的 Query Cache 是 基于 hash 值计算进行匹配的缓存机制;通常在大数据量的情况下如果开启Query Cache 会 频繁的计算Hash ,会增加性能的消耗,得不偿失,生产环境中建议关闭该选项;

关于锁的知识希望读者学习过高并发相关知识,对所有的锁分类有个清晰的认识,学习本篇关于锁的概念将不会遇到阻碍;在MYSQL中根据不同的引擎,主要会出现三类锁的情况,即 表锁,读锁 和写锁;读锁很好理解,在MYSQL 中 读锁也是共享锁, 即 多用户状态下同一时间对资源的读取是互不影响,但不能对数据进行修改等操作

一般情况下我们手动给一条或者某个范围内(一般使用在储存过程)的数据加上读锁;

写锁是排他锁,也称为独占锁;使用的情况一般是写入数据的情况下,一个用户如果获得写锁,其它用户将不能获取写锁或者读锁,直到该用户执行完操作并释放锁;其使用方式为在执行语句后加上for update 语句即可

锁粒度是指对资源锁定范围的一个程度,使用不同的锁定策略达到并发性能较优的结果;通常锁粒度使用策略情况分为,行锁,表锁,页锁的情况;

**表锁:**即对整张表进行加锁,其性能开销较小,加锁的速度较快,但缺点也很明显,其锁粒度大,并发低;如果要手动加表锁,语法示例 lock tables 表名,释放锁 unlock tables 表名

行锁:即对行进行锁定,能够最大支持并发量,故锁粒度最小,但其枷锁速度慢,性能消耗大,会出现死锁;行锁的种类又有 记录锁(主键或者唯一索引都属于记录锁),间隙锁(GAP),记录锁和间隙锁的组合(next -key lock);间隙锁一般用于查询条件是范围情况下,而非相等条件;

页锁:通常情况下遇不到页锁,其开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间;

还有锁的其它分类也会使用到比如乐观锁(基于版本号实现),注意点是条件必须是主键,读取时将数据版本号读出,更新数据时,版本号加1;将查询的数据进行对比,如果版本号不一致就是过期数据;

悲观锁(如表锁,行锁,读写锁都是悲观锁);

如果看了知识追寻者写的锁知识还有困惑可以参考如下链接

在上面的图例中可以看见MYSQL支持多种引擎,当然远不止图中显示的引擎数量;我们主流使用的引擎就是 InnoDB,其次是 MyISAM,特殊情况下会使用到Memory;引擎的知识是一本书都无法概括的内容,知识追寻者在这边给小伙伴们做个简介,有个大概的了解就好;

InnoDB 是使用最广泛的引擎,也是最重要的引擎,读者有必要了解其储存性能;InnoDB 是 可重复读的事物隔离级别,但其实现了next key lock ,防止的幻读出现;其基于聚簇索引实现;其组要组成结构为内存结构,线程,磁盘文件组;

MyISAM在早期版本是MYSQL的默认引擎,在MYSQL5.1之后不再使用;其不支持事物,不支持行锁,默认表锁,并发量低,;

Menory引擎故名思意,其储存内容都是存放在引擎当中,支持Hash和Btree索引,其数据读取快,但缺点也很明显,服务器如果发生故障重启后就会造成数据丢失;

锁等待的意思非常好理解,就是session (事物会话,开启一个事物代表一个会话)A 对 某行数据获取独占锁(在这边一般就是写锁),然后session B 对相同的行进行获取独占锁就发生了锁等待;简单理解就是 小孩子抢玩具,谁先抢到 谁 先玩,没抢到的玩具的孩子只能 等待 抢到玩具孩子玩腻了再给你,瞬间泪奔有木有,就是这么残酷,当然MYSQL 没 这么残忍 其 还是有一个保留参数 innodb_lock_wait_timeout 指定死锁 的时间,如果超过 死锁等待时间就是报异常;

知识追寻者 做个实验:

session A 执行如下语句,开启事物,更新索引为1 的语句;此时 session A 获取了 id= 1 这条 语句的 写锁权限;

session B 执行如下 语句 , 跟 上面的语句一样 ,由于 id =1 这条数据的写锁已经被session A 获取,故会发生锁等待的情况;

知识追寻者这边默认等待了50秒 就报了如下异常

查看 默认锁等待 语句

死锁 就是 两个以上的会话 在 抢占 资源过程中 ,产生相互等待的情况;有点绕是不是,其实很简单 死锁是建立在 锁等待的基础上,session A 获取 id = 1 的写锁 , session B 获取 id =2 的写锁 ,此时由于索引不同,故不会长生锁等待现象 ;当 session A 尝试 获取 id =2 的 写锁时 ,由于 id = 2 写锁已经被

session A 执行语句, 尝试获取 id =2 的 写锁权限,进入锁等待状态

session B 执行语句, 尝试获取 id =1 的 写锁权限,进入锁等待状态

当 B 进入 锁等待后就直接报死锁异常

不得不说下字母代表锁得类型如下

  • gap lock(GK), 间隙锁,锁定一个范围,不包括当前记录本身;

如何解决死锁,知识追寻者这边给个思路:

查找到死锁线程,杀死MYSQL死锁的线程(kill命令);

如果事物未提交,直接回滚事物;

25.3 如何避免死锁

  • 在死锁容易产生得表使用表锁不会产生死锁;
原文:本文出自公众号Java知音
}

仓库管理员管的不仅仅是仓库里的物品,还要记录各种数据,甚至根据领导的要求做出各类报表。这些难吗?太难了,仅仓库里的物品就够管的了,还要再做报表,真的难死宝宝了,再难,咱也要干啊,报表做出来要一目了然,要看着舒服,所以,先从版面说起。

在excel或者wps表格中,是无法看到有多少内容能放到A4纸上的,这一点做的没有word那么方便,所以我们以进行一点小小的设置。

一、点文件下的打印预览,进入到文件的预览界面。

二、在纸张类型上,咱选择A4,注意一下纸张类型的右边,有一个纵向和横向,你的报表需要怎么打印,就怎么调整。

三、如果想要报表好看,除了表格内容设计好之外,还有一点很重要,就是页边距,在打印预览的右侧,有个页边距,还有个页面设置,页边距是上下左右拉去页边距的线进行调整,在拉动的同时显示离页边的数值,页面设置下有四个栏目,页边距是用数字精确调整。

需要注意的有两点,一是页眉和页脚,上下的页边距含页眉和页脚离页边的距离,你可以自行调整一下看看,二是装订线,你是从顶部还是从左侧,如果是从顶部装订报表呢,从哪里装订一定要把此处的页边距做大一点,否则可能会把重要的内容给遮挡住。

当你选择打印预览后,再回到表格界页,会看到出现了虚线,这个虚线内就是你设置的在A4纸显示的内容,虚线外的内容就是另外一张。

关注我,仓管路上不迷途!

}

我要回帖

更多关于 基指什么意思 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信