以下是笔者总结的Java笔试面试题中数据库部分,答案为笔者自己总结得出,未必完全正确,仅供参考,由于使用MySQL比较多,所以大多数都是关于MySQL的
(1) MySQL是中小型数据库。Oracle是大型数据库
(2) 安装空间的差距。MySQL安装完后才几百兆。Oracle有几个G左右,运行时占用特别大的内存空间和机器性能
(3) 主键的不同。MySQL主键可以用自增类型,Oracle没有自增类型
(4) 单引号的处理。MySQL可以用单引号和双引号。Oracle只可以用单引号,执行sql语句前必须做单引号的替换,把所有出现的一个双引号替换成两个单引号
(5) 翻页的SQL语句的处理。MySQL处理翻页的SQL语句比较简单,用LIMIT就可以进行输出记录条数限制。Oracle处理翻页的SQL语句比较繁琐
(6) 空字符串的处理。MySQL的非空字段可以存空字符串,Oracle非空字段不能存空字符串
(1) 原子性(A),即事务的操作是一个整体,要么全做要么全不做,确保所有操作无误的情况下才提交事务,若其中一个环节出现异常,则进行回滚
(2) 一致性(C),即事务开始和结束之后,不破坏数据库的完整性
(3) 隔离性(I),事务可以并发执行,并且它们之间互不干扰,相互隔离
(4) 持久性(D),即事务提交之后,对数据库的修改是永久的
第一范式,要求数据表必须是二维数据表,并且每一列都是不可分割的
第二范式,在满足第一范式的基础上,必须有一个主键,非主键属性必须完全依赖于主键属性
第三范式,在满足第二范式的基础上,每一个非主键属性都直接依赖于主键属性。非主键属性不传递依赖于主键属性
BC范式,在满足第三范式的基础上,任何字段都不传递依赖于其它非主键属性
SQL注入是指通过输入特殊字符串嵌入SQL语句提交,对数据库进行非法查询或更新
预防措施:
(1) 不使用拼接的SQL语句,采用参数化的SQL语句代替
(2) 对用户的输入进行校验,可以利用正则表达式对单引号进行转换
(3) 对密码等隐私信息进行一定的加密转换后存储
(4) 不使用管理员权限进行数据库连接
(1) 主键是非空且唯一的,可以标识每个元组是唯一的。定义主键时,系统会为其创建唯一性索引
(2) 外键可以保证取值是被引用的列中的值或NULL,也就是保证参照完整性。使用外键可以与同表或者不同表的列建立引用关系
优点:
(1) 唯一索引可以标识每一行的唯一性
(2) 大大加快数据的检索速度和排序速度
(3) 加快了表和表之间的连接
缺点:
(1) 创建和维护索引要耗费时间,对表中的数据进行更新的时候,索引也要动态的维护
(2) 索引也会占物理空间
(1) 数据表中只允许有一个主键,但是允许有多个唯一索引
(2) 主键列会自动创建唯一索引,非主键列上也可以创建唯一索引
MySQL索引有B+树索引、R树索引、Hash索引、FullText索引等
B+树叶子结点都在用一层,信息都存在叶子结点,查找每个关键字的速度比较平均,并且B+树是排好序的,可以快速锁定关键字的范围,然后逐步减小查询范围。之所以不用二叉树,是因为二叉树在关键字多的时候,深度会很大,越是查找底层的数据,效率越慢
(1) 复合索引中没有使用第一个字段值
(2) 单键索引列上存在NULL值,导致SELECT COUNT(*)不走索引
(3) 索引列上有函数、运算或隐式转换
(5) 表的数据库数据量小或者查询表中大部分数据
(6) 查询条件使用不等于或者模糊查询通配符%在前面
(1) 最左前缀原则。创建复合索引时,WHERE中为=的在左边,遇到范围查询(>,<,between,like)时右边的列会失效
(2) 选择区分度高的。区分度为count(distinct)/count(*),区分度越高扫描的次数越少
(3) 尽量拓展索引,不新建索引。在原有的索引上进行拓展列,比如把单值变为复合索引
(4) WHERE,ORDER BY,GROUP BY子句常使用的列建索引
(5) 两个表连接字段建索引
(1) id表示执行顺序。值不同时越大越先执行,相同时从上往下执行
(2) select_type表示每个SELECT子句的类型。SIMPLE为最简单的查询,PRIMARY为嵌套查询中的主查询(最外层),SUBQUERY为嵌套查询的子查询,UNION为联合查询
(3) type表示访问类型。性能ALL< index < range < ref < eq_ref < const < system < NULL,查询优化中至少要达到range级别
(4) possible_keys表示可能用到的索引列
(5) key表示实际用到的索引列
(6) key_len表示键的长度
(7) ref表示哪些列或常量被用于查找索引列上的值
(8) rows表示估算找到记录所需要读取的行
(9) Extra表示额外的但非常重要的信息。Using index表示select操作中使用了覆盖索引,Using where表示使用过滤条件,Using temporary表示使用看临时表,Using filesort表示额外使用了文件进行排序,Using join buffer表示使用了连接缓存。查询语句中绝对不能出现Using temporary和Using filesort
(1) InnoDB支持外键。MyISAM不支持外键
(2) InnoDB支持事务。MyISAM不支持事务
(3) InnoDB的锁是行级锁。MyISAM的锁是表级锁
(4) InnoDB不保存表的具体行数,SELECT COUNT(*)会扫描整个表计算有多少行。MyISAM会保存行数
(5) 当数据库中的数据读多写少,建议使用MyISAM。写多读少,建议使用InnoDB引擎
(1) 内连接又称为自然连接,显示两个表公共部分
(2) 外连接又分为左外连接、右外连接和全外连接。左外连接显示左表的数据和右表中关联的数据,右外连接显示右表的数据和左表关联的数据,全连接显示两个表中所有数据
(1) 资源重用。重复使用数据库连接,避免了频繁创建、释放连接引起的大量性能开销
(2) 更快的系统响应速度。直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销,从而缩减了系统整体响应时间
(3) 新的资源分配手段。可在应用层通过数据库连接的配置,实现数据库连接池技术
(4) 统一连接管理,避免数据库连接泄漏。在较为完备的数据库连接池实现中,可回收超时的连接,避免了数据库连接操作可能出现的资源泄漏
(1) 存储过程可以返回参数。函数只能返回值或者表对象
(2) 存储过程可以没有返回值。函数必须有返回值
(3) 存储过程一般是作为一个独立的部分来执行,不能嵌入SQL语句中。函数一般作为SQL语句的一部分来调用
(4) 存储过程在创建时已在服务器上编译,执行速度比函数快
(1) 聚集索引的表记录的排列顺序和索引的排列顺序一致,非聚集索引的表记录的排列顺序和索引的排列顺序不一致
(2) 查询连续记录时,聚集索引效率高于非聚集索引
(3) 更新数据时,聚集索引效率低于非聚集索引,因为聚集索引更新后需要进行重排
(4) 聚集索引在B+树中存储直接存储物理数据,非聚集索引存的是索引值和物理数据对应的地址
(1) 使用索引。在SQL语句中WHERE,ORDER BY和GROUP BY列上创建索引
(2) 优化SQL。不使用SELECT *,只返回需要的字段。索引列上不做函数运算,避免隐式转换。尽量使用LIMIT控制输出的行数
(3) 优化数据类型。用尽量短的数据类型存储表中所有数据
(4) 对表进行拆分。垂直拆分,把主键和常用的列放一个表,主键和不常用的列放另一个表
(5) 修改数据库配置文件。尽量使用查询缓存,指定查询缓冲区大小
(6) 主从复制。读写分离,在主数据库执行写数据操作,在从数据库执行读操作
(1) 丢失更新。两个事务并发执行,后一个事务的更新覆盖前一个事务的更新
(2) 脏读。一个事务读到别的事务未提交的数据
(3) 不可重复读。在一个事务内,多次读取同一数据时,结果不同
(4) 幻读。在一个事务内,多次读取同一个表时,读取的记录数不同
虽然脏读和不可重复读两次读取的数据可能不同。但脏读读到的是别的事务未提交的数据,不可重复读读到的都是已提交的数据。
(1) 共享锁(S锁)。多个事务可以对同一个数据库加S锁,只可以读。只要有一个事务加上S锁后,其它事务就不能加X锁
(2) 排他锁(X锁)。一个事务加上X锁后,其它事务不能加任何锁。加X锁的事务可以对数据进行读写,其它事务不能读写
(1) 读未提交。可能出现脏读,不可重复读和幻读
(2) 读已提交(Oracle默认)。可以避免脏读,不能避免不可重复读和幻读
(3) 可重复读(MySQL默认)。可以避免脏读和不可重复读,不能避免幻读
(4) 可串行化。可以避免脏读,不可重复读和幻读
(1) 表级锁。一下锁住整张表,锁的粒度最大,发生冲突概率最高,开销小,不会出现死锁,并发度最低
(2) 行级锁。仅对操作的行加锁,锁的粒度最小,发生冲突概率最低,开销大,会出现死锁,并发度最高
(3) 页级锁。锁定相邻的记录,同样会出现死锁
(1) 悲观锁,认为写多读少。数据开始更改时锁住表,直到更改完成才释放锁,效率低。调用方法是SELECT … FOR UPDATE
(2) 乐观锁,认为读多写少。修改完成准备提交时才加锁,效率高,可能出现脏读
基于版本号实现,每次更新时版本号加1。读取数据时,版本号一起读出来,提交更新时提交的版本号大于当前数据的版本号则更新成功,否则重试
触发器是一种特殊的存储过程,是由事件触发的
触发器与存储过程的区别:
(1) 触发器是当DML语句发生时隐式调用的,而存储过程从一个应用或过程中显式调用
(2) 触发器禁止使用COMMIT和ROLLBACK语句,存储过程可以使用任何SQL语句
(3) 触发器不能接受参数输入,存储过程可以接受参数输入
(1) TRUNCATE TABLE,删除内容,不删除定义,释放空间,执行后数据不可恢复
(2) DELETE TABLE,删除内容,不删除定义,不释放空间,执行后操作记录写进日志,数据可以恢复
(3) DROP TABLE,删除内容,删除定义,释放空间,执行后完全删除,不可恢复
(1) 授权语句:GRANT 权限 ON 数据库对象 TO 用户
(2) 回收语句:REVOKE 权限 ON 数据库对象 FROM 用户
把什么权限在哪个表上(ON)的给(TO)谁 把什么权限在哪个表上(ON)的从(FROM)谁那里收回
(1) 增加列。ALTER TABLE 表名 ADD 列名 数据类型
(2) 删除列。ALTER TABLE 表名 DROP 列名
(3) 修改列(适用MySQL)。ALTER TABLE 表名 CHANGE 列名 新列名 数据类型
修改表 哪个表 增加/删除/修改 列名 指定类型
SELECT COUNT(*)和SELECT COUNT(数字)返回的记录数包括NULL。SELECT COUNT(列名)返回的记录数不包括NULL。
(1) 视图是一种虚拟的表,是对查询结果的一种封装的逻辑结构
(2) 可以简化查询,可以对数据进行保护
外键在业务层定义,不直接使用数据库外键,因为会影响插入的性能,如果设置了级联,在更新的时候级联的表也会更新,在被引用表的数据删除的时候,也会跟着删除
主数据库进行更新操作后,操作记录都会保存到日志中,然后日志通过网络发送给从数据库,从数据库根据日志更新数据
安全性控制、完整性控制、并发性控制和数据库恢复