Java****面试宝典(数据库篇)
Redis
**1.**使用Redis有哪些好处?
(1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)
(2) 支持丰富数据类型,支持string,list,set,sorted set,hash
(3) 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
(4) 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除
2. redis****相比memcached有哪些优势?
(1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型
(2) redis的速度比memcached快很多
(3) redis可以持久化其数据
3. redis****常见性能问题和解决方案:
(1) Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件
(2) 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次
(3) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内
(4) 尽量避免在压力很大的主库上增加从库
(5) 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master<- Slave1 <- Slave2 <- Slave3…
这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。
4.MySQL****里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据
相关知识:redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis 提供 6种数据淘汰策略:
voltile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
no-enviction(驱逐):禁止驱逐数据
5. Memcache****与Redis的区别都有哪些?
1)、存储方式
Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。
Redis有部份存在硬盘上,这样能保证数据的持久性。
2)、数据支持类型
Memcache对数据类型支持相对简单。
Redis有复杂的数据类型。
3)、使用底层模型不同
它们之间底层实现方式 以及与客户端之间通信的应用协议不一样。
Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。
4),value大小
redis最大可以达到1GB,而memcache只有1MB
**6. Redis **常见的性能问题都有哪些?如何解决?
1).Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照。
2).Master AOF持久化,如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件过大会影响Master重启的恢复速度。Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化,如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。
3).Master调用BGREWRITEAOF重写AOF文件,AOF在重写的时候会占大量的CPU和内存资源,导致服务load过高,出现短暂服务暂停现象。
4). Redis主从复制的性能问题,为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内
**7, redis **最适合的场景
Redis最适合所有数据in-momory的场景,虽然Redis也提供持久化功能,但实际更多的是一个disk-backed的功能,跟传统意义上的持久化有比较大的差别,那么可能大家就会有疑问,似乎Redis更像一个加强版的Memcached,那么何时使用Memcached,何时使用Redis呢?
如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点:
1 、Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
2 、Redis支持数据的备份,即master-slave模式的数据备份。
3 、Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
(1)、会话缓存(Session Cache)
最常用的一种使用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 10WITHSCORES
Agora Games就是一个很好的例子,用Ruby实现的,它的排行榜就是使用Redis来存储数据的,你可以在这里看到。
(5)、发布/订阅
最后(但肯定不是最不重要的)是Redis的发布/订阅功能。发布/订阅的使用场景确实非常多。我已看见人们在社交网络连接中使用,还可作为基于发布/订阅的脚本触发器,甚至用Redis的发布/订阅功能来建立聊天系统!(不,这是真的,你可以去核实)。
Redis提供的所有特性中,我感觉这个是喜欢的人最少的一个,虽然它为用户提供如果此多功能。
8, redis****有时候会请求超时,已知都是固定的一个时间,比如200ms或者500ms,问这是为什么?
请求redis超时,如果时间较长,比如60s或者75s这样的,可能是redis的timeout配置。目前是时间较短,200ms就超时,一般来说redis没道理在能处理请求的时候报超时错误,会否是现在超过了redis设置的最大连接数maxclients,导致拒绝服务;会否是client自身的连接超时设置。无论如何,CS模式的两端都有可能是原因
Mysql
1.sql****语句应该考虑哪些安全性?(新浪网技术部)
防止Sql注入,对特殊字符进行转义、过滤或者使用预编译的sql语句绑定变量。
最小权限原则,特别是不要用 root 账户,为不同的类型的动作或者组建使用不同的账户。
当 sql 运行出错时,不要把数据库返回的错误信息全部显示给用户,以防止泄露服务器和数据库相关信息。
**2.**简单描述mysql中,索引,主键,唯一索引,联合索引的区别,对数据库的性能有什么影响(从读写两方面)(新浪网技术部)
索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。
普通索引(由关键字KEY或INDEX定义的索引)的唯一任务是加快对数据的访问速度。
普通索引允许被索引的数据列包含重复的值。如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该用关键字UNIQUE把它定义为一个唯一索引。也就是说,唯一索引可以保证数据记录的唯一性。
主键,是一种特殊的唯一索引,在一张表中只能定义一个主键索引,主键用于唯一标识一条记录,使用关键字 PRIMARY KEY 来创建。
索引可以覆盖多个数据列,如像INDEX(columnA, columnB)索引,这就是联合索引。
索引可以极大的提高数据的查询速度,但是会降低插入、删除、更新表的速度,因为在执行这些写操作时,还要操作索引文件。
另外mysql给某字段建立索引以后,where查询时这个字段等于或or或like时索引是不会生效的。
**3.**有一个留言板,用mysql做数据库,用户信息包括:用户名,密码,email,留言内容包括:留言ID,标题,内容,发表时间,状态(新浪网技术部)请实现下列需求:
(1).数据库结构。无需写建表语句,用类似下面的表格,描述清楚即可,注意,要在索引栏中注明是否需要创建索引,以及要创建的索引的类型
表名 | table_aaa | ||
---|---|---|---|
字段名 | 字段说明 | 字段类型 | 索引 |
name | 姓名 | varchar(64) | 唯一索引 |
gender | 性别 | enum(‘M’,‘F’) |
(2).用一个sql语句查询出发表留言数量大于10条的用户名及其留言数量,查询结果按文章数量降序排列参考答案:用户表结构如下:
表名 | user | ||
---|---|---|---|
字段名 | 字段说明 | 字段类型 | 索引 |
user_id | 用户编号 | int unsigned | 主键 |
name | 用户名 | varchar(30) | |
password | 密码 | char(32) | |
邮箱 | varchar(50) |
留言表结构如下:
表名 | message | ||
---|---|---|---|
字段名 | 字段说明 | 字段类型 | 索引 |
message_id | 留言编号 | int unsigned | 主键 |
title | 标题 | varchr(100) | |
content | 内容 | text | |
user_id | 用户 id | int unsigned | 普通索引 |
pubtime | 发表时间 | int unsigned | |
state | 状态 | tinyint 0 未审核 1 审核 |
查询语句如下:
SELECTu.name, COUNT(*) AS total
FROMuser AS u INNER JOIN message AS m
ONu.user_id = m.user_id
GROUPBY u.name
HAVINGtotal > 10
ORDERBY total DESC
**4.**两张表 city表和province表。分别为城市与省份的关系表。
city:
id | city | provinceid |
---|---|---|
1 | 广州 | 1 |
2 | 深圳 | 1 |
3 | 惠州 | 1 |
4 | 长沙 | 2 |
5 | 武汉 | 3 |
province:
id | province |
---|---|
1 | 广东 |
2 | 湖南 |
3 | 湖北 |
(1). 写一条sql语句关系两个表,实现:显示城市的基本信息。
显示字段:城市id ,城市名, 所属省份 。如:
id(城市id) cityname(城市名)privence(所属省份)
……
SELECTc.id AS id,c.city AS cityname,p.province
FROMcity c LEFT JOIN province p ON c.provinceid=p.id
(2). 如果要统计每个省份有多少个城市,请用group by 查询出来。
显示字段:省份id ,省份名,包含多少个城市。
SELECTp.id,p.province,count(c.id) AS num
FROMprovince p LEFT JOIN city c ON p.id = c.provinceid
GROUPBY p.id;
5.MySQL****数据库中的字段类型varchar和char的主要区别是什么?哪种字段的查找效率要高,为什么?
区别一,定长和变长
char 表示定长,长度固定,varchar表示变长,即长度可变
当所插入的字符串超出它们的长度时,视情况来处理,如果是严格模式,则会拒绝插入并提示错误信息,如果是宽松模式,则会截取然后插入。如果插入的字符串长度小于定义长度时,则会以不同的方式来处理,如char(10),表示存储的是10个字符,无论你插入的是多少,都是10个,如果少于10个,则用空格填满。而varchar(10),小于10个的话,则插入多少个字符就存多少个。varchar怎么知道所存储字符串的长度呢?实际上,对于varchar 字段来说,需要使用一个(如果字符串长度小于255)或两个字节(长度大于255)来存储字符串的长度。
区别之二,存储的容量不同对char来说,最多能存放的字符个数 255,和编码无关。
而varchar呢,最多能存放 65532 个字符。
VARCHAR的最大有效长度由最大行大小和使用的字符集确定。整体最大长度是65,532 字节
最大有效长度是 65532 字节,在varchar存字符串的时候,第一个字节是空的,不存任何的数据,然后还需要两个字节来存放字符串的长度。所以有效长度就是 65535 - 1 - 2
= 65532
由字符集来确定,字符集分单字节和多字节
Latin1一个字符占一个字节,最多能存放 65532个字符
GBK一个字符占两个字节,最多能存 32766 个字符 UTF8一个字符占三个字节, 最多能存 21844 个字符注意,char和varchar 后面的长度表示的是字符的个数,而不是字节数。
两相比较,char的效率高,没有碎片,尤其更新比较频繁的时候,方便数据文件指针
的操作。但不够灵活,在实际使用时,应根据实际需求来选用合适的数据类型。
相关题目:若一个表定义为 **create table t1(c int, c2char(30), c3 varchar(N)) charset=utf8; **问
**N **的最大值又是多少?(65535 - 1 - 2 - 4 - 30 *3 )/3
**6.**设有成绩表如下所示,查询两门及两门以上不及格同学的平均分。
编号 | 姓名 | 科目 | 分数 |
---|---|---|---|
1 | 张三 | 数学 | 90 |
2 | 张三 | 语文 | 50 |
3 | 张三 | 地理 | 40 |
4 | 李四 | 语文 | 55 |
5 | 李四 | 政治 | 45 |
6 | 王五 | 政治 | 30 |
#创建一个成绩表
CREATETABLE grade( id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, nameVARCHAR(10) NOT NULL, subject VARCHAR(10) NOT NULL, score TINYINT UNSIGNED NOTNULL
);
#插入记录
INSERTINTO grade(name,subject,score) VALUES(‘张三’,‘数学’,90);
INSERTINTO grade(name,subject,score) VALUES(‘张三’,‘语文’,50);
INSERTINTO grade(name,subject,score) VALUES(‘张三’,‘地理’,40);
INSERTINTO grade(name,subject,score) VALUES(‘李四’,‘语文’,55);
INSERTINTO grade(name,subject,score) VALUES(‘李四’,‘政治’,45);
INSERTINTO grade(name,subject,score) VALUES(‘王五’,‘政治’,30);
#查询语句
SELECTname,AVG(score),SUM(score<60) AS gk
FROMgrade
GROUPBY name HAVING gk>=2;
**7.**为了记录足球比赛的结果,设计表如下, team:参赛队伍表
字段名称 | 类型 | 描述 |
---|---|---|
teamID | int | 主键 |
teamname | varchar(20) | 队伍名称 |
match:赛程表
字段名称 | 类型 | 描述 |
---|---|---|
matchID | int | 主键 |
hostTeamID | int | 主队的 ID |
gusetTeamID | int | 客队的 ID |
marchResult | varchar(20) | 比赛结果 |
matchTime | date | 比赛日期 |
其中,match 赛程表中的 hostTeamID 与 guestTeamID 都和 team 表中的 teamID 关联,查出
2006-6-1到 2006-7-1 之间举行的所有比赛,并且用以下形式列出:拜仁 2:0 不莱梅 2006-6-21
#创建参赛队伍表
CREATETABLE team( teamID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, teamNameVARCHAR(30) NOT NULL
);
#向参赛队伍表中插入记录
INSERTINTO team(teamName) VALUES(‘拜仁’);
INSERTINTO team(teamName) VALUES(‘不莱梅’);
INSERTINTO team(teamName) VALUES(‘皇家马德里’);
INSERTINTO team(teamName) VALUES(‘巴塞罗那’);
INSERTINTO team(teamName) VALUES(‘切尔西’);
INSERTINTO team(teamName) VALUES(‘曼联’);
INSERTINTO team(teamName) VALUES(‘AC 米兰’);
INSERTINTO team(teamName) VALUES(‘国际米兰’);
#创建 match 赛程表
CREATETABLE mat( matchID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEy, hostTeamIDINT UNSIGNED NOT NULL, guestTeamID INT UNSIGNED NOT NULL, matchResultVARCHAR(20) NOT NULL, matchTime DATE NOT NULL
);
#向赛程表中插入几条记录
INSERTINTO mat(hostTeamID,guestTeamID,matchResult,matchTime)
VALUES(1,2,‘3:1’,‘2006-6-15’);
INSERTINTO mat(hostTeamID,guestTeamID,matchResult,matchTime)
VALUES(3,4,‘2:2’,‘2006-6-28’);
INSERTINTO mat(hostTeamID,guestTeamID,matchResult,matchTime)VALUES(5,6,‘0:2’,‘2006-7-10’);
INSERTINTO mat(hostTeamID,guestTeamID,matchResult,matchTime)
VALUES(7,8,‘5:3’,‘2006-5-30’);
#查询语句
SELECTt1.teamName,matchResult,t2.teamName,matchTime FROM mat
LEFTJOIN team AS t1
ONhostTeamID = t1.teamID
LEFTJOIN team AS t2
ONguestTeamID = t2.teamID
WHEREmatchTime BETWEEN ‘2006-6-1’ AND ‘2006-7-1’;
**8.**请简述项目中优化sql语句执行效率的方法?
尽量选择较小的列
将where中用的比较频繁的字段建立索引
select子句中避免使用‘*’
避免在索引列上使用计算、not in 和<>等操作
当只需要一行数据的时候使用limit 1
保证单表数据不超过200W,适时分割表。针对查询较慢的语句,可以使用explain 来分析该语句具体的执行情况。
避免改变索引列的类型。
选择最有效的表名顺序,from字句中写在最后的表是基础表,将被最先处理,在from子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。
避免在索引列上面进行计算。****
尽量缩小子查询的结果****
**9.**使用java写一段简单查询,查出所有姓名为“张三”的内容并打印出来
表 user | ||
---|---|---|
name tel | content | date |
张三 13333663366 | 大专毕业 | 2006-10-11 |
张三 13612312331 | 本科毕业 | 2006-10-15 |
张四 021-55665566 | 中专毕业 | 2006-10-15 |
请根据上面的题目完成代码:
select* from user where name=‘张三’
**10.**写出 SQL语句的格式 : 插入 ,更新 ,删除 (卓望)
表名 user
name tel content date
张三 13333663366 大专毕业 2006-10-11 张三 13612312331 本科毕业 2006-10-15张四 021-55665566 中专毕业 2006-10-15
(a).有一新记录(小王 13254748547 高中毕业2007-05-06)请用SQL语句新增至表中
(b).请用sql语句把张三的时间更新成为当前系统时间 ©.请写出删除名为张四的全部记录
INSERT INTOuser(name,tel,content,date)VALUES(‘小王’,‘13254748547’,'高中毕业
',‘2007-05-06’);
UPDATE userSET date = date_format(now(),’%Y-%m-%d’) WHERE name = ‘张三’
DELETE FROMuser WHERE name = ‘张四’
**11.**数据库中的事务是什么?
事务(transaction)是作为一个单元的一组有序的数据库操作。如果组中的所有操作都成功,则认为事务成功,即使只有一个操作失败,事务也不成功。如果所有操作完成,事务则提交,其修改将作用于所有其他数据库进程。如果一个操作失败,则事务将回滚,该事务所有操作的影响都将取消。ACID 四大特性,原子性、隔离性、一致性、持久性。
**12.**从表 login 中选出 name 字段包含 admin 的前10 条结果所有信息的 sql 语句 (酷讯)
SELECT* FROM login WHERE name LIKE ‘%admin%’LIMIT10;
**13.**表中有A B C三列,用SQL语句实现:当A列大于B列时选择A列,否则选择B列,当 B列大于C列时选择B列否则选择C列。
使用case语句,如下:
SELECT CASE WHENA > B THEN A ELSE B END,
CASE WHEN B> C THEN B ELSE C END
FROM table
**14.**取得最新一次添加记录(假设id为主键,并且是自增类型)所产生的id的函数是什么?
mysqli_insert_id();如果上一查询没有产生 AUTO_INCREMENT 的值,则 mysqli_insert_id() 返回 0。
**15.**在平常mysql优化方面,最基本的也是最重要的优化是()。(奇矩互动)
查询优化
**16.**用户互为好友的SNS存储结构怎么设计。(亿邮)
首先是有用户表,如下:
CREATETABLE user( id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, usernameVARCHAR(30) NOT NULL DEFAULT ‘’ COMMENT ‘用户名’, email VARCHAR(50) NOT NULLDEFAULT ‘’ COMMENT ‘邮箱’, password CHAR(32) NOT NULLDEFAULT ‘’ COMMENT ‘密码’
)engine=MyISAMcharset=utf8 comment=‘用户表’;
其次是用户间的关系,如下:
CREATETABLE relation( rel_id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, fuidINT UNSIGNED NOT NULL COMMENT ‘关注人的 id’, suid INT UNSIGNED NOTNULL COMMENT ‘被关注人的 id’, relation_type ENUM(‘S’,‘D’)NOT NULL DEFAULT ‘S’ COMMENT '关系,s 为关注,
d 表示为好友’
)engine=MyISAMcharset=utf8 comment=‘用户关系表’;
**17.**假设现在有一个数据库服务器,服务器地址为192.168.0.110,用户名为 root 密码为password 请使用 java编写一个连接该数据库的代码 (亿邮)
**18.**简述在MySQL数据库中MyISAM和InnoDB的区别 (亿邮)
区别于其他数据库的最重要的特点就是其插件式的表存储引擎。切记:存储引擎是基于表的,而不是数据库。
InnoDB与MyISAM的区别:
InnoDB存储引擎,主要面向OLTP(Online Transaction Processing,在线事务处理)方面的应用,是第一个完整支持ACID事务的存储引擎(BDB第一个支持事务的存储引擎,已经停止开发)。
特点:
行锁设计、支持外键;
支持类似于Oracle风格的一致性非锁定读(即:默认情况下读取操作不会产生锁);
InnoDB将数据放在一个逻辑的表空间中,由InnoDB自身进行管理。从MySQL4.1版本开始,可以将每个InnoDB存储引擎的表单独存放到一个独立的ibd文件中;
InnoDB通过使用MVCC(多版本并发控制:读不会阻塞写,写也不会阻塞读)来获得高并发性,并且实现了SQL标准的4种隔离级别(默认为REPEATABLE级别);
InnoDB还提供了插入缓冲(insert buffer)、二次写(double write)、自适应哈希索引(adaptive hash index)、预读(read ahead)等高性能和高可用的功能;
InnoDB采用了聚集(clustered)的方式来存储表中的数据,每张标的存储都按主键的顺序存放(如果没有显式的在建表时指定主键,InnoDB会为每一行生成一个6字节的ROWID,并以此作为主键);
InnoDB表会有三个隐藏字段:除了上面提到了6字节的DB_ROW_ID外,还有6字节的DB_TX_ID(事务ID)和7字节的DB_ROLL_PTR(指向对应回滚段的地址)。这个可以通过innodb monitor看到;
MyISAM存储引擎是MySQL官方提供的存储引擎,主要面向OLAP(Online Analytical Processing,在线分析处理)方面的应用。
特点:
不支持事务,支持表所和全文索引。操作速度快;
MyISAM存储引擎表由MYD和MYI组成,MYD用来存放数据文件,MYI用来存放索引文件。MySQL数据库只缓存其索引文件,数据文件的缓存交给操作系统本身来完成;
MySQL5.0版本开始,MyISAM默认支持256T的单表数据;
**19.**现在有下面一个查询语句 select *from tabname where id=2 and password='abc’如何判断它是现在是最优的。(亿邮)
可以使用 explain select * from tabname where id=2 andpassword='abc’来分析其执行情况。
相关题目:谈一下对explain工具的理解,以及其中的一些参数的意义?
explain 是一个mysql的分析语句的一个小工具。
explain可以帮助开发人员分析SQL语句,用explain显示mysql如何使用索引来处理SQL语句连接表,处理表,以帮助开发人员写出更好的SQL语句,更高效的SQL语句。
你在查询的时候,如果你的SQL语句写出来来了,SQL解析引擎会决定如何进行处理,是否使用索引或者进行全表扫描。如果是全表扫描,那么你这个效率就非常。学习explain重点就是会查看对应的一引起信息。帮助我们分析如何写出更好的SQL语句,如果是非特殊情况,尽量不要出现全表扫描的情况。这样,效率太低了。
simple | 简单的select,不使用union |
---|---|
primary | 最外面的select |
union | union中的第二个或者后面的select |
dependent union | union中引二个或者后面的select,取决于外面的查询 |
union result | union的结果 |
dependent subquery | 查询中的第一个select |
derived | 导出的select |
type在这里面是一个非常重要的指标,决定了它的扫描类型。
ALL | index | range | ref | eq_ref | const,system | null |
---|---|---|---|---|---|---|
distinct: 一旦mysql找到了与行所匹配的行,就不再搜索了
not exists:mysql 优化了left join,一旦找到他left join所匹配的行,就不搜搜索
range checked foreach record:没有找到理想的索引。
using filesort:查询就需要优化了。mysql需要进行更多额外的步骤,来对返回的内容进行排序。
using index:列数据仅仅从索引中进行读取。而没有真正的读取行,所返回的数据。你当前查的结果和查的字段都在索引。
where used:限制哪些行或者其他的表的数据返回给用户。
system:表示system表,这是const连接类型特殊情况。
const:表中的一个最大记录能够匹配这个查询,因为只有一行,所有这个值通常是个const常数。
eq_ref:MySQL在查询时,从前面的表中,对每一条记录联合读取。它使用索引为主键 或者为唯一索引时使用。
ref: 这个查询只查询使用了不是唯一或者主键时的查询发生。
range: 返回一个区间的查询。
ALL: 就尽量避免,因为全表扫描。
注意:
\1. 不要让索引字段参与了运算。
\2. 查询的时候使用有索引的字段
\3. 索引不是越多越好,索引太多会造成写入和修改速度变慢
\4. 少用or,因为用了容易全表扫描。
\5. 不要真实的删除数据,使用软删除删除数据
\6. 对于innodb表不要使用count进行查询总数,或者使用一个计数器去统计数量。
**20.**请问如何在Mysql操作中如何写入utf8格式数据 (亿邮)
首先确保数据库中的表是基于utf8编码的,其次java文件是utf8编码,在执行mysql 操作之前,对于要操作的文本如果是utf8 编码,则可以直接操作,如果是其它编码,则可以使用函数将其转化为utf8编码,然后写入。
**21.mysql **中varchar的最大长度是多少?用什么类型的字段存储大文本?date 和 datetime和timestamp什么区别?怎么看数据库中有哪些sql正在执行? (卓望)
varchar的最大有效长度由最大行大小和使用的字符集确定。整体最大长度是65532字节。在varchar存字符串的时候,第一个字节是空的,不存任何的数据,然后还需要两个字节来存放字符串的长度。所以有效长度就是 65535 - 1 - 2 = 65532。
由字符集来确定,字符集分单字节和多字节,如果是单字节,如 latin1,则最多可以存放65532个字符,如果是多字节,如GBK则可以存放32766个字符,UTF8则可以存放21844 个字符。
存储大文本可以使用text类型。
date表示日期,其范围为 1000-01-01 ~ 9999-12-31
datetime表示日期时间,其范围为 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59
timestamp 是 unix 时间戳的日期时间表示方式,其范围较小为 1970-01-01
00:00:00~2038-01-1903:14:07 ,timestamp具备自动初始化和自动更新功能。
查看数据库中正在执行的 sql 语句可以使用日志,也可以使用 show processlist 命令。
**22.**对于关系型数据库而言,索引是相当重要的概念,请回答有关索引的几个问题:
a)、索引的目的是什么?
1.快速访问数据表中的特定信息,提高检索速度
2.创建唯一性索引,保证数据库表中每一行数据的唯一性。
3.加速表和表之间的连接
4.使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间
b)、索引对数据库系统的负面影响是什么?
负面影响:创建索引和维护索引需要耗费时间,这个时间随着数据量的增加而增加;索引需要占用物理空间,不光是表需要占用数据空间,每个索引也需要占用物理空间;当对表进行增、删、改、的时候索引也要动态维护,这样就降低了数据的维护速度。
c)、为数据表建立索引的原则有哪些?
1、在最频繁使用的、用以缩小查询范围的字段上建立索引。
2、在频繁使用的、需要排序的字段上建立索引
d)、 什么情况下不宜建立索引?
1、对于查询中很少涉及的列或者重复值比较多的列,不宜建立索引。
2、对于一些特殊的数据类型,不宜建立索引,比如文本字段(text)等。
**23.**请举例说明在你的开发中用什么方法来加快页面的加载速度?
要用到服务器资源时才打开,及时关闭服务器资源,数据库添加索引,页面可生成静态,图片等大文件单独服务器。使用代码优化工具。
24.如何设计或配置Mysql,才能达到高效使用的目的?
1、数据库设计方面,设计结构良好的数据库,允许部分数据冗余。选取最适用的字段属性,尽可能把字段设置为NOTNULL,这样在查询的时候,数据库不用去比较NULL值。
2、系统架构设计方面,表散列,把海量数据散列到几个不同的表里面,集群,数据库查询和写入分开。
写高效的sql语句,以提高效率。
使用连接(join)来代替子查询。
使用联合(union)来代替手动创建的临时表。
所得皆必须,只从数据库取必须的数据。
必要的时候用不同的存储引擎,比如Innodb 可以减少死锁,HEAP可以提高一个数量级的查询速度。
使用事务
使用外键
使用索引。
**25.**设定网站的用户数量在千万级,但是活跃用户的数量只有1%,如何通过优化数据库提高活跃用户的访问速度?
我们可以根据用户的活跃程度,把活跃的用户提取出来放到另外一张表里面,每次活跃的用户登录的时候就直接到活跃用户表中进行查询,这样就提高了数据库的查询速度。
26.SQL****注入漏洞产生的原因?如何防止?
SQL注入产生的原因:程序开发过程中不注意规范书写sql语句和对特殊字符进行过滤,导致客户端可以通过全局变量POST和GET提交一些sql语句正常执行。
防止SQL注入的方式:
1、 开启配置文件中的magic_quotes_gpc 和magic_quotes_runtime设置
2、 执行sql语句时使用addslashes进行sql语句转换
3、 Sql语句书写尽量不要省略双引号和单引号。
4、 过滤掉sql语句中的一些关键词:update、insert、delete、select、 * 。
5、 提高数据库表和字段的命名技巧,对一些重要的字段根据程序的特点命名,取不易被猜到的。
6、 控制错误信息,不要在浏览器上输出错误信息,将错误信息写到日志文件中。
**27.**你常用到的 mysql 命令?
Show databases
Show tables
Insert into 表名() values()
Update 表名 set 字段=值 where …
Delete from 表名 where …
Select * from 表名 where 条件 order by …
Desc/asc limit … Group by …Having …
28.mysql****常用命令的应用?
进入 l mysql 管理命令行的命令?
Mysql -uroot-p 回车 密码
**show databases; **这个命令的作用?
显示当前 mysql 服务器中有哪些数据库
**show create database mysql; **这个命令的作用?
显示创建数据库的 sql 语句
**show create table user; **这个命令的作用?
显示创建表的 sql 语句
** desc user; **这个命令的作用?
查询 user 表的结构
** explain select * from user; **这个命令的作用?
获取 select 相关信息
** showprocesslist; **这个命令的作用?
显示哪些线程正在运行
** SHOW VARIABLES; **这个命令的作用?
显示系统变量和值
**SHOW VARIABLES like **’ %conn% ’ 这个命令的作用?
显示系统变量名包含 conn 的值
**LEFT JOIN **写一个 SQL 语句?
SELECTA.id,A.class FROM A LEFT JOIN B ON A.cid=B.id
**29.**优化 Mysql 数据库的方法 ?
第一、优化索引、SQL语句、分析慢查询
第二、设计表的时候严格按照数据库的设计范式来设计数据库
第三、我们可以加上memcached缓存,将经常被访问到的数据,但是不需要经常变化的数据放入至memcached缓存服务器里面,这样的话能够节约太强盘I/0(昨天)
第四、还可优化硬件,在硬件层面,我们可以使用更好的一些硬盘(固态硬盘),使用一些磁盘阵列技术(raid0,raid1,raid5)
raid0 最简单的 (两块硬盘硬盘相加100G + 100 G = 200G)
raid1 镜像卷 把同样的数据写两份。可以随机从A/B里面读取,更高。硬盘坏了一块,数据也不会丢失
raid5 3块硬盘,坏了一块,另外两块也能工作。
第五、如果以上都做速度还是慢,先不要去切分可以使用MySQL内部自带的表分区技术,来将数据分成不同的文件。这样能够让磁盘在读取的时候效率更高。
第六、可以再做垂直分表,可以将不经常读数据放到另外一个表里面去。这样能够节约磁盘IO
第七、如果发现我们的效率还是不够高,我们可以采用主从的方式来将数据读写分离。
第八、数据量特别大,我们优化起来会很困难可以使数数据库中间件的方式,将数据进行分库分表分机器。(原理,数据路由)
第九、此外,我们还可以采用一些更快的存储方式,例如NoSQL来存储一些我们需要经常访问到的数据。从数据库里面取出来后,再到NoSQL取出一些其他的数据。
第十、此外还有一些表引擎 选择,参数优化和一些相关小技巧都是优化MySQL的方式
第十一、我们还可以将我们的业务系统在架构级别进行缓存,静态化和分式式。
第十二、不使用全文索引,使用xunsearch,ES或者云服务器上的索引。
**30.**什么是JDBC? 解释下驱动(Driver)在JDBC中的角色。
JDBC是允许用户在不同数据库之间做选择的一个抽象层。JDBC允许开发者用JAVA写数据库应用程序,而不需要关心底层特定数据库的细节。
JDBC驱动提供了特定厂商对JDBC API接口类的实现,驱动必须要提供java.sql包下面这些类的实现:Connection, Statement,PreparedStatement,CallableStatement, ResultSet和Driver。
**31.Class.forName()****方法有什么作用? **
初始化参数指定的类,并且返回此类对应的Class 对象
32.PreparedStatement****比Statement有什么优势?
PreparedStatements是预编译的,因此,性能会更好。同时,不同的查询参数值,PreparedStatement可以重用。
**33.**数据库连接池是什么意思? 说出数据连接池的工作机制是什么?
像打开关闭数据库连接这种和数据库的交互可能是很费时的,尤其是当客户端数量增加的时候,会消耗大量的资源,成本是非常高的。可以在应用服务器启动的时候建立很多个数据库连接并维护在一个池中。连接请求由池中的连接提供。在连接使用完毕以后,把连接归还到池中,以用于满足将来更多的请求。
J2EE服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。
调用:客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量有配置参数决定。
释放:当使用的池连接调用完成后,池驱动程序将此连接表记为空闲,其他调用就可以使用这个连接。
34.DBUtils****是什么?
DbUtils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,使用它能够简化JDBC应用程序的开发,同时也不会影响程序的性能。
**35.**下面哪个SQL命令用来向表中添加列()
A.MODIFY TABLE TableName ADD COLUMN ColumnName
B.MODIFY TABLE TableName ADD ColumnName
C.ALTER TABLE TableName ADD COLUMN ColumnName
D.ALTER TABLE TableName ADD ColumnName Type
答:D
**36.**数据库中的事务是什么?
事务(transaction)是作为一个单元的一组有序的数据库操作。如果组中的所有操作都成功,则认为事务成功,即使只有一个操作失败,事务也不成功。如果所有操作完成,事务则提交,其修改将作用于所有其他数据库进程。如果一个操作失败,则事务将回滚,该事务所有操作的影响都将取消。ACID 四大特性,原子性、隔离性、一致性、持久性。
**37.**请问如何在Mysql操作中写入utf8格式数据 (亿邮)
首先确保数据库中的表是基于utf8编码的,其次java文件是utf8编码,在执行mysql 操作之前,对于要操作的文本如果是utf8 编码,则可以直接操作,如果是其它编码,则可以使用函数将其转化为utf8编码,然后写入。
38.update****和saveOrUpdate的区别?
update()和saveOrUpdate()是用来对跨Session的PO进行状态管理的。
update()方法操作的对象必须是持久化了的对象。也就是说,如果此对象在数据库中不存在的话,就不能使用update()方法。
saveOrUpdate()方法操作的对象既可以使持久化了的,也可以使没有持久化的对象。如果是持久化了的对象调用saveOrUpdate()则会 更新数据库中的对象;如果是未持久化的对象使用此方法,则save到数据库中。
**39.**如果某段与数据库交互的程序运行较慢你将如何处理?
一是首先提高数据库的查询速度,比如增加索引,优化表的结构。
二是优化程序代码,如果查询比较多,可以尽量用条件查询,减少查询语句,比如能用一条查询语句就不用两条。
三就是提高服务器的速度,优化服务器,把不必要的进程关掉。
**40.**以下哪个不是与Mysql服务器相互作用的通讯协议()
A.TCP/IP B.UDP C.共享内存 D.Socket
答: B
**41.**下面有关jdbc statement的说法错误的是?
A.JDBC提供了Statement、PreparedStatement 和 CallableStatement三种方式来执行查询语句,其中 Statement 用于通用查询, PreparedStatement 用于执行参数化查询,而CallableStatement则是用于存储过程
B.对于PreparedStatement来说,数据库可以使用已经编译过及定义好的执行计划,由于 PreparedStatement 对象已预编译过,所以其执行速度要快于 Statement对象”
C.PreparedStatement中,“?” 叫做占位符,一个占位符可以有一个或者多个值
D.PreparedStatement可以阻止常见的SQL注入式攻击
答: C
**42.**下面哪一项不是加载驱动程序的方法?
A.通过DriverManager.getConnection方法加载
B.调用方法 Class.forName
C.通过添加系统的jdbc.drivers属性
D.通过registerDriver方法注册
答: A