标签:否则 jpg 数据库服务器 情况 tab primary next drive customer
以下是对面试常见面试题整理,来自知乎大神分享的pdf,引用部分链接已给出,如果有没有标注的,纯属意外,希望提醒。这篇主要整理出来给自己看的
B/B+树
B树中的每个结点根据实际情况可以包含大量的关键字信息和分支(当然是不能超过磁盘块的大小,根据磁盘驱动(disk drives)的不同,一般块的大小在1k~4k左右);这样树的深度降低了,这就意味着查找一个元素只要很少结点从外存磁盘中读入内存,很快访问到要查找的数据
代码定义:
B树优势
高度比平衡树低,所以IO磁盘操作次数少,查找更快
当B树包含N个关键字时,B树的最大高度为l-1(因为计算B树高度时,叶结点所在层不计算在内),即:l - 1 = log┌m/2┐((N+1)/2 )+1。
B+-tree的磁盘读写代价更低:
B+-tree的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对B 树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说IO读写次数也就降低了。
举个例子,假设磁盘中的一个盘块容纳16bytes,而一个关键字2bytes,一个关键字具体信息指针2bytes。一棵9阶B-tree(一个结点最多8个关键字)的内部结点需要2个盘快。而B+ 树内部结点只需要1个盘快。当需要把内部结点读入内存中的时候,B 树就比B+ 树多一次盘块查找时间(在磁盘中就是盘片旋转的时间)。
B+-tree的查询效率更加稳定:
由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。
在MySQL中,索引属于存储引擎级别的概念,不同存储引擎对索引的实现方式是不同的,这里主要讨论MyISAM和InnoDB两个存储引擎的索引实现方式
索引
MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址。下图是MyISAM索引的原理图
假设我们以Col1为主键,则图8是一个MyISAM表的主索引(Primary key)示意。可以看出MyISAM的索引文件仅仅保存数据记录的地址。在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复
MyISAM的索引方式也叫做“非聚集”的,之所以这么称呼是为了与InnoDB的聚集索引区分。
虽然InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同。
了解不同存储引擎的索引实现方式对于正确使用和优化索引都非常有帮助,例如知道了InnoDB的索引实现后,就很容易明白为什么不建议使用过长的字段作为主键,因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大。再例如,用非单调的字段作为主键在InnoDB中不是个好主意,因为InnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,而使用自增字段作为主键则是一个很好的选择。
//普通索引
alter table table_name add index index_name (column_list) ;
//唯一索引
alter table table_name add unique (column_list) ;
//主键索引
alter table table_name add primary key (column_list) ;
//CREATE INDEX可用于对表增加普通索引或UNIQUE索引,可用于建表时创建索引。
CREATE INDEX index_name ON table_name(username(length));
//如果是CHAR,VARCHAR类型,length可以小于字段实际长度;如果是BLOB和TEXT类型,必须指定 length。
//create只能添加这两种索引;
CREATE INDEX index_name ON table_name (column_list)
CREATE UNIQUE INDEX index_name ON table_name (column_list)
drop index index_name on table_name ;
alter table table_name drop index index_name ;
alter table table_name drop primary key ;
一致性(Consistency):从一个一致性状态到另一个一致性状
态。
例如现有完整性约束 a+b=10,如果一个事务改变了a,那么必须
得改变b,使得事务结束后依然满足 a+b=10,否则事务失败。
隔离性(Isolation):一个事务所做的修改在最终提交以前,对其它事务不可见。
比如现有有个交易是从A 账户转100 元至 B 账户,在这个交易还
未完成的情况下,如果此时 B 查询自己的账户,是看不到新增加的
100元的。
(Durability) 持久性
持久性是指一旦事务提交后,它所做的修改将会永久的保存在数据库
上,即使出现宕机也不会丢失。
尽量使用数字字段而不是字符字段
尽量使用timestamp而不是datetime
Public void FindAllUsers(){
//1、装载sqlserver驱动对象
DriverManager.registerDriver(new SQLServerDriver());
//2、通过JDBC建立数据库连接
Connection con =DriverManager.getConnection("jdbc:sqlserver://192.168.2.6:1433;DatabaseName=customer", "sa", "123");
//3、创建状态
Statement state =con.createStatement();
//4、查询数据库并返回结果
ResultSet result =state.executeQuery("select * from users");
//5、输出查询结果
while(result.next()){
System.out.println(result.getString("email"));
}
//6、断开数据库连接
result.close();
state.close();
con.close();
}
程序开发过程中,存在很多问题:首先,每一次web请求都要建立一次数据库连接。建立连接是一个费时的活动,每次都得花费0.05s~1s的时间,而且系统还要分配内存资源。这个时间对于一次或几次数据库操作,或许感觉不出系统有多大的开销。可是对于现在的web应用,尤其是大型电子商务网站,同时有几百人甚至几千人在线是很正常的事。在这种情况下,频繁的进行数据库连接操作势必占用很多的系统资源,网站的响应速度必定下降,严重的甚至会造成服务器的崩溃。不是危言耸听,这就是制约某些电子商务网站发展的技术瓶颈问题。其次,对于每一次数据库连接,使用完后都得断开。否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将不得不重启数据库。还有,这种开发不能控制被创建的连接对象数,系统资源会被毫无顾及的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃。
public class MyDataSource implements DataSource {
//链表 --- 实现栈结构
privateLinkedList<Connection> dataSources = new LinkedList<Connection>();
//初始化连接数量
publicMyDataSource() {
//一次性创建10个连接
for(int i = 0; i < 10; i++) {
try {
//1、装载sqlserver驱动对象
DriverManager.registerDriver(new SQLServerDriver());
//2、通过JDBC建立数据库连接
Connection con =DriverManager.getConnection(
"jdbc:sqlserver://192.168.2.6:1433;DatabaseName=customer", "sa", "123");
//3、将连接加入连接池中
dataSources.add(con);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
publicConnection getConnection() throws SQLException {
//取出连接池中一个连接
finalConnection conn = dataSources.removeFirst(); // 删除第一个连接返回
returnconn;
}
//将连接放回连接池
publicvoid releaseConnection(Connection conn) {
dataSources.add(conn);
}
}
//查询所有用户
Public void FindAllUsers(){
//1、使用连接池建立数据库连接
MyDataSource dataSource = new MyDataSource();
Connection conn =dataSource.getConnection();
//2、创建状态
Statement state =con.createStatement();
//3、查询数据库并返回结果
ResultSet result =state.executeQuery("select * from users");
//4、输出查询结果
while(result.next()){
System.out.println(result.getString("email"));
}
//5、断开数据库连接
result.close();
state.close();
//6、归还数据库连接给连接池
dataSource.releaseConnection(conn);
}
前缀查询,例如“abc%”,还是索
引策略的问题
对于共享资源,有一个很著名的设计模式:资源池(resource pool)。该模式正是为了解决资源的频繁分配﹑释放所造成的问题。为解决上述问题,可以采用数据库连接池技术。数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量﹑使用情况,为系统开发﹑测试及性能调整提供依据。线程池也是如此,因为频繁开启关闭线程会降低系统资源,所以可以用线程池达到资源共享,统一管理线程资源的目的。初始化一个比较大的线程池,每当程序需要开启新的线程时,会到线程池中申请。同样的我们可以初始化适当的线程数来达到最大的资源利用率
个人认为是第三范式,此时数据冗余较小,范式级别过高对查询效率也不利
序。
select id from table group by id having avg(score) > 80 order by avg(score) desc
/找出第K大的数
int find_k_big(int A[], int low, int high, int k)
{
if(low < high)
{
int pivot_pos = partion2(A, low, high);
if(pivot_pos + 1 == k)
return A[pivot_pos];
else if(pivot_pos + 1 > k)
find_k_big(A, low, pivot_pos - 1, k);
else
find_k_big(A, pivot_pos + 1, high, k);
}
else
return -1;
标签:否则 jpg 数据库服务器 情况 tab primary next drive customer
原文地址:https://www.cnblogs.com/HannahLihui/p/10326767.html