1.int(M) 在 integer 数据类型中,M 表示最大显示宽度。
在 int(M) 中,M 的值跟 int(M) 所占多少存储空间并无任何关系。 int(3)、int(4)、int(8) 在磁盘上都是占用 4 btyes 的存储空间。说白了,除了显示给用户的方式有点不同外,int(M) 跟 int 数据类型是相同的。int(10)表示的是数据显示的长度为10位。
2.mysql四种隔离状态
Read Uncommitted(读未提交):最低的隔离级别,一个事务可以读到另一个事务未提交的结果。所有的并发事务问题都会发生。
Read Committed(读已提交):只有在事务提交后,其更新结果才会被其他事务看见。可以解决脏读问题。
Repeated Read(可重复读):在一个事务中,对于同一份数据的读取结果总是相同的,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交。可以解决脏读、不可重复读。
Serialization(可串行化):事务串行化执行,隔离级别最高,牺牲了系统的并发性。可以解决并发事务的所有问题。事务只能一个接一个执行,不能并发执行。
脏读:是指一个事务中访问到了另外一个事务未提交的数据
不可重复读:是指在一个事务内根据同一个条件对行记录进行多次查询,但是搜出来的结果却不一致。发生不可重复读的原因是在多次搜索期间查询条件覆盖的数据被其他事务修改了。
幻读:是指同一个事务内多次查询返回的数据条数不一样(比如增加了或者减少了行记录)。发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据。不同在于不可重复读是同一个记录的数据内容被修改了,幻读是数据行记录变多了或者少了。
3.数据库事务以及四个特性
数据库事务(简称:事务)是数据库管理系统执行过程中的一个逻辑单位,由一条或多条SQL语句组成。只有当所有语句都成功执行,引发的结果才会被写入数据库中,否则所有操作都会被取消。
数据库事务拥有以下四个特性,习惯上被称之为ACID特性。
· 原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。
· 一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。
· 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。
· 持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。
4.关系型数据库和非关系型数据库的区别
关系型数据库:指采用了关系模型来组织数据的数据库。关系模型指的就是二维表格模型,而一个关系型数据库就是由二维表及其之间的联系所组成的一个数据组织。
非关系型数据库以键值对存储,且结构不固定,每一个元组可以有不一样的字段,每个元组可以根据需要增加一些自己的键值对,不局限于固定的结构,可以减少一些时间和空间的开销。
5.redis watch的作用
WATCH命令可以监控一个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行。监控一直持续到EXEC命令(事务中的命令是在EXEC之后才执行的,所以在MULTI命令后可以修改WATCH监控的键值)
以下是两种情况
6.mysql和redis的区别
mysql是关系型数据库,主要用于存放持久化数据,将数据存储在硬盘中,读取速度较慢。
redis是NOSQL,即非关系型数据库,也是缓存数据库,即将数据存储在缓存中,缓存的读取速度快,能够大大的提高运行效率,但是保存时间有限
大多数的应用场景是MySQL(主)+Redis(辅),MySQL做为主存储,Redis用于缓存,加快访问速度。需要高性能的地方使用Redis,不需要高性能的地方使用MySQL。存储数据在MySQL和Redis之间做同步
7.数据库的三范式
数据库范式是指关系型数据库中优化数据存储方式的规范。可以建立冗余较小、结构合理的数据库。
①第一范式:当关系模式R的所有属性都不能再分解为更基本的数据单位时,称R是满足第一范式,即属性不可分,每一列都具有原子性。
在上面的表中,“家庭信息”和“学校信息”列均不满足原子性的要求,故不满足第一范式。
②第二范式:如果关系模式R满足第一范式,每个非主关键字属性完全依赖于主关键字,称R满足第二范式。第二范式需要确保数据库表中的每一列的属性都和主键属性相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。
第二范式(2NF)要求数据库表中的每个实例或记录必须可以被唯一地区分。第二范式适用于具有合成关键字的关系,即主关键字由两个或两个以上的属性构成。主关键字仅包含一个属性的关系已经至少是2NF的。
上面的数据表示一个房屋租赁的记录表,其中主键由“承租人”和“房屋编号”组成,而“房屋所在地”不是完全依赖于主键,而是部分依赖于主键,“房屋所在地”依赖于“房屋编号”,所以上面的数据表是不符合2NF的。
③第三范式:满足第一范式和第二范式的要求并且所有非主关键字属性都不传递依赖于主关键字的关系,称R满足第三范式。
上面的数据表中,主键是“学号”,但是“大学类型”不是直接依赖于主键“学号”,“大学类型”依赖于“大学”,然后“大学”依赖于“学号”,因此存在传递依赖的情况,因此上表不符合3NF。
8.ER图
E-R图也称实体-联系图(Entity Relationship Diagram),提供了表示实体类型、属性和联系的方法,用来描述现实世界的概念模型。
在ER图中有如下四个成分:
矩形框:表示实体,在框中记入实体名。
菱形框:表示联系,在框中记入联系名。
椭圆形框:表示实体或联系的属性,将属性名记入框中。对于主属性名,则在其名称下划一下划线。
连线:实体与属性之间;实体与联系之间;联系与属性之间用直线相连,并在直线上标注联系的类型。(对于一对一联系,要在两个实体连线方向各写1; 对于一对多联系,要在一的一方写1,多的一方写N;对于多对多关系,则要在两个实体连线方向各写N,M。)
9.索引是什么,多加索引一定会好吗
索引是对数据库表中一列或多列的值进行排序的一种存储结构。数据库索引是为了增加查询速度而对表字段附加的一种标识。使用B+树来实现
索引分类
①普通索引index :加速查找
②唯一索引
主键索引:primary key :加速查找+约束(不为空且唯一)
唯一索引:unique:加速查找+约束 (唯一)
③联合索引
-primary key(id,name):联合主键索引
-unique(id,name):联合唯一索引
-index(id,name):联合普通索引
④全文索引fulltext :用于搜索很长一篇文章的时候,效果最好。
⑤空间索引spatial :了解就好,几乎不用
实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。
上面都在说使用索引的好处,但过多的使用索引将会造成滥用。因此索引也会有它的缺点:
创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。
索引需要占物理空间,如果要建立聚簇索引,那么需要的空间就会更大。
当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。降低更新表的速度。
10.索引最左前缀匹配原则
最左前缀匹配原则,必须按照从左到右的顺序匹配。
mysql会以最左边的为起点任何连续的索引都能匹配上,直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
假如建立联合索引(a,b,c)
①全值匹配查询时
select * from table_name where a = ‘1’ and b = ‘2’ and c = ‘3’
select * from table_name where b = ‘2’ and a = ‘1’ and c = ‘3’
select * from table_name where c = ‘3’ and b = ‘2’ and a = ‘1’
…
用到了索引。where子句几个搜索条件顺序调换不影响查询结果,因为Mysql中有查询优化器,会自动优化查询顺序
②匹配左边的列时
select * from table_name where a = ‘1’
select * from table_name where a = ‘1’ and b = ‘2’
select * from table_name where a = ‘1’ and b = ‘2’ and c = ‘3’
都从最左边开始连续匹配,用到了索引
③以下没有从最左边开始,最后查询没有用到索引,用的是全表扫描
select * from table_name where b = ‘2’
select * from table_name where c = ‘3’
select * from table_name where b = ‘1’ and c = ‘3’
④如果不连续时,只用到了a列的索引,b列和c列都没有用到
select * from table_name where a = ‘1’ and c = ‘3’
11.请问数据库优化方法有哪些
参考回答:
①通过建立索引对查询进行优化,尽量避免全表扫描
②优化查询语句
⑴建有索引的字段上尽量不要使用函数进行操作,否则会使索引失效,进行扫全表描查询。原因是,b+树中存的都是数据表中的字段值,但使用函数后进行检索时,需要把所有元素都应用函数才能比较,故无法使用B+树。
⑵在搜索字符型字段时,尽量不要使用使用LIKE关键字和通配符
⑶所有使用NULL值的情况,都可以通过一个有意义的值的表示。Mysql难以优化引用可空列查询,它会使索引、索引统计和值更加复杂。可空列需要更多的存储空间,还需要mysql内部进行特殊处理。可空列被索引后,每条记录都需要一个额外的字节。(需要一个额外字节作为判断是否为NULL 的标志位)
⑷避免在 where 子句中使用!=或<>、or、in/not in、is null、表达式、函数等,这会导致引擎放弃使用索引而进行全表扫描
③选取最适用的字段属性。尽量使用数字型字段,这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。.尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
④使用连接(JOIN)来代替子查询(Sub-Queries)
MySQL不需要在内存中创建临时表来完成这个逻辑上的需要两个步骤的查询工作。
12.redis发布/ 订阅模式
Redis 的发布与订阅功能可以让用户将消息同时发送给多个客户端。此种模式下,消息发布者和订阅者不进行直接通信,发布者客户端向指定的频道(channel)发布消息,订阅该频道的每个客户端都可以收到该消息(频道没有”创建“的概念,可以直接订阅、亦可直接发布消息)。
这一功能最明显的用法就是构建实时消息系统,比如普通的即时聊天,群聊等功能。
简单的应用场景的话, 以门户网站为例, 用户可以订阅某个板块的内容,当出现更新后,会推送给用户。
常用的朋友圈,我们发送朋友圈时就是一个发布者,而能看到这条朋友圈的人就是一个订阅者,订阅者可以根据自己的喜好对发布的消息进行点赞,评论等操作。
13.explain
explain这个命令来查看一个这些SQL语句的执行计划,这条命令的输出结果能够让我们了解MySQL 优化器是如何执行SQL 语句的。
id:选择标识符
select_type:表示查询的类型。
table:输出结果集的表
partitions:匹配的分区
type:表示表的连接类型
possible_keys:表示查询时,可能使用的索引
key:表示实际使用的索引
key_len:索引字段的长度
ref:列与索引的比较
rows:扫描出的行数(估算的行数)
filtered:按表条件过滤的行百分比
Extra:执行情况的描述和说明
type表示MySQL在表中找到所需行的方式,又称“访问类型”,常见类型如下: ALL, index, range, ref, eq_ref, const, system, NULL从左到右,性能从最差到最好
ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行
index:Full Index Scan,index与ALL区别为index类型只遍历索引树
range:索引范围扫描,对索引的扫描开始于某一点,返回匹配值域的行。显而易见的索引范围扫描是带有between或者where子句里带有<, >查询。当mysql使用索引去查找一系列值时,例如IN()和OR列表,也会显示range(范围扫描),当然性能上面是有差异的。
ref:使用非唯一索引扫描或者唯一索引的前缀扫描,返回匹配某个单独值的记录行
14.乐观锁和悲观锁
① 悲观锁总是假设最坏的情况,每次对数据库中的一条数据进行修改的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。
当我们要对一个数据库中的一条数据进行修改的时候,为了避免同时被其他人修改,最好的办法就是直接对该数据进行加锁以防止并发。悲观锁的实现,往往依靠数据库提供的锁机制, ,比如行锁,表锁等,读锁,写锁等。
悲观并发控制实际上是“先取锁再访问”的保守策略,为数据处理的安全提供了保证。但是降低了效率,处理加锁的机制会让数据库产生额外的开销,还有增加产生死锁的机会;另外,还会降低并行性,一个事务如果锁定了某行数据,其他事务就必须等待该事务处理完才可以处理那行数据。
我们拿比较常用的MySql Innodb引擎举例,来说明一下在SQL中如何使用悲观锁。
要使用悲观锁,我们必须关闭mysql数据库的自动提交属性,因为MySQL默认使用autocommit模式,也就是说,当你执行一个更新操作后,MySQL会立刻将结果进行提交。set autocommit=0;
begin; 开始事务
//1.查询出商品库存信息
select quantity from items where id=1for update;
//2.修改商品库存为2
update items set quantity=2where id= 1;
//3.提交事务
commit;
在对id = 1的记录修改前,先通过for update的方式进行加锁,然后再进行修改。这就是比较典型的悲观锁策略。
当for update的字段为索引或者主键的时候,只会锁住索引或者主键对应的行。
而当for update的字段为普通字段的时候,Innodb会锁住整张表。
②乐观锁总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,如果被更新过则重试更新操作,直到更新成功。可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量。
存在问题:
①ABA 问题
如果一个变量V初次读取的时候是A值,并且在准备赋值的时候检查到它仍然是A值,那我们就能说明它的值没有被其他线程修改过了吗?很明显是不能的,因为在这段时间它的值可能被改为其他值,然后又改回A,那CAS操作就会误认为它从来没有被修改过。这个问题被称为CAS操作的 "ABA"问题。
②CAS循环时间长开销大。自旋CAS(也就是不成功就一直循环执行直到成功)如果长时间不成功,会给CPU带来非常大的执行开销。
③版本号机制,高并发的时候,就只有一个线程可以修改成功,那么就会存在大量的失败。可以减小乐观锁力度,最大程度的提升吞吐率,提高并发能力。
updateitem
setquantity=quantity - 1
whereid = 1andquantity - 1> 0
应用场景:乐观锁适用于多读的情况,这样可以提高吞吐量。如果是多写的情况,一般会经常产生冲突,这就会导致上层应用会不断的进行retry,这样反倒是降低了性能。悲观锁适用于多写的情况。