数据库-面试题(持续更新)

时间:2024-11-13 07:28:03

来自牛客网的汇总

1. MySQL查询时,只有满足联接条件的记录才包含在查询结果,这种联接是(内联接)。

内联接:典型的联接运算,使用像 = 或 <> 之类的比较运算符。包括相等联接和自然联接。内联接使用比较运算符根据每一表共有的列的值匹配两个表中的行。例如,检索 students 和 courses 表中学生标识号相同的所有行。

外联接:外联接可以是左向外联接、右向外联接或完整外部联接。
在FROM子句中指定外联接时,可以由下列几组关键字中的一组指定:

LEFT JOIN 或 LEFT OUTER JOIN
左向外联接的结果集包括 LEFT OUTER 子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表均为空值。

RIGHT JOIN 或 RIGHT OUTER JOIN
右向外联接是左向外联接的反向联接。将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值。

FULL JOIN 或 FULL OUTER JOIN
完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。

交叉联接:交叉联接返回左表中的所有行,左表中的每一行与右表中的所有行组合。交叉联接也称笛卡尔积。


2. 数据库事务正确执行的四个基本要素

ACID — 数据库事务正确执行的四个基本要素

ACID,指数据库事务正确执行的四个基本要素的缩写。
包含:原子性(Atomicity)一致性(Consistency)隔离性(Isolation)持久性(Durability)

一个支持事务(Transaction)中的数据库系统,必需要具有这四种特性,否则在事务过程(Transaction processing)当中无法保证数据的正确性,交易过程极可能达不到交易。

原子性:一个事务(Transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的默认规则,这包含资料的精准度、串联新以及后续数据库可以自发性地完成预定的工作。

隔离性:当两个或者多个事务并发访问(此处访问指查询和修改的操作)数据库的同一数据时所表现出的互相关系。事务隔离分为不同的级别,包括读为提交(Read uncommitted)、读提交(Read committed)、可重复读(Repeatable read)和串行化(Serializable)。

持久性:在事务完成以后,该事务对数据库所作的更改便持久地保存在数据库之中,而且是完全的。

由于一项操作通常会包含许多子操作,而这些子操作可能会因为硬件的损坏或其他因素产生问题,要正确实现ACID并不容易。ACID建议数据库将所有需要更新以及修改的资料一次操作完毕,但实际上并不可行。

目前主要有两种方式实现ACID:第一种是Write ahead logging,也就是日志式的方式。第二种是Shadow paging。

Write ahead logging(预写日志):
1. 事务所引起的所有改动都要记录在日志中,在事务提交完成之前,所有的这些记录必须被写入硬盘;
2. 一个数据库的缓冲页直到被记入日志后才能发生修改。直到缓冲页对应的日志被写入键盘后,该缓冲页才会存入键盘;
3. 当缓冲页被修改和日志被更新修改时,必须加上互斥锁,以保证改动被记录到日志中的顺序与它发生的顺序是一致的。

以上规则的结果:

  1. 如果一条日志记录未被存入硬盘,则它可以被忽略,因为该日志中包含的改动一定属于未提交的事务。此外,这样的日志不能反映已持久化在数据库中的改动;
  2. 日志记录按顺序记录系统的改动。加锁协议(latch protocol)保证如果有对于同一页改动的两条日志记录,则两条记录的顺序反映对页发生改变的顺序。

3. 从表TABLE_NAME中提取10条记录

-- oracle:
select * from TABLE_NAME where rownum <= 10;

-- sql server:
select top 10 * from TABLE_NAME;

-- mysql: 
select * from TABLE_NAME limit 10;

-- db2:
select * from TABLE_NAME fetch first 10 rows only;
--查询表的TOP 10 条记录
set ROWCOUNT 10
select * from tablename;

4. SQL 约束有哪几种?

NOT NULL: 用于控制字段的内容一定不能为空(NULL)。 

UNIQUE: 控件字段内容不能重复,一个表允许有多个 Unique 约束。

PRIMARY KEY: 也是用于控件字段内容不能重复,但它在一个表只允许出现一个。

FOREIGN KEY: 用于预防破坏表之间连接的动作,也能防止非法数据插入外键列,因为它必须是它指向的那个表中的值之一。

CHECK: 用于控制字段的值范围。

DEFAULT: 用于设置新记录的默认值。

1、not null : 用于控制字段的内容一定不能为空(NULL)。

-- 用法:
Create table MyTable 
               ( 
                   id varchar(32) not null, 
                   name varchar (32) 
               ) 

2、Unique :控件字段内容不能重复,一个表允许有多个 Unique 约束。

1. 新建: 

-- 在Sql Server、Orcale、MS Access 支持的添加 Unique 语法:

 Create table MyTable 
                ( 
                    id varchar(32) not null unique, 
                    name varchar (32) 
                );

-- 在Sql Server、 My Sql 支持的添加 Unique 语法:可同时添加几个字段为约束 如: unique (id,name) 

 Create table MyTable 
                ( 
                    id varchar(32) not null, 
                    name varchar (32), 
                    unique (id,.....) 
                 );

-- 在Sql Server、Orcale、MS Access、My Sql 都支持的添加 Unique 语法: 

 Create table MyTable 
                  ( 
                      id varchar(32) not null, 
                      name varchar (32), 
                     Constraint uniqueName unique(UniqueColumn,.....) 
                   );

2. 删除: 

-- 在Sql Server、Oracle、MS Access 删除 Unique 约束语法:

  drop constraint UniqueName; 

-- 在My Sql 删除 Unique 约束语法:

  drop index UniqueName;

3. 修改:

ALTER TABLE EPlatform 
ADD CONSTRAINT Unique_EPlatform 
unique ([UserId],[Platform]); 

3、Primary Key :也是用于控件字段内容不能重复,但它在一个表只允许出现一个。

-- 在Sql Server、Orcale、MS Access 支持的添加Primary Key语法: 

         Create table myTB1 
             ( 
                 id nvarchar(32) not null primary key, 
                 name nvarchar(32) 
              ); 

-- 在Sql Server、My Sql 支持的添加Primary Key 语法: 

         Create table myTB1 
             ( 
                 id nvarchar(32) not null, 
                 name nvarchar(32), 
primary key (id) 
             );

-- 在Sql Server、Orcale、MS Access、My Sql 支持的添加Primary Key 语法: 

             Create table myTB1 
             ( 
                  id nvarchar(32) not null, 
                 name nvarchar(32), 
constraint PrimaryName primary key (id) 
              ); 

-- 在Sql Server、Orcale、MS Access、My Sql 表已存在的情况下,添加表的Primary Key约束语法: 

             Alter table myTB1 
             ADD Primary Key (id,......); 
             -- 这样的写法,系统会自定义约束名称 

             Alter table myTB1 
             Add Constaint PrimaryName primary key (id); 
             -- 这样的写法,自己可以自定义约束名称 

-- 在Sql Server、Orcale、MS Access 删除表已存在的 Primary Key 约束的语法: 

             Alter table myTB1 
             Drop Constraint PrimaryName;

-- 在My Sql 删除表已存在的 Primary Key 约束的语法: 

             Alter table myTB1 
             Drop Primary Key;

Unique 与 Primary 的相同之处:UNIQUE 和 PRIMARY KEY 约束均为列或列集合提供了唯一性的保证。

Unique 与 Primary 的不同之处:每个表可以有多个 UNIQUE 约束,但是每个表只能有一个 PRIMARY KEY 约束,Unique允许有NULL值,而 Primary key 不允许有NULL值。

注:在同一个数据库中,就算在不同的表中,约束名称是不允许相同的。

4、Foreign Key :FOREIGN KEY 约束用于预防破坏表之间连接的动作,FOREIGN KEY 约束也能防止非法数据插入外键列,因为它必须是它指向的那个表中的值之一。

-- 在Sql Server、My Sql 支持的添加Foreign Key语法: 

              Create table myTB1 
              ( 
                   id nvarchar(32) not null primary key, 
                   name nvarchar(32), 
foreign key(id) references myTB(id) 
              );

-- 在Sql Server、Orcale、MS Access 支持的添加Foreign Key语法: 

              Create table myTB1 
              ( 
                   id nvarchar(32) not null foreign key references myTB(id), 
                   name nvarchar(32) 
              );

-- 在Sql Server、Orcale、MS Access、My Sql 都支持的添加Foreign Key语法: 

              Create table myTB1 
              ( 
                   id nvarchar(32) not null primary key, 
                   name nvarchar(32), 
                    Constraint foreignName foreign key(id) references myTB(id) 
              );

-- 在Sql Server、Orcale、MS Access、My Sql 的表已存在情况下,向表添加外键约束的语法:

              Alter table myTB1 
              Add foreign key(id) references myTB(id); 
              -- 这样写系统会自定义约束名称 

              Alter table myTB1 
              Add Constraint foreignName foreign key(id) references myTB(id); 
              -- 这样写自己可以自定义约束名称 

-- 在Sql Server、Orcale、MS Access 中删除外键约束的语法: 

              Alter table myTB1 
              Drop Constraint foreignName; 

-- 在My Sql 中删除外键约束的语法: 

              Alter table myTB1 
              Drop foreign key foreignName; 

5、Check :用于控制字段的值范围。

-- 在Sql Server、My Sql 支持的添加check 语法: 

              Create table myCheck 
              ( 
                   id nvarchar(32) not null, 
                   age int not null, 
check (age>15 and age <30) 
              );

-- 在Sql Server、Orcale、MS Access 支持的添加 check 语法: 

              Create table myCheck 
              ( 
                   id nvarchar(32) not null, 
age int not null check (age>15 and age<30) 
              );

-- 在Sql Server、Orcale、MS Access、My Sql 都支持的添加 check 语法: 
               Create table myCheck 
              ( 
                   id nvarchar(32) not null, 
                   age int not null, 
constraint checkName check (age<15 and age>30) 
              );

-- 在Sql Server、Orcale、MS Access、My Sql 的表已存在情况下,向表添加check约束的语法: 

              Alter table myCheck 
              add check (id='celly'); 
              -- 这样定义是系统自定义 check约束名称。 

              Alter table myCheck 
              add constraint checkName check(id='celly'); 
              -- 这样定义是自己自定义 check约束名称。 

-- 在 Sql Server、Orcale、MS Access 删除表已存在的 check 约束的语法: 

              Alter table myCheck 
              drop constraint checkName; 

6、Default :用于设置新记录的默认值。

-- 在Sql Server、Orcale、MS Access、My Sql 添加default约束的语法: 

              Create table myDefault 
              ( 
                  id int, 
name nvarchar(32) default 'celly' 
              ); 

-- 在My Sql 的已存在表中添加 字段默认值: 

              Alter table myDefault 
              Alter [id] set default 0; 

-- 在 Sql Server、Orcale、MS Access 的已存在表中添加 字段默认值: 

              Alter table myDefault 
              Alter column [id] set default 0;

-- 在 My Sql 中删除字段默认值语法:

              Alter table myDefault 
              Alter ColumnName drop default;

5. 关系数据库的范式

第一范式(1NF)

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

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

例如,员工信息表,不能将员工信息都放在一列中显示,也不能将其中的两列或多列在一列中显示;员工信息表的每一行只表示一个员工的信息,一个员工的信息在表中只出现一次。简而言之,第一范式就是无重复的列。

第二范式(2NF)

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

例如,员工信息表中加上了员工编号(emp_id)列,因为每个员工的员工编号是惟一的,因此每个员工可以被惟一区分。这个惟一属性列被称为主关键字或主键、主码。

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

第三范式(3NF)

满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。

例如,存在一个部门信息表,其中每个部门有部门编号(dept_id)、部门名称、部门简介等信息。那么在员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入员工信息表中。如果不存在部门信息表,则根据第三范式(3NF)也应该构建它,否则就会有大量的数据冗余。简而言之,第三范式就是属性不依赖于其它非主属性。


6. 数据库运行于哪种状态下可以防止数据的丢失?

在archivelog mode只要其归档日志文件不丢失,就可以有效地防止数据丢失。


7. 通过JDBC访问数据库包含下面哪几步?

 1. 加载JDBC驱动程序:
 2. 提供JDBC连接的URL   
 3. 创建数据库的连接   
 4. 创建一个Statement   
 5. 执行SQL语句   
 6. 处理结果   
 7. 关闭JDBC对象

8. 有关聚集索引的描述,说法正确的是? (AC)

A. 有存储实际数据
B. 没有存储实际数据
C. 物理上连续
D. 逻辑上连续
E. 可以用B树实现
F. 可以用二叉排序树实现

聚集索引是一种索引,该索引中键值的逻辑顺序决定了表中相应行的物理顺序

聚集索引确定表中数据的物理顺序。聚集索引类似于电话簿,按姓氏排列数据。由于聚集索引规定数据在表中的物理存储顺序,因此一个表只能包含一个聚集索引。但该索引可以包含多个列(组合索引),就像电话簿按姓氏和名字进行组织一样。

聚集索引对于那些经常要搜索范围值的列特别有效。使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻。例如,如果应用程序执行的一个查询经常检索某一日期范围内的记录,则使用聚集索引可以迅速找到包含开始日期的行,然后检索表中所有相邻的行,直到到达结束日期。这样有助于提高此类查询的性能。同样,如果对从表中检索的数据进行排序时经常要用到某一列,则可以将该表在该列上聚集(物理排序),避免每次查询该列时都进行排序,从而节省成本。

当索引值唯一时,使用聚集索引查找特定的行也很有效率。例如,使用唯一雇员 ID 列 emp_id 查找特定雇员的最快速的方法,是在 emp_id 列上创建聚集索引或 PRIMARY KEY 约束。


9. mysql数据库中一张user表中,其中包含字段A,B,C,字段类型如下:A:int,B:int,C:int根据字段A,B,C按照ABC顺序建立复合索引idx_A_B_C,以下查询语句中使用到索引idx_A_B_C的语句有哪些? (ABD)

A. select *from user where A=1 and B=1
B. select *from user where 1=1 and A=1 and B=1
C. select *from user where B=1 and C=1
D. select *from user where A=1 and C=1

因复合索引为idx_A_B_C,所以查询条件只能是在a,ab,abc,ac才算 使用到索引idx_A_B_C。

复合索引: Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。 例如索引是key index (a,b,c). 可以支持a | a,b| a,b,c 3种组合进行查找,但不支持 b,c进行查找 .当最左侧字段是常量引用时,索引就十分有效。


10. 假设MySQL数据库表:

create table T{
k int unsigned not null auto_increment,
a date,
b varchar(24),
c int,d varchar(24),
primary key(k),unique key a_index (a DESC,b DESC),
key k1(b),key k2(c),key k3(d));

如下哪些sql语句查询能较好的利用索引? (AD)

A. select b from WHERE b like 'aaa%';
B. select a,b from T WHERE a='2015-10-25' ORDER BY b ASC,c ASC;
C. select a,b,c from T WHERE a='2015-10-25' ORDER BY b ASC;
D. select a,b,c from T WHERE a='2015-10-25' ORDER BY a,b;

题目中的索引b是降序,而B,C两个选项都是升序,故会导致效率降低。而A,D两个选项没有指定升序降序,故会按照其定义的索引a desc,b desc 来进行操作,故而效率较高。所以选A,D。


MySQL的操作

  1. 如何登陆mysql数据库:

    MySQL -u username -p
  2. 如何开启/关闭mysql服务

    service mysql start/stop
  3. 查看mysql的状态

    service mysql status
  4. 如何显示所有数据库

    show databases;
  5. 进入数据库

    use db_name;
  6. 显示所有表

    show tables;
  7. 获取表内所有字段对象名称和类型

    desc table_name;
  8. MySQL支持事务吗?

    在缺省模式下,MySQL是autocommit模式的,所有的数据库更新操作都会及时提交,所以在缺省情况下,mysql是不支持事务的。

    但是如果你的mysql表类型是使用InnoDB Tables 或 BDB tables的话,你的MySQL就可以使用事务处理,使用SET AUTOCOMMIT = 0就可以使MySQL允许在非autocommit模式下,你必须使用commit来提交你的更改,或者有ROLLBACK来回滚你的更改。

    START TRANSACTION;
    SELECT @A:=SUM(salary) FROM table1 WHERE type=1; 
    UPDATE table2 SET summmary=@A WHERE type=1; 
    COMMIT;