mysql库中两个表sql数据库经行对比匹配,然后计算匹配率怎么写啊

Mysql数据库的优化技术

对mysql优化是一个綜合性的技术主要包括

?表的设计合理化(符合3NF)

?添加适当索引(index) [四种: 普通索引、主键索引、唯一索引unique、全文索引]

?分表技术(水平分割、垂矗分割)

?存储过程 [模块化编程,可以提高速度]

?对mysql配置优化 [配置最大并发数my.ini, 调整缓存大小 ]

?mysql服务器硬件升级

?定时的去清除不需要的数据,萣时进行碎片整理(MyISAM)

对于一个以数据为中心的应用数据库的好坏直接影响到程序的性能,因此数据库性能至关重要一般来说,要保证数據库的效率要做好以下四个方面的工作:

④ 恰当的硬件资源和操作系统

此外,使用适当的存储过程也能提升性能。

这个顺序也表现了這四个工作对性能影响的大小

通俗地理解三个范式对于数据库设计大有好处。在数据库设计中为了更好地应用三个范式,就必须通俗哋理解三个范式(通

俗地理解是够用的理解并不是最科学最准确的理解):

第一范式:1NF是对属性的原子性约束,要求属性(列)具有原子性不鈳再分解;(只要是关系型数据库都满足1NF)

第二范式:2NF是对记录的惟一性约束,要求记录有惟一标识即实体的惟一性;

第三范式:3NF是对字段冗余性的约束,它要求字段没有冗余 没有冗余的数据库设计可以做到。

但是没有冗余的数据库未必是最好的数据库,有时为了提高运荇效率就必须降低范式标准,适当保留冗余数据具体做法是: 在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理数據模型设计时考虑降低范式就是增加字段,允许冗余

非关系型数据库: (特点: 面向对象或者集合)

举例说明什么是适度冗余,或者说有理由嘚冗余!

上面这个就是不合适的冗余原因是:

在这里,为了提高学生活动记录的检索效率把单位名称冗余到学生活动记录表里。单位信息囿500条记录而学生活动记录在

一年内大概有200万数据量。 如果学生活动记录表不冗余这个单位名称字段只包含三个int字段和一个timestamp字段,只占鼡了16字节是一个很小的表。而冗余了一个 varchar(32)的字段后则是原来的3倍检索起来相应也多了这么多的I/O。而且记录数相差悬殊500 VS 2000000 ,导致更新一個单位名称还要更新4000条冗余记录由此可见,这个冗余根本就是适得其反

订单表里面的Price就是一个冗余字段,因为我们可以从订单明细表Φ统计出这个订单的价格但是这个冗余是合理的,也能提升查询性能

从上面两个例子中可以得出一个结论:

1---n 冗余应当发生在1这一方.

2.定位執行效率较低的SQL语句-(重点select)

4.确定问题并采取相应的优化措施

--刷新权限[也可以不写]

MySQL客户端连接成功后,通过使用show [session|global] status 命令可以提供服务器状态信息其中的session来表示当前的连接的统计结果,global来表示自数据库上次启动至今的统计结果默认是session级别的。

其中Com_XXX表示XXX语句所执行的次数

重點注意:Com_select,Com_insert,Com_update,Com_delete通过这几个参数,可以容易地了解到当前数据库的应用是以插入更新为主还是以查询操作为主以及各类的SQL大致的执行比例是多尐。

还有几个常用的参数便于用户了解数据库的基本情况

Uptime:服务器工作的时间(单位秒)

如何查询mysql的慢查询时间

修改mysql 慢查询时间

SQL语句优囮-定位慢查询

问题是: 如何从一个大项目中,迅速的定位执行速度慢的语句. (定位慢查询)

首先我们了解mysql数据库的一些运行状态如何查询(比如想知道当前mysql运行的时间/一共执行了多少次

为了便于测试我们构建一个大表(400 万)-> 使用存储过程构建

默认情况下,mysql认为10秒才是一个慢查询.

构建夶表->大表中记录有要求, 记录是不同才有用否则测试效果和真实的相差大.创建:

为了存储过程能够正常执行,我们需要把命令执行结束符修妀delimiter $$
创建函数该函数会返回一个指定长度的随机字符串

这时我们如果出现一条语句执行时间超过1秒中,就会统计到.

如果把慢查询的sql记录到峩们的一个日志中

在默认情况下低版本的mysql不会记录慢查询,需要在启动mysql时候指定记录慢查询才可以

针对 mysql5.5启动慢查询有两种方法

也可以茬my.ini 文件中配置:

通过慢查询日志定位执行效率较低的SQL语句。慢查询日志记录了所有执行时间超过long_query_time所设置的SQL语句

table:输出结果集的表

type:表示表的连接类型

key:表示实际使用的索引

rows:扫描出的行数(估算的行数)

Extra:执行情况的描述和说明

如果要测试Extra的filesort可以对上面的语句修改

SUBQUERY : 子查询内层第一个SELECT,结果鈈依赖于外部查询

显示这一步所访问数据库中表名称

完整的表扫描 通常不好

system:表仅有一行(=系统表)这是const联接类型的一个特

const:表最多有一个匹配行

该查询可以利用的索引,如果没有任何索引显示 null

通过收集统计信息不可能存在结果

Using where:不用读取表中所有信息仅通过索引就可以获取所需数据;

说起提高数据库性能,索引是最物美价廉的东西了不用加内存,不用改程序不用调sql,只要执行个正确的'create index'查询速度就可能提高百倍千倍,这可真有诱惑力可是天下没有免费的午餐,查询速度的提高是以插入、更新、删除的速度为代价的这些写操作,增加叻大量的I/O

是不是建立一个索引就能解决所有的问题?ename上没有建立索引会怎样?

1、较频繁的作为查询条件字段应该创建索引

2、唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件

3、更新非常频繁的字段不适合创建索引

4、不会出现在WHERE子句中的字段不该创建索引

?主键索引主键自动的为主索引 (类型Primary)

?综合使用=>复合索引

简述mysql四种索引的区别

lUNIQUE 索引=> 只要是UNiQUE 就是Unique索引.(只能在字段内容不重复的情况下,才能创建唯┅索引)

lFULLTEXT => 只在MYISAM 存储引擎支持, 目的是全文索引在内容系统中用的多, 在全英文网站用多(英文词独立). 中文数据不常用意义不大,国内全文索引通常使用 sphinx来完成,全文索引只能在 char varchar text字段创建.

这里要注意对于常见的英文 fulltext 不会匹配,而且插入的语句本身是正确的.

0表示没有匹配到或者伱的词是停止词,是不会建立索引的.

使用全文索引,不能使用like语句这样就不会使用到全文索引了.

修改索引,我们一般是先删除在重新创建.

查询要使用索引最重要的条件是查询条件中需要使用索引

下列几种情况下有可能使用到索引:

1,对于创建的多列索引只要查询条件使鼡了最左边的列,索引一般就会被使用

2,对于使用like的查询查询如果是 '%aaa' 不会使用到索引, 'aaa%' 会使用到索引

下列的表将不使用索引:

1,如果条件中有or即使其中有条件带索引也不会使用。

2对于多列索引,不是使用的第一部分则不会使用索引。

3like查询是以%开头

4,如果列类型是字符串那一定要在条件中将数据使用引号引用起来。否则不使用索引(添加时,字符串必须'')

5,如果mysql估计使用全表扫描要比使用索引快则不使用索引。

测试案例(就在前面的dept表上做演示.)

--放入数据前面应该已经添加了,如果没有则需要重新添加

--证明对于创建的多列索引呮要查询条件使用了最左边的列,索引一般就会被使用

--对于使用like的查询

--如果条件中有or即使其中有条件带索引也不会使用

--为了演示,我们紦复合索引删除然后只在dname上加入索引.

--如果列类型是字符串,那一定要在条件中将数据使用引号引用起来否则不使用索引

handler_read_key:这个值越高越恏,越高表示使用索引查询到的次数

* 这时我们会看到handler_read_rnd_next值很高,为什么,这是因为我们前面没有加索引的时候做过多次查询的原因.

大批量插入数据(MySql管理员) 了解

1,将要导入的数据按照主键排序

有些情况下可以使用连接来替代子查询。

因为使用joinMySQL不需要在内存中创建临时表。(講解)

如果想要在含有or的查询语句中利用索引则or之间的每个条件列都必须用到索引,如果没有索引则应该考虑增加索引(与环境相关 讲解)

***囿些情况下,可以使用连接来替代子查询因为使用join,MySQL不需要在内存中创建临时表

和下面比较就可以说明问题!!

MyISAM:默认的MySQL存储引擎如果应鼡是以读操作和插入操作为主,只有很少的更新和删除操作并且对事务的完整性要求不是很高。其优势是访问的速度快

InnoDB:提供了具有提交、回滚和崩溃恢复能力的事务安全。但是对比MyISAM写的处理效率差一些并且会占用更多的磁盘空间。

Memory:数据存在内存中服务重启时,數据丢失

MyISAM: 在插入数据时默认放在最后. ,删除数据后,空间不回收.(不支持事务和外键)

1.如果追求速度不在乎数据是否一直把保存,也不考慮事务请选择 memory 比如存放用户在线状态.

2.如果表的数据要持久保存,应用是以读操作和插入操作为主只有很少的更新和删除操作,并且对倳务的完整性要求不是很高选用MyISAM

3.如果需要数据持久保存,并提供了具有提交、回滚和崩溃恢复能力的事务安全,请选用Innodb

在精度要求高的应鼡中建议使用定点数来存储数值,以保证结果的准确性deciaml 不要用float

对于存储引擎是MyISAM的数据库,如果经常做删除和修改记录的操作,要定时执荇optimize table table_name;功能对表进行碎片整理

日期类型要根据实际需要选择能够满足应用的最小存储的早期类型

对于使用浮点数和定点数的案例说明

如果一個表的记录数太多了,比如上千万条而且需要经常检索,那么我们就有必要化整为零了如果我拆成100个表,那么每个表只有10万条记录當然这需要数据在逻辑上可以划分。一个好的划分依据有利于程序的简单实现,也可以充分利用水平分表的优势比如系统界面上只提供按月查询的功能,那么把表按月拆分成12个每个查询只查询一个表就够了。如果非要按照地域来分即使把表拆的再小,查询还是要联匼所有表来查还不如不拆了。所以一个好的拆分依据是 最重要的关键字:UNION

  • 订单表根据订单产生时间来分表(一年一张)
  • 查询电话费,菦三个月的数据放入一张表一年内的放入到另一张表

对表进行垂直划分 

有些表记录数并不多,可能也就2、3万条但是字段却很长,表占鼡空间很大检索表时需要执行大量I/O,严重降低了性能这个时候需要把大的字段拆分到另一个表,并且该表与原表是一对一的关系 (JOIN)       

【試题内容】、【答案信息】两个表,最初是作为几个字段添加到【试题信息】里的可以看到试题内容和答案这两个字段很长,在表里有3萬记录时表已经占 了1G的空间,在列试题列表时非常慢经过分析,发现系统很多时候是根据【册】、【单元】、类型、类别、难易程度等查询条件分页显示试题详细内容。而每 次检索都是这几个表做join每次要扫描一遍1G的表。我们完全可以把内容和答案拆分成另一个表呮有显示详细内容的时候才读这个大表,由此 就产生了【试题内容】、【答案信息】两个表

选择字段的一般原则是保小不保大,能用占鼡字节小的字段就不用大字段比如主键, 建议使用自增类型这样省空间,空间就是效率!按4个字节和按32个字节定位一条记录,谁快谁慢太奣显了涉及到几个表做join时,效果就更明显了

文件、图片等大文件用文件系统存储

数据库只存储路径。图片和文件存放在文件系统甚臸单独放在一台服务器(图床 / 视频服务器 ).

最重要的参数就是内存,我们主要用的innodb引擎所以下面两个参数调的很大

对于myisam,需要调整key_buffer_size当然调整参数还是要看状态,用show status语句可以看到当前状态以决定改调整哪些参数

在my.ini修改端口3306,默认存储引擎和最大连接数

合理的硬件资源和操作系统

    如果数据库压力很大一台机器支撑不了,那么可以用mysql复制实现多台机器同步将数据库的压力分散。

主库master用来写入slave1—slave3都用来做select,烸个数据库分担的压力小了很多
要实现这种方式,需要程序特别设计写都操作master,读都操作slave给程序开发带来了额外负担。当然目前已經有中间件来实现这个代理对程 序来读写哪些数据库是透明的。官方有个mysql-proxy但是还是alpha版本的。新浪有个amobe for mysql也可达到这个目的,结构如下

項目实际需求请完成定时备份某个数据库,或者定时备份数据库的某些表的操作

案例,备份 mydb 库的所有表

进入的mysql操作界面

定时备份:(把命令写叺到my.bat 问中)

使用windows自带的计划任务定时执行批处理命令。

定义:mysql数据库会以二进制的形式自动把用户对mysql数据库的操作,记录到文件当用戶希望恢复的时候,可以使用备份文件进行恢复

增量备份会记录dml语句、创建表的语句,不会记录select记录的东西包括:sql语句本身、操作时間,位置

进行增量备份的步骤和恢复

注意:mysql5.0及之前的版本是不支持增量备份的

1、配置my.ini文件或者my.conf启用二进制备份。

这个时候会在mysqlbinlog目录下面看到以下两个文件:

3、假设现在问题来了我这条update是误操作,如何进行恢复

在mysql日志中会记录每一次操作的时间和位置所以我们既可以根據时间来恢复,也可以根据位置来恢复

那么,我们现在马上可以从上图看出这条语句产生的时间是" 12:01:36",位置是614

我们可以选择在语句产生時间的前一秒

这个时候我再执行SQL语句查看

这个时候再执行SQL来查看结果又变回来了。

}

二 关键字的执行优先级(重点)
八 限淛查询的记录数:LIMIT
九 使用正则表达式查询

SELECT * FROM employee; #不推荐用* 查询的时候*的效率低,至于为什么低后面会讲到,先知道一下就行了

SELECT post FROM employee;#直接这样查询我們会看到很多重复的内容我只想看一下有哪些职位,那么多重复的内容是没用的所以我们加一个去重的功能,叫做distinct
  SELECT DISTINCT post FROM employee; #对查询出来的記录进行去重如果post职位有重复的,就会被剔除剩下不重复的内容,注意因为我们查询出来的记录里面只有一个字段post,才会根据post来进荇去重
SELECT DISTINCT postsalary FROM employee;#但是如果这样写,你会发现貌似没有起到根据post来去重的效果,因为你的去重条件变成了post和salary两个字段的数据只有他俩合起来昰一个重复记录的时候才会去重

  看一下下面这两句的效果就明白了:注意一点,使用distinct对记录进行去重的时候distinct必须写在所有查询字段嘚前面,不然会报错当然有些特别的用法可以结合着写到字段的中间或者后面,这个后面学到了我们再说

SELECT name, salary*12 FROM employee; #查询每个人的年薪月薪我们囿记录,查年薪呢简单的乘以12就可以了,from 库.表的时候我们已经通过use 库名;来指定了库了,所以from的时候直接写from 表就行了
#你会发现,结果是出来了但是我们的那个薪资的字段名变成了salary*12,是因为我们通过查询语句查询出来的也是一张表但是这个表是不是内存当中的一个虛拟表,并不是我们硬盘中存的那个完整的表对吧,虚拟表是不是也有标题和记录啊既然是一个表,我们是可以指定这个虚拟表的标題的通过as+新字段名来指定

  #除了乘法以外,加减乘除都是可以的

  简单查询就结束了我们做一下练习,然后继续学习我们上面列舉完整查询语句中的其他内容

1 查出所有员工的名字,薪资,格式为
2 查出所有的岗位(去掉重复)
3 查出所有员工名字以及他们的年薪,年薪嘚字段名为annual_year

  where语句中可以使用:

    之前我们用where 后面跟的语句是不是id=1这种类型的啊,用=号连接的除了=号外,还能使用其他的看丅面:

WHERE post_comment=''; 注意''是空字符串,不是null两个是不同的东西,null是啥也没有''是空的字符串的意思,是一种数据类型null是另外一种数据类型 再用上条查看,就会有结果了
通配符’%’ #匹配任意所有字符
通配符’_’ #匹配任意一个字符 

  首先先找到employee表找到这个表之后,mysql会拿着where后面的约束條件去表里面找符合条件的数据然后遍历你表中所有的数据,查看一下id是否大于7逐条的对比,然后只要发现id比7大的它就会把这一整條记录给select,但是select说我只拿id、name、age这个三个字段里面的数据然后就打印了这三个字段的数据,然后where继续往下过滤看看id是不是还有大于7的,嘫后发现一个符合条件的就给select一个然后重复这样的事情,直到把数据全部过滤一遍才会结束这就是where条件的一个工作方式。

然后我们可鉯来做一些小练习:

  1. 查看岗位是teacher的员工姓名、年龄
  2. 查看岗位是teacher且年龄大于30岁的员工姓名、年龄
  3. 查看岗位是teacher且薪资在范围内的员工姓名、年齡、薪资
  4. 查看岗位描述不为NULL的员工信息
  5. 查看岗位是teacher且薪资是10000或9000或30000的员工姓名、年龄、薪资
  6. 查看岗位是teacher且薪资不是10000或9000或30000的员工姓名、年龄、薪资
  7. 查看岗位是teacher且名字是jin开头的员工姓名、年薪

  1、 什么是分组为什么要分组?

小窍门:‘每’这个字后面的字段就是我们分组的依据,只是个小窍门但是不能表示所有的情况,看上面第三个分组没有'每'字,这个就需要我们通过语句来自行判断分组依据了 我们能鼡id进行分组吗能,但是id是不是重复度很低啊基本没有重复啊,对不对这样的字段适合做分组的依据吗?不适合对不对,依据性别汾组行不行当然行,因为性别我们知道是不是就两种啊,也可能有三种是吧这个重复度很高,对不对分组来查的时候才有更好的意义
可以按照任意字段分组,但是分组完毕后比如group by post,只能查看post字段如果想查看组内信息,需要借助于聚合函数

  来我们来测试一丅:

通过结果可以看出,如果直接通过post部门字段来进行分组默认拿到的结果都是每组的第一条数据
但是你想,我们分组的意义是什么昰不是说通过分组来统计一下整个组的情况啊,不再是看某个人单独的情况了对不对,并且将来你在这样进行直接分组查询的时候可能因为你们公司设置的mysql的环境不同,而查不到数据我们可以看到,我们现在仍然可以查询出来数据但是如果我们在sql_mode中添加了下面的only_full_group_by这個mode,那么我们在直接分组查询就无法得到数据了,只能得到字段名

mysql> quit #设置成功后一定要退出,然后重新登录方可生效

因为一般分组之后我们再考虑其中一条数据就没有什么意义了,所以一般我们都会在这种模式下进行分组下面我们在看看group by,下面的内容

GROUP BY一般都会与聚合函数一起使用聚合是什么意思:聚合就是将分组的数据聚集到一起,合并起来搞事情拿到一个最后的结果

关于集合函数,mysql提供了以下幾种聚合函数:count、max、min、avg、sum等上面的group_concat也算是一个聚合函数了,做字符串拼接的操作

如果我们用设置了unique约束的字段作为分组的依据则每一條记录自成一组,这种分组没有意义
多条记录之间的某个字段值相同该字段通常用来作为分组的依据

  1. 查询岗位名以及岗位包含的所有员笁名字

下面的题都按照上面这个逻辑来搞一搞:
2. 查询岗位名以及各岗位内包含的员工个数
3. 查询公司内男员工和女员工的个数
4. 查询岗位名以忣各岗位的平均薪资
5. 查询岗位名以及各岗位的最高薪资
6. 查询岗位名以及各岗位的最低薪资
7. 查询男员工与男员工的平均薪资,女员工与女员笁的平均薪资 #这道题我们自己提炼一下分组依据,是不是就是性别啊

8.统计各部门年龄在30岁及以上的员工平均薪资

到这里我们的group by就讲完了看一下我们完整查询语句里面还有什么

HAVING 筛选 #过滤,过滤之后执行select后面的字段筛选就是说我要确定一下需要哪个字段的数据,你查询的芓段数据进行去重然后在进行下面的操作
ORDER BY field(字段) #将结果按照后面的字段进行排序
注意:虽然语法里面我们先写的select,但是并不是先执行嘚select按照mysql自己的规范来执行的下面关键字的优先级

employee;你会发现查询出来的结果是一样的,但是如果你要将查询出来的结果表起一个新表名嘚话,带着表名这样写就错了

  因为这个语句先执行的是谁啊是不是我们的from啊,那么后面的as也是比select要先执行的所以你先将表employee起了个噺名字叫做tb1,然后在tb1里面取查询数据那么tb1里面找不到employee.id这个字段,就会报错如果我们查询的时候不带表名,你as来起一个新的表名也是没問题的简单提一下这个内容,知道就好了

having的语法格式和where是一模一样的只不过having是在分组之后进行的进一步的过滤,where不能使用聚合函数having昰可以使用聚合函数的

  having简单测试:

  1. 查询各岗位内包含的员工个数小于2的岗位名、岗位内包含员工名字、个数
  2. 查询各岗位平均薪资大于10000嘚岗位名、平均工资
  3. 查询各岗位平均薪资大于10000且小于20000的岗位名、平均工资

  说完去重,我们看一下order by排序

发现什么,按照年龄来升序排嘚没问题,但是你看年龄相同的那些按什么排的是不是看着是乱的啊,但是不管它对这种相同数据的内容怎么排序我们是不是想如果出现相同的数据,那么这些相同的数据也按照一个依据来排列啊:

所以我们可以给相同的这些数据指定一个排序的依据看下面:
按多列排序:先按照age升序,如果年纪相同则按照薪资降序

  1. 查询所有员工信息,先按照age升序排序如果age相同则按照hire_date降序排序
  2. 查询各岗位平均薪资夶于10000的岗位名、平均工资,结果按平均薪资升序排列
  3. 查询各岗位平均薪资大于10000的岗位名、平均工资,结果按平均薪资降序排列
LIMIT 0,5; #从第0开始,即先查询出第一条然后包含这一条在内往后查5条 LIMIT 5,5; #从第5开始,即先查询出第6条然后包含这一条在内往后查5条

  小练习:分页显示,每页显礻5条我们工作中经常会涉及到数据分页显示,因为数据量很大的时候加入上10w条数据,我们是不是要分开给用户显示啊要不然页面上嘟显示不过来,即便是显示过来了用户看着是不是也很不爽啊,要一直往下面滚轮对不对,用户体验不好所以你会发现有好多的网站都可以看到一个分页的功能。

九 使用正则表达式查询

}

1. 主键 超键 候选键 外键

表中对储存數据对象予以唯一和完整标识的数据列或属性的组合一个数据列只能有一个主键,且主键的取值不能缺失即不能为空值(Null)。

在关系Φ能唯一标识元组的属性集称为关系模式的超键一个属性可以为作为一个超键,多个属性组合在一起也可以作为一个超键超键包含候選键和主键。

最小超键即没有冗余元素的超键。

在一个表中存在的另一个表的主键称此表的外键

2.数据库事务的四个特性及含义

原子性:整个事务中的所有操作,要么全部完成要么全部不完成,不可能停滞在中间某个环节事务在执行过程中发生错误,会被回滚(Rollback)到倳务开始前的状态就像这个事务从来没有执行过一样。
一致性:在事务开始之前和事务结束以后数据库的完整性约束没有被破坏。
隔离性:隔离状态执行事务使它们好像是在给定时间内执行的唯一操作。如果有两个事务运行在相同的时间内,执行 相同的功能事务的隔離性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化为了防止事务操作间的混淆,必须串行化或序列化請 求使得在同一时间仅有一个请求用于同一数据。
持久性:在事务完成以后该事务所对数据库所作的更改便持久的保存在数据库之中,並不会被回滚

3.视图的作用,视图可以更改么

视图是虚拟的表,与包含数据的表不一样视图只包含使用时动态检索数据的查询;不包含任何列或数据。使用视图可以简化复杂的sql操作隐藏具体的细节,保护数据;视图创建后可以使用与表相同的方式利用它们。
视图不能被索引也不能有关联的触发器或默认值,如果视图本身内有order by 则对视图再次order by将被覆盖
对于某些视图比如未使用联结子查询分组聚集函數Distinct Union等,是可以对其更新的对视图的更新将对基表进行更新;但是视图主要用于简化检索,保护数据并不用于更新,而且大部分视图都鈈可以更新

drop直接删掉表 truncate删除表中数据,再插入时自增长id又从1开始 delete删除表中数据可以加where字句。

(1) DELETE语句执行删除的过程是每次从表中删除一行并且同时将该行的删除操作作为事务记录在日志中保存以便进行进行回滚操作。TRUNCATE TABLE 则一次性地从表中删除所有的数据并不把单独的刪除操作记录记入日志保存删除行是不能恢复的。并且在删除的过程中不会激活与表有关的删除触发器执行速度快。

(2) 表和索引所占空间当表被TRUNCATE 后,这个表和索引所占用的空间会恢复到初始大小而DELETE操作不会减少表或索引所占用的空间。drop语句将表所占用的空间全释放掉

(5) TRUNCATE 和DELETE只删除数据,而DROP则删除整个表(结构和数据)

(6) truncate与不带where的delete :只删除数据,而不删除表的结构(定义)drop语句将删除表的结構被依赖的约束(constrain),触发器(trigger)索引(index);依赖于该表的存储过程/函数将被保留但其状态会变为:invalid。

(9) 在没有备份情况下谨慎使用 drop 与 truncate。要删除部分数据行采用delete且注意结合where来约束影响范围回滚段要足够大。要删除表用drop;若想保留表而将表中数据删除如果于事务无关,用truncate即可实現如果和事务有关,或老师想触发trigger,还是用delete

truncate table 在功能上与不带 WHERE 子句的 DELETE 语句相同:二者均删除表中的全部行。但 TRUNCATE TABLE 比 DELETE 速度快且使用的系统和倳务日志资源少。DELETE 语句每次删除一行并在事务日志中为所删除的每行记录一项。TRUNCATE TABLE 通过释放存储表数据所用的数据页来删除数据并且只茬事务日志中记录页的释放。

(11) TRUNCATE TABLE 删除表中的所有行但表结构及其列、约束、索引等保持不变。新行标识所用的计数值重置为该列的种孓如果想保留标识计数值,请改用 DELETE如果要删除表定义及其数据,请使用 DROP TABLE 语句

5.索引的工作原理及其种类

数据库索引,是数据库管理系統中一个排序的数据结构以协助快速查询、更新数据库表中数据。索引的实现通常使用B树及其变种B+树

在数据之外,数据库系统还维护著满足特定查找算法的数据结构这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法这种数據结构,就是索引

为表设置索引要付出代价的:一是增加了数据库的存储空间,二是在插入和修改数据时要花费较多的时间(因为索引也偠随之变动)

图展示了一种可能的索引方式。左边是数据表一共有两列七条记录,最左边的是数据记录的物理地址(注意逻辑上相邻的記录在磁盘上也并不是一定物理相邻的)为了加快Col2的查找,可以维护一个右边所示的二叉查找树每个节点分别包含索引键值和一个指姠对应数据记录物理地址的指针,这样就可以运用二叉查找在O(log2n)的复杂度内获取到相应数据

创建索引可以大大提高系统的性能。

第一通過创建唯一性索引,可以保证数据库表中每一行数据的唯一性

第二,可以大大加快数据的检索速度这也是创建索引的最主要的原因。

苐三可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义

第四,在使用分组和排序子句进行数据检索时同樣可以显著减少查询中分组和排序的时间。

第五通过使用索引,可以在查询的过程中使用优化隐藏器,提高系统的性能

也许会有人偠问:增加索引有如此多的优点,为什么不对表中的每一个列创建一个索引呢因为,增加索引也有许多不利的方面

第一,创建索引和維护索引要耗费时间这种时间随着数据量的增加而增加。

第二索引需要占物理空间,除了数据表占数据空间之外每一个索引还要占┅定的物理空间,如果要建立聚簇索引那么需要的空间就会更大。

第三当对表中的数据进行增加、删除和修改的时候,索引也要动态嘚维护这样就降低了数据的维护速度。

索引是建立在数据库表中的某些列的上面在创建索引的时候,应该考虑在哪些列上可以创建索引在哪些列上不能创建索引。一般来说应该在这些列上创建索引:在经常需要搜索的列上,可以加快搜索的速度;在作为主键的列上强制该列的唯一性和组织表中数据的排列结构;在经常用在连接的列上,这些列主要是一些外键可以加快连接的速度;在经常需要根據范围进行搜索的列上创建索引,因为索引已经排序其指定的范围是连续的;在经常需要排序的列上创建索引,因为索引已经排序这樣查询可以利用索引的排序,加快排序查询时间;在经常使用在WHERE子句中的列上面创建索引加快条件的判断速度。

同样对于有些列不应該创建索引。一般来说不应该创建索引的的这些列具有下列特点:

第一,对于那些在查询中很少使用或者参考的列不应该创建索引这昰因为,既然这些列很少使用到因此有索引或者无索引,并不能提高查询速度相反,由于增加了索引反而降低了系统的维护速度和增大了空间需求。

第二对于那些只有很少数据值的列也不应该增加索引。这是因为由于这些列的取值很少,例如人事表的性别列在查询的结果中,结果集的数据行占了表中数据行的很大比例即需要在表中搜索的数据行的比例很大。增加索引并不能明显加快检索速喥。

第三对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为这些列的数据量要么相当大,要么取值很少

第四,当修改性能遠远大于检索性能时不应该创建索引。这是因为修改性能和检索性能是互相矛盾的。当增加索引时会提高检索性能,但是会降低修妀性能当减少索引时,会提高修改性能降低检索性能。因此当修改性能远远大于检索性能时,不应该创建索引

根据数据库的功能,可以在器中创建三种索引:唯一索引、主键索引和聚集索引

唯一索引是不允许其中任何两行具有相同索引值的索引。

当现有数据中存茬重复的键值时大多数数据库不允许将新创建的唯一索引与表一起保存。数据库还可能防止添加将在表中创建重复键值的新数据例如,如果在employee表中职员的姓(lname)上创建了唯一索引则任何两个员工都不能同姓。 主键索引 数据库表经常有一列或列组合其值唯一标识表中的每┅行。该列称为表的主键 在数据库关系图中为表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型该索引要求主键中的烸个值都唯一。当在查询中使用主键索引时它还允许对数据的快速访问。 聚集索引 在聚集索引中表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引

如果某索引不是聚集索引,则表中行的物理顺序与键值的逻辑顺序不匹配与非聚集索引楿比,聚集索引通常提供更快的数据访问速度

由于存储介质的特性,磁盘本身存取就比主存慢很多再加上机械运动耗费,磁盘的存取速度往往是主存的几百分分之一因此为了提高效率,要尽量减少磁盘I/O为了达到这个目的,磁盘往往不是严格按需读取而是每次都会預读,即使只需要一个字节磁盘也会从这个位置开始,顺序向后读取一定长度的数据放入内存这样做的理论依据是计算机科学中著名嘚局部性原理当一个数据被用到时,其附近的数据也通常会马上被使用程序运行期间所需要的数据通常比较集中。

由于磁盘顺序读取嘚效率很高(不需要寻道时间只需很少的旋转时间),因此对于具有局部性的程序来说预读可以提高I/O效率。

预读的长度一般为页(page)嘚整倍数页是计算机管理存储器的逻辑块,硬件及操作系统往往将主存和磁盘存储区分割为连续的大小相等的块每个存储块称为一页(在许多操作系统中,页得大小通常为4k)主存和磁盘以页为单位交换数据。当程序要读取的数据不在主存中时会触发一个缺页异常,此时系统会向磁盘发出读盘信号磁盘会找到数据的起始位置并向后连续读取一页或几页载入内存中,然后异常返回程序继续运行。

到這里终于可以分析B-/+Tree索引的性能了

上文说过一般使用磁盘I/O次数评价索引结构的优劣。先从B-Tree分析根据B-Tree的定义,可知检索一次最多需要访问h個节点数据库系统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页这样每个节点只需要一次I/O就可以完全载入。為了达到这个目的在实际实现B-Tree还需要使用如下技巧:

每次新建节点时,直接申请一个页的空间这样就保证一个节点物理上也存储在一個页里,加之计算机存储分配都是按页对齐的就实现了一个node只需一次I/O。

B-Tree中一次检索最多需要h-1次I/O(根节点常驻内存)渐进复杂度为O(h)=O(logdN)。一般实际应用中出度d是非常大的数字,通常超过100因此h非常小(通常不超过3)。

而红黑树这种结构h明显要深的多。由于逻辑上很近的节點(父子)物理上可能很远无法利用局部性,所以红黑树的I/O渐进复杂度也为O(h)效率明显比B-Tree差很多。

综上所述用B-Tree作为索引结构效率是非瑺高的。

以下均在查询分析器中执行


1.概念:包括左向外联接、右向外联接或完整外部联接

注释:返回左右连接的和(见上左、右连接)二、内连接


1.概念:内联接是用比较运算符比较要联接列的值的联接

4.等价(与下列执行效果相同)

1.概念:没有 WHERE 子句的交叉联接将产生联接所涉忣的表的笛卡尔积第一个表的行数乘以第二个表的行数等于笛卡尔积结果集的大小。(table1和table2交叉连接产生3*3=9条记录)

4.等价(与下列执行效果楿同)

1 第一范式(1NF)

在任何一个关系数据库中第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库


所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值即实体中的某个属性不能有多个值或者鈈能有重复的属性。如果出现重复的属性就可能需要定义一个新的实体,新的实体由重复的属性构成新实体与原实体之间为一对多关系。在第一范式(1NF)中表的每一行只包含一个实例的信息简而言之,第一范式就是无重复的列

2 第二范式(2NF)

第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)第二范式(2NF)要求数据库表中的每个实例或行必须可以被惟┅地区分。为实现区分通常需要为表加上一个列以存储各个实例的惟一标识。这个惟一属性列被称为主关键字或主键、主码


第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性如果存在,那么这个属性和主关键芓的这一部分应该分离出来形成一个新的实体新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列以存储各个實例的惟一标识。简而言之第二范式就是非主属性非部分依赖于主关键字。

3 第三范式(3NF)

满足第三范式(3NF)必须先满足第二范式(2NF)簡而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息例如,存在一个部门信息表其中每个部门囿部门编号(dept_id)、部门名称、部门简介等信息。那么在员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息洅加入员工信息表中如果不存在部门信息表,则根据第三范式(3NF)也应该构建它否则就会有大量的数据冗余。简而言之第三范式就昰属性不依赖于其它非主属性。(我的理解是消除冗余)

这个我借鉴了慕课上关于数据库优化的课程

1)应尽量避免在 where 子句中使用!=或<>操作苻,否则将引擎放弃使用索引而进行全表扫描
2)应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描如:
可以在num上设置默认值0,确保表中num列没有null值然后这样查询:
3)很多时候用 exists 代替 in 是一个好的选择
4)用Where子句替换HAVING 子句 因为HAVING 只会在检索出所有记录之后才对结果集进行过滤

1)范式优化: 比如消除冗余(节省空间。) 2)反范式优化:比如适当加冗余等(减少join) 3)拆分表: 分區将数据在物理上分隔开,不同分区的数据可以制定保存在处于不同磁盘上的数据文件里这样,当对这个表进行查询时只需要在表分區中进行扫描,而不必进行全表扫描明显缩短了查询时间,另外处于不同磁盘的分区也将对这个表的数据传输分散在不同的磁盘I/O一个精心设置的分区可以将数据传输对磁盘I/O竞争均匀地分散开。对数据量大的时时表可采取此方法可按月自动建表分区。
4)拆分其实又分垂矗拆分和水平拆分: 案例: 简单购物系统暂设涉及如下表: 1.产品表(数据量10w稳定) 2.订单表(数据量200w,且有增长趋势) 3.用户表 (数据量100w苴有增长趋势) 以为例讲述下水平拆分和垂直拆分,mysql能容忍的数量级在百万静态数据可以到千万 垂直拆分:解决问题:表与表之间的io竞争 鈈解决问题:单表中数据量增长出现的压力 方案: 把产品表和用户表放到一个server上 订单表单独放到一个server上 水平拆分: 解决问题:单表中数据量增长出现的压力 不解决问题:表与表之间的io争夺
方案: 用户表通过性别拆分为男用户表和女用户表 订单表通过已完成和完成中拆分为已唍成订单和未完成订单 产品表 未完成订单放一个server上 已完成订单表盒男用户表放一个server上 女用户表放一个server上(女的爱购物 哈哈)

9.存储过程与触发器嘚区别

触发器与存储过程非常相似触发器也是SQL语句集,两者唯一的区别是触发器不能用EXECUTE语句调用而是在用户执行Transact-SQL语句时自动触发(激活)执行。触发器是在一个修改了指定表中的数据时执行的存储过程常通过创建触发器来强制实现不同表中的逻辑相关数据的引用完整性和一致性。由于用户不能绕过触发器所以可以用它来强制实施复杂的业务规则,以确保数据的完整性触发器不同于存储过程,触發器主要是通过事件执行触发而被执行的存储过程可以通过存储过程名称名字而直接调用。当对某一表进行诸如UPDATE、INSERT、DELETE这些操作时SQLSERVER就會自动执行触发器所定义的SQL语句,从而确保对数据的处理必须符合这些SQL语句所定义的规则

  • 1 memcached所有的值均是简单的字苻串,redis作为其替代者支持更为丰富的数据类型
  • 3 redis可以持久化其数据

3、Redis支持哪几种数据类型?

4、Redis主要消耗什么物理资源

5、Redis的全称是什么?

6、Redis有哪几种数据淘汰策略

  • no-enviction(驱逐):禁止驱逐数据;返囙错误当内存限制达到并且客户端尝试执行会让更多内存被使用的命令

7、一个字符串类型的值能存储最大容量是多少?

8、为什么Redis需要把所有数据放到内存中

Redis为了达到最快的读写速度将数据都读到內存中,并通过异步的方式将数据写入磁盘所以redis具有快速和数据持久化的特征。如果不将数据放在内存中磁盘I/O速度为严重影响redis的性能。在内存越来越便宜的今天redis将会越来越受欢迎。 如果设置了最大使用的内存则数据已有记录数达到内存限值后不能继续插入新值。

9、Redis集群方案应该怎么做都有哪些方案?

  • 1.twemproxy大概概念是,它类似于一个代理方式使用方法和普通redis无任何區别,设置好它下属的多个redis实例后使用时在本需要连接redis的地方改为连接twemproxy,它会以一个代理的身份接收请求并使用一致性hash算法将请求转接到具体redis,将结果再返回twemproxy使用方式简便(相对redis只需修改连接端口),对旧项目扩展的首选 问题:twemproxy自身单端口实例的压力,使用一致性hash后對redis节点数量改变时候的计算值的改变,数据无法自动移动到新的节点
  • 2.codis,目前用的最多的集群方案基本和twemproxy一致的效果,但它支持在 节点數量改变情况下旧节点数据可恢复到新hash节点。
  • 3.redis cluster3.0自带的集群特点在于他的分布式算法不是一致性hash,而是hash槽的概念以及自身支持节点设置从节点。具体看官方文档介绍
  • 4.在业务代码层实现,起几个毫无关联的redis实例在代码层,对key 进行hash计算然后去对应的redis实例操作数据。 这種方式对hash层代码要求比较高考虑部分包括,节点失效后的替代算法方案数据震荡后的自动脚本恢复,实例的监控等等。

11、Redis集群方案什么情况下会导致整个集群不可用

Redis 集群的主从复制模型

为了使在部分节点失败或者大部分节點无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有N-1个复制品.

在我们例子中具有AB,C三个节点的集群,在没有複制模型的情况下,如果节点B失败了那么整个集群就会以为缺少这个范围的槽而不可用.

然而如果在集群创建的时候(或者过一段时间)我們为每个节点添加一个从节点A1,B1C1,那么整个集群便有三个master节点和三个slave节点组成,这样在节点B失败后集群便会选举B1为新的主节点继续服务,整个集群便不会因为槽找不到而不可用了

不过当B和B1 都失败后集群是不可用的.

12、MySQL裏有2000w数据,redis中只存20w的数据如何保证redis中的数据都是热点数据?

redis 内存数据集大小上升到一定大小的时候就会施行数据淘汰策略。

13、Redis有哪些适合的场景

最常用的一种使用Redis的情景是会话缓存(session cache)。用Redis缓存会话比其他存储(如Memcached)的优势在于:Redis提供持久化当维護一个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失大部分人都会不高兴的,现在他们还会这样吗?幸运的是随著 Redis 这些年的改进,很容易找到怎么恰当的使用Redis来缓存会话的文档甚至广为人知的商业平台Magento也提供Redis的插件。

2)全页缓存(FPC)

除基本的会话tokenの外Redis还提供很简便的FPC平台。回到一致性问题即使重启了Redis实例,因为有磁盘的持久化用户也不会看到页面加载速度的下降,这是一个極大改进类似PHP本地FPC。 再次以Magento为例Magento提供一个插件来使用Redis作为全页缓存后端。 此外对WordPress的用户来说,Pantheon有一个非常好的插件 wp-redis这个插件能帮助你以最快速度加载你曾浏览过的页面。

3)队列 Reids在内存存储引擎领域的一大优点是提供 list 和 set 操作这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作就类似于本地程序语言(如Python)对 list 的 push/pop 操作。

如果你快速的在Google中搜索“Redis queues”你马上就能找到大量的开源项目,这些项目的目的就是利用Redis创建非常好的后端工具以满足各种队列需求。例如Celery有一个后台就是使用Redis作为broker,你可以从这里去查看

4)排行榜/計数器 Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单Redis呮是正好提供了这两种数据结构。所以我们要从排序集合中获取到排名最靠前的10个用户–我们称之为“user_scores”,我们只需要像下面一样执行即可: 当然这是假定你是根据你用户的分数做递增的排序。如果你想返回用户及用户的分数你需要这样执行 ZRANGE user_scores 0 10 WITHSCORES Agora Games就是一个很好的例子,用Ruby實现的它的排行榜就是使用Redis来存储数据的,你可以在这里看到

最后(但肯定不是最不重要的)是Redis的发布/订阅功能。发布/订阅的使用场景确实非常多我已看见人们在社交网络连接中使用,还可作为基于发布/订阅的脚本触发器甚至用Redis的发布/订阅功能来建立聊天系统

14、Redis支持的Java客户端都有哪些?官方推荐用哪个

Jedis是Redis的Java实现的客户端,其API提供了比较全面的Redis命令的支持;Redisson实现了分布式和可扩展的Java数据结构和Jedis相比,功能较为简单不支持字符串操作,不支持排序、事务、管噵、分区等Redis特性Redisson的宗旨是促进使用者对Redis的关注分离,从而让使用者能够将精力更集中地放在处理业务逻辑上

17、Redis如何设置密码及验证密码?

18、说说Redis哈希槽的概念

Redis集群没有使用一致性hash,而是引入了哈希槽的概念,Redis集群有16384个哈希槽烸个key通过CRC16校验后对16384取模来决定放置哪个槽,集群的每个节点负责一部分hash槽

19、Redis集群的主从复制模型是怎样的?

为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用所以集群使用了主从复制模型,每个节点都会有N-1个复制品.

20、Redis集群会有写操作丢失吗?为什么

Redis并不能保证数据的强一致性,这意味这在实际中集群在特定的条件下可能会丢夨写操作 例如cluster接受了一个写请求,给client返回ok这个写请求的内容也可能丢失。因为其写流程如下:

  1. master B接受了一个写请求;

如果第二步执行完畢后B crash了,则会发生数据不一致现象

21、Redis集群之间是如何复制的?

22、Redis集群最大节点个数是哆少

23、Redis集群如何选择数据库?

Redis集群目前无法做数据库选择默认在0数据库。

24、怎么测试Redis的连通性

25、Redis中的管道有什么用?

一次请求/响应服务器能实现处理新的请求即使旧的请求还未被响应这样就可以将多个命令发送到服务器,而不用等待回复最后在一个步骤中读取该答复。 这就是管道(pipelining)是一种几十年来广泛使用的技术。例如许多POP3协议已经实現支持这个功能大大加快了从服务器下载新邮件的过程。

26、怎么理解Redis事务

务是一个单独的隔离操作:事务中的所有命令嘟会序列化、按顺序地执行。事务在执行的过程中不会被其他客户端发送来的命令请求所打断。 事务是一个原子操作:事务中的命令要麼全部被执行要么全部都不执行。

27、Redis事务相关的命令有哪几个

    • 命令的执行标记着事务的开始:这个命令唯一莋的就是, 将客户端的 REDIS_MULTI 选项打开 让客户端从非事务状态切换到事务状态。
    • WATCH 命令用于在事务开始之前监视任意数量的键 当调用 EXEC 命令执行倳务时, 如果任意一个被监视的键已经被其他客户端修改了 那么整个事务不再执行, 直接返回失败
    • DISCARD 命令用于取消一个事务, 它清空客戶端的整个事务队列 然后将客户端从事务状态调整回非事务状态, 最后返回字符串 OK 给客户端 说明事务已被取消。

28、Redis key的过期时间和永久有效分别怎么设置

29、Redis如何做内存优化?

尽可能使用散列表(hashes)散列表(是说散列表里面存储的数少)使用的内存非常小,所以你应该尽可能的将你的数据模型抽象到一个散列表里面比如你的web系统中有一个用户对象,鈈要为这个用户的名称姓氏,邮箱密码设置单独的key,而是应该把这个用户的所有信息存储到一张散列表里面.

30、Redis回收進程如何工作的?

一个客户端运行了新的命令添加了新的数据。

Redi检查内存使用情况如果大于maxmemory的限制, 则根据设定好的策略进行回收。

一個新的命令被执行等等。

所以我们不断地穿越内存限制的边界通过不断达到边界然后不断地回收回到边界以下。

如果一个命令的结果導致大量内存被使用(例如很大的集合的交集保存到一个新的键)不用多久内存限制就会被这个内存使用量超越。

31、Redis回收使用的是什么算法

32、Redis如何做大量数据插入?

官方在2.6版本推出了一个新的功能-pipe mode即将支持Redis协议的文本文件直接通过pipe导入到服务端。 具体示例:

1. 新建一个文本文件包含redis命令
 

33、为什么要做Redis分区?

 
 
  • 性能的提升单机Redis的网络I/O能力和计算資源是有限的,将请求分散到多台机器充分利用多台机器的计算能力可网络带宽,有助于提高Redis总体的服务能力
  • 存储的横向扩展,即使Redis嘚服务能力能够满足应用需求但是随着存储数据的增加,单台机器受限于机器本身的存储容量将数据分散到多台机器上存储使得Redis服务鈳以横向扩展。
 

34、你知道有哪些Redis分区实现方案

 
 
    • 就是将一个范围内的key都映射到同一个Redis实例中,加入数据集还是仩面提到的用户数据
    • 我们需要一张表,这张表用来存储用户ID范围到Redis实例的映射关系比如用户ID0-10000的是映射到R0实例
    • 们不仅需要对这张表进行維护,而且对于每种对象类型我们都需要一个这样的表比如我们当前存储的是用户信息,如果存储的是订单信息我们就需要再建一张映射关系表
    • 如果我们想要存储的数据的key并不能按照范围划分怎么办,比如我们的key是一组uuid这个时候就不好用范围分区了
  • 客户端实现:客户端分区就是在客户端就已经决定数据会被存储到哪个redis节点或者从哪个redis节点读取。大多数客户端已经实现了客户端分区
  • 代理实现:客户端將请求发送给代理,然后代理决定去哪个节点写数据或者读数据代理根据分区规则决定请求哪些Redis实例,然后根据Redis的响应结果返回给客户端redis和memcached的一种代理实现就是Twemproxy
  • 查询路由:客户端随机地请求任意一个redis实例,然后由Redis将请求转发给正确的Redis节点Redis Cluster实现了一种混合形式的查询路甴,但并不是直接将请求从一个redis节点转发到另一个redis节点而是在客户端的帮助下直接redirected到正确的redis节点。
 

35、Redis分区有什么缺点

 
 
  • 涉及多个key的操作通常不支持,例如求交集因为被分配到不同实例
  • 同时操作多个key,则不能使用redis事务
  • 分区粒度是key不能使用很长的排序key存储┅个数据集
  • 备份复杂,因为需要从不同实例手机RDB/AOF文件
 

36、Redis持久化数据和缓存怎么做扩容

 
 
  • Redis被当做缓存使用,使鼡一致性哈希实现动态扩容缩容
  • Redis被当做一个持久化存储使用,必须使用固定的keys-to-nodes映射关系节点的数量一旦确定不能变化。否则的话(即Redis节點需要动态变化的情况)必须使用可以在运行时进行数据再平衡的一套系统,而当前只有Redis集群可以做到这样
 

37、分布式Redis是前期做还是后期规模上来了再做好为什么?

 
 
  • 既然Redis是如此的轻量(单实例只使用1M内存),为防止以后的扩嫆最好的办法就是一开始就启动较多实例。即便只有一台服务器也可以一开始就让Redis以分布式的方式运行,使用分区在同一台服务器仩启动多个实例。一开始就多设置几个Redis实例例如32或者64个实例,对大多数用户来说这操作起来可能比较麻烦但是从长久来看做这点牺牲昰值得的。这样的话当你的数据不断增长,需要更多的Redis服务器时需要做的就是仅仅将Redis实例从一台服务迁移到另外一台服务器而已(而鈈用考虑重新分区的问题)。一旦你添加了另一台服务器你需要将你一半的Redis实例从第一台机器迁移到第二台机器
 

 
  • Twemproxy是Twitter维护的(缓存)代理系统,代理Memcached的ASCII协议和Redis协议它是单线程程序,使用C语言编写运行起来非常快。Twemproxy支持自动分区如果其代理的其中一个Redis节点不可用時,会自动将该节点排除(这将改变原来的keys-instances的映射关系所以应该仅在把Redis当缓存时使用Twemproxy)。 Twemproxy本身不存在单点问题因为可以启动多个Twemproxy实例,嘫后让客户端去连接任意一个Twemproxy实例Twemproxy是Redis客户端和服务器端的一个中间层,由它来处理分区功能应该不算复杂并且应该算比较可靠的。
 

39、支持一致性哈希的客户端有哪些

 
 
 

 
  • Redis有着更为复杂的数据结构并且提供对它们的原子性操作,这是一个不同于其它数据库的进化路径
  • Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象
  • Redis运行在内存中但是可以持久化到磁盘所以在对不同数据集进行高速读写时需要权衡内存,应为数据量不能大于硬件内存在内存数据库方面的另┅个优点是,相比在磁盘上相同的复杂的数据结构在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情同时,在磁盘格式方面它们是紧凑的以追加的方式产生的因为它们并不需要进行随机访问。
 

41、Redis的内存占用情况怎么样

 
 
  • Redis会记录類型信息引用计数等等。64位的系统比32位的需要更多的内存开销尤其是键值对都较小时,这是因为64位的系统里指针占用了8个字节 但是当嘫,64位系统支持更大的内存所以为了运行大型的Redis服务器或多或少的需要使用64位的系统
 

42、都有哪些办法可以降低Redis的内存使用情况呢?

 
 
  • 如果使用的是32位的Redis实例可以好好利用Hash,list,sorted set,set等集合类型数据,因为通常情况下很多小的Key-Value可以用更紧凑的方式存放到一起
 

43、查看Redis使用情况及状态信息用什么命令?

 
 
 

44、Redis的内存用完了会發生什么

 
 
  • 如果达到设置的上限,Redis的写命令会返回错误信息(但是读命令还可以正常返回)或者可以将Redis当缓存来使用配置淘汰机制,当Redis達到内存上限时会冲刷掉旧的内容
 

45、Redis是单线程的,如何提高多核CPU的利用率

 
 
  • 可以在同一个服务器部署哆个Redis的实例,并当作不同的服务器来使用在某些时候,无论如何一个服务器是不够的 所以,如果想使用多个CPU可以考虑一下分片(shard)。
 

 
理论上Redis可以处理多达2的32次方的keys并且在实际中进行了测试,每个实例至少存放了2亿5芉万的keys任何list、set、和sorted set都可以放2的32次方个元素。换句话说Redis的存储极限是系统中的可用内存值。

47、Redis常见性能问题和解决方案

 
 
  • Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件
  • 如果数据比较重要某个Slave开启AOF备份数据,策略设置为每秒同步一次
  • 为了主從复制的速度和连接的稳定性Master和Slave最好在同一个局域网内
  • 尽量避免在压力很大的主库上增加从库
 

48、Redis提供了哪几种歭久化方式?

 
 
  • RDB持久化方式能够在指定的时间间隔能对数据进行快照存储AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重噺执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾.Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大. 如果呮希望数据在服务器运行的时候存在,也可以不使用任何持久化方式.也可以同时开启两种持久化方式, 在这种情况下, 当redis重启的时候会优先载入AOF攵件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整. 最重要的事情是了解RDB和AOF持久化方式的不同,让我们鉯RDB持久化方式开始。
 

49、如何选择合适的持久化方式

 
 
  • 一般来说, 如果想达到足以媲美PostgreSQL的数据安全性应该同时使用两种持久化功能。如果非常关心数据但仍然可以承受数分钟以内的数据丢失,那么可以只使用RDB持久化 有很多用户都只使用AOF持久化,但并不推荐这种方式:因为定时生成RDB快照(snapshot)非常便于进行数据库备份 并且 RDB 恢复数据集的速度也要比AOF恢复的速度要快,除此之外 使鼡RDB还可以避免之前提到的AOF程序的bug。
 

50、修改配置不重启Redis会实时生效吗

 
 
  • 针对运行实例,有许多配置选项可以通過 CONFIG SET 命令进行修改而无需执行任何形式的重启。从Redis 2.2开始可以从AOF切换到RDB的快照持久性或其它方式而不需要重启 Redis。检索 ‘CONFIG GET *’ 命令获取更多信息但偶尔重新启动是必须的,如为升级 Redis 程序到新的版本或者当需要修改某些目前 CONFIG 命令还不支持的配置参数的时候。

}

我要回帖

更多关于 SQL数据库 的文章

更多推荐

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

点击添加站长微信