SQL常见面试题
关系型数据库(SQL)
关系型数据库是由二维表及其之间的联系所组成的一个数据组织,最典型的数据结构是表,即所有的数据都通过行和列的二元表现形式表示出来
常用的关系型数据库:mysql / oracle / sql server / sqlite
优点:
1、保持了数据的一致性(最大优势),可以进行事务处理
2、支持通用的SQL(结构化查询语言)语句
3、可以在一个表以及多个表之间进行复杂的数据查询,如join
4、二维表结构非常贴近逻辑世界的概念,更容易理解
缺点:
1、高并发读写能力差,一台数据库的最大连接数有限,硬盘 I/O 也有限,不能满足很多人同时连接
2、海量数据情况下读写效率低。对大数据量的表进行读写操作时,需要等待较长的时间
3、数据结构灵活度低,固定的表结构无法快速容纳新的数据类型
非关系型数据库(NoSQL)
非关系型数据库又称NoSQL(Not only SQL ),意为不仅仅是 SQL。其中数据以对象的形式存储在数据库中,而对象之间的关系通过每个对象自身的属性来决定
常见的非关系型数据库:键值数据库Redis、文档数据库MongoDB、图形数据库InfoGrid、列族数据库Bigtable等
优点:
1、格式灵活,存储数据的格式可以是key-value形式、文档形式、图片形式等,而关系型数据库则只支持基础类型
2、查询速度快,NoSQL将数据存储于缓存之中,而关系型数据库将数据存储在硬盘中
3、数据之间没有耦合性,非常容易进行水平扩展
4、高并发、高稳定性、成本低廉、可以实现数据的分布式处理
缺点:
1、不支持 SQL 语句,学习和使用成本高
2、没有事务处理,无法保证数据的完整性和安全性,适合处理海量数据,但不一定安全
3、复杂表关联查询不容易实现
数据库三大范式
-
第一范式:确保每列的原子性
第一范式是最基本的范式,如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式
第一范式的合理遵循需要根据系统的实际需求来定。例如:某些数据库系统中包含“地址”属性,本来直接将“地址”属性设计成一个数据库表的字段即可,但是如果系统经常访问“地址”属性中的“城市”部分,那么就需要将“地址”这个属性重新拆分为省份、城市、详细地址等多个部分进行存储,才算满足了数据库的第一范式:
编号 姓名 性别 年龄 联系电话 省份 城市 详细地址 1 张红欣 男 26 0378-23459876 河南 开封 朝阳区新华路23号 2 李四平 女 32 0751-65432584 广州 广东 白云区天明路148号 3 刘志国 男 21 0371-87659852 河南 郑州 二七区大学路198号 -
第二范式:确保表中每列都与主键相关
第二范式是指在关系表中,不是主键的列都必须完全依赖于主键,而不是主键的一部分(即消除部分依赖,主要是针对联合主键而言)
依赖:对于X的每个值,Y都有一个值与之对应,反过来则不一定不成立,这叫做X函数决定Y,Y函数依赖X
部分依赖:当主键由两个或两个以上字段构成,而表中的某些信息通过主键的一个字段就能唯一确定
例如:在学生选课表中,通过学号和课程号可以唯一确定一条记录,因此用学号和课程号做联合主键。但是表中的姓名、专业通过主键中的学号就能唯一确定,而课程名通过课程号就能唯一确定,这就是部分依赖,这样的设计不符合第二范式:
学号 姓名 专业 课程号 课程名 成绩 001 张三 电子 C01 C++ 80 002 李四 电子 C01 C++ 86 001 张三 电子 C02 操作系统 90 002 李四 电子 C02 操作系统 88 不符合第二范式会带来的问题:
- 数据信息冗余
- 增删改会出现问题,比如有一门《微机原理》没有人选,那么由于缺少学号(主键之一)那么这门课就不能出现在表里。
解决方案:用关系分解的方法消除部分依赖,将上表改成三张表
学号 姓名 专业 001 张三 电子 002 李四 电子 课程号 课程名 C01 C++ C02 操作系统 学号 课程号 成绩 001 C01 80 002 C01 86 001 C02 90 002 C02 88 -
第三范式:确保每列都和主键列直接相关
第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。第三范式的目的是移除那些不是直接依赖于主键的属性,这些属性是借由另一个属性来依赖于主键的(即A依赖于B,B依赖于C,就可以说A依赖C,形成了传递依赖)
例如:下表中有如下决定关系: 学号 –> 姓名,性别;系号 –> 系名;宿舍号 –> 宿舍电话,同时又有学号 –> 系名,学号 –> 宿舍电话,即存在着传递依赖。
学号 姓名 性别 系号 系名 宿舍号 宿舍电话 J001 张三 男 X01 计算机 103 13579 D005 李四 男 X02 电子 205 24680 S005 王五 男 X03 生物 309 12345 这样设计表会带来数据冗余,操作异常等问题。同样可以用关系分解的分解的方法来消除传递依赖,将这张表分成三张表:
系号 系名 X01 计算机 X02 电子 X03 生物 宿舍号 宿舍电话 103 13579 205 24680 309 12345 学号 姓名 性别 系号 宿舍号 J001 张三 男 X01 103 D005 李四 男 X02 205 S005 王五 男 X03 309
主键与外键
- 主键:主键是能确定一条记录的唯一标识,不可重复,不能为空,一张表只能有一个主键
- 外键:外键用来建立与其他表的连接,是另一张表的主键,可以重复,可以为空,一张表可以有多个外键
CHAR与VRCHAR数据类型
-
CHAR的长度是不可变的,VARCHAR的长度是可变的
当定义的是char(10),输入的是"abc"这三个字符时,它们所占空间是10个字节,其中包括7个空字节,当输入的字符长度超过指定的数时,char会截取超出的字符。在取数据时,char类型的要去除多余的空格,而对于varchar类型则不需要
-
CHAR的存取速度比VARCHAR快,因为其长度固定,方便程序的存储与查找
char也为此付出的是空间的代价,因为其长度固定,所以难免会有多余的空格占位符占据空间,可谓是以空间换取时间效率。varchar则是以空间效率为首位
-
CHAR的存储方式是:对英文字符(ASCII)占用1个字节,对一个汉字占用两个字节。
VARCHAR的存储方式是:对每个英文字符占用2个字节,汉字也占用2个字节。 -
两者的存储数据都非unicode的字符数据
临时表
临时表只在当前连接可见,当关闭连接时会被自动删除并释放所有空间,因此可以在不同连接中创建同名的临时表
临时表的创建与语法为CREATE TEMPOPARY TABLE tmp_table
临时表也可以手动删除DELETE TEMPOPARY TABLE IF EXISTS tmp_table
数据库函数、触发过程与存储器
存储过程 | 函数 | |
---|---|---|
参数类型 | 可以使用IN、OUT、IN OUT三种模式的参数 | 只有IN |
返回值 | 可以通过OUT、IN OUT参数返回零个或多个参数值 | 必须有返回值,且必须为单一值或单一对象 |
是否可以单独执行 | 可以 | 必须通过execute执行 |
是否可以通过SQL语句 (DML或SELECT)调用 |
不可以 | 可以,且可以位于FROM关键字的后面 |