1.sql语句分类?
- sql语句分为四大类:DDL、DML、DQL、DCL
- DDL数据定义语言:CREATE、DROP,、ALTER(操作的对象是数据库、表)
- DML数据操纵语言:INSERT、UPDATE、DELETE(操作的对象是记录)
- DQL数据查询语言:SELECT
- select ... from student where 条件 group by 分组字段 having 条件 order by 排序字段
- 执行顺序:from->where->group by->having->order by->select
- group by 通常和聚合函数(avg(),count()...)一起使用 ,经常先使用group by关键字进行分组,然后再进行集合运算。
- group by与having 一起使用,可以限制输出的结果,只有满足条件表达式的结果才会显示。
- DCL数据控制功能:GRANT(授权)、REVOKE(收回权限)、COMMIT(提交)、ROLLBACK(回滚)
- where和having的区别:两者起作用的地方不一样,where作用于表或视图,是表和视图的查询条件。having作用于分组后的记录,用于选择满足条件的组。
简要回答:
- DDL语言,对表、视图、索引操作,对逻辑结构操作的;
- DML语言,对数据进行操作;
- DQL语言,这个简单,以select为关键字,各种查询语句都属于;
- DQL语言,可以简单的理解为权限控制;
- where和having的区别,where后面接表或者视图,having后面是结果。
2.什么是数据库的三范式?什么是反三范式?
- 范式其实指的就是规范的意思,英文Normal form,简称NF,目的,范式可以避免数据冗余,减少数据库的空间,减轻维护数据完整性的麻烦。
- 只有关系型数据库才存在范式,总共有1NF,2NF,3NF,BCNF,4NF,5NF,DKNF,6NF,用的最多的1NF、2NF、3NF;
- 第一范式(1NF)表中的列不可分割,具有原子性。
- 第二范式(2NF)在1NF的基础上,有主键,非主键列需要完全依赖于主键,不能只依赖于主键的一部分。
- 第三范式(3NF)在2NF基础上,非主键列需要直接依赖于主键,不能存在传递依赖。即不能存在:非主键列 A 依赖于非主键列 B,非主键列 B 依赖于主键的情况。
- 反三范式, 故名思义,跟范式所要求的正好相反,在反范式的设计模式,我们可以允许适当的数据的冗余,用这个冗余去取操作数据时间的缩短。也就是利用空间来换取时间,把数据冗余在多个表中,当查询时可以减少或者是避免表之间的关联。
简要回答:
- 1NF,列不可拆分,具有原子性。
- 2NF,满足1NF,有主键,非主键列需要完全依赖主键,不能依赖部分。
- 3NF,满足2NF,非主键需要直接依赖主键,不能传递依赖。
- 反三范式就是通过增加冗余、聚合的手段来提升性能。
辅助理解:
- 第一范式:假如有张表有一列所在地,可分割为省、市,这样就不符合1NF。
编号 |
姓名 |
性别 |
所在地 |
0001 |
张三 |
男 |
广东省,深圳市 |
0002 |
李四 |
女 |
海南省,海口市 |
应该拆分为:
编号 |
姓名 |
性别 |
所在省 |
地市 |
0001 |
张三 |
男 |
广东省 |
深圳市 |
0002 |
李四 |
女 |
海南省 |
海口市 |
- 第二范式:假如有一张订单表,产品数量、产品折扣、产品价格和订单号、产品号都有依赖,订单金额和订单时间只和订单号有依赖,要完全依赖,这样就不符合第二范式。
订单号 |
产品号 |
产品数量 |
产品折扣 |
产品价格 |
订单金额 |
订单时间 |
2008003 |
205 |
100 |
0.9 |
8.9 |
2870 |
20080103 |
2008003 |
206 |
200 |
0.9 |
9.9 |
2870 |
20080103 |
2008005 |
207 |
200 |
0.75 |
10 |
2000 |
20080203 |
2008006 |
207 |
400 |
0.85 |
12 |
4800 |
20080206 |
2008007 |
207 |
1000 |
0.88 |
14 |
14000 |
20080209 |
2008008 |
210 |
240 |
0.95 |
8 |
12255 |
20100423 |
2008008 |
211 |
300 |
0.75 |
8 |
12255 |
20100423 |
2008008 |
212 |
350 |
0.8 |
15.9 |
12255 |
20100423 |
应该分为订单表和订单详情表,用一对多去解决。
订单号 |
产品号 |
产品数量 |
产品折扣 |
产品价格 |
2008003 |
205 |
100 |
0.9 |
8.9 |
2008003 |
206 |
200 |
0.9 |
9.9 |
2008005 |
207 |
200 |
0.75 |
10 |
2008006 |
207 |
400 |
0.85 |
12 |
2008007 |
207 |
1000 |
0.88 |
14 |
2008008 |
210 |
240 |
0.95 |
8 |
2008008 |
211 |
300 |
0.75 |
8 |
2008008 |
212 |
350 |
0.8 |
15.9 |
订单号 |
订单金额 |
订单时间 |
2008003 |
2870 |
20080103 |
2008003 |
2870 |
20080103 |
2008005 |
2000 |
20080203 |
2008006 |
4800 |
20080206 |
2008007 |
14000 |
20080209 |
2008008 |
12255 |
20100423 |
2008008 |
12255 |
20100423 |
2008008 |
12255 |
20100423 |
- 第三范式:假如有一张学生表,所有属性都完全依赖于学号,所以满足第二范式,但是“班主任性别”和“班主任年龄”直接依赖的是“班主任姓名”,而不是主键学号。
3.多列索引的最左原则是什么?
- (A、B、C)创建了索引,相当于创建了(A)、(A、B)、(A、B、C)
- (A、B)创建了索引,相当于创建了(A)、(A、B)
- 创建复合索引时应该将最常用作限制条件的列放在最左边,依次递减。
4.说一下常用的聚合函数?
- AVG() 返回数值列的平均值。
- COUNT()返回匹配指定条件的行数。
- FIRST()返回指定的列中第一个记录的值。
- LAST()返回指定的列中最后一个记录的值。
- MAX() 返回指定列的最大值。
- MIN()返回指定列的最小值。
- SUM()返回数值列的总数。
- GROUP BY 用于结合聚合函数,根据一个或多个列对结果集进行分组。
- HAVING 让我们筛选分组后的各组数据。
- EXISTS 用于判断查询子句是否有记录,如果有一条或多条记录存在返回 True,否则返回 False。
- UCASE()把字段的值转换为大写。
- LCASE()把字段的值转换为小写。
- MID()用于从文本字段中提取字符。
- LEN()返回文本字段中值的长度。
- ROUND()用于把数值字段舍入为指定的小数位数。
- NOW()返回当前系统的日期和时间。
- FORMAT()用于对字段的显示进行格式化。
5.说说数据库约束有哪些?
- 真正约束字段的是数据类型,但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合法性,从业务逻辑角度保证数据的正确性。
- 数据库约束主要分为:
- 主键约束(PRIMARY KEY,非空和唯一的结合),确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录。
- 唯一约束(UNIQUE),保证某列的每行必须有唯一的值。
- 默认约束(DEFAULT),规定没有给列赋值时的默认值。
- 检查约束(CHECK),保证列中的值符合指定的条件。
- 外键约束(FOREIGN KEY),保证一个表中的数据匹配另一个表中的值的参照完整性。
- 非空约束(NOT NULL),指示某列不能存储 NULL 值。
简要回答:
- 数据库sql约束有:主键约束,唯一约束,默认约束,检查约束,外键约束,非空约束。
6.说说数据库连接查询有哪些?
- 连接查询是把多张表进行记录的连接(按照某个条件进行数据的拼接);
- 内连接(inner join),a表和b表同时符合条件的行;
- 外连接,分为左外连接(left join)、有右外连接(right join)、全连接(full join是Oracle里面的,mysql是union和union all来实现);
- 左外连接:左表保持不动,右表在右侧滑动,用右表匹配左表。结果保留左表的所有行,右表中不匹配的行默认填充为空值NULL。
- 右外连接:右表保持不动,左表在左侧滑动,用左表匹配右表。结果保留右表的所有行,左表中不匹配的行默认填充为空值NULL。
- 全连接:包括左右表所有的行。
- 交叉连接(cross join),a表*b表的笛卡尔积,笛卡尔积在查询的时候没有太大的意义,在数学上表示所有可能性。
简要回答:
- 自连接,外连接(左外连接、右外连接、全连接),交叉连接。
7.Mysql查询语句的执行顺序?
- sql的编写顺序:
- select 字段列表
- distinct 去重
- from 表名列表
- join on 表关联
- where 条件列表
- group by 分组字段列表
- having 分组后的条件列表
- order by 排序字段列表
- limit 分页参数
- sql的执行顺序:
- from 表名列表
- join on 表关联
- where 条件列表
- group by 分组字段列表
- having 分组后的条件列表
- select 字段列表
- distinct 去重
- order by 排序字段列表
- limit 分页参数
8.Mysql 如何实现多表查询?
- 多表关系
- 一对多:在多的一方设置外键,关联一的一方的主键
- 一对一:用于表结构拆分,在其中任何一方设置外键(给唯一约束UNIQUE),关联另一方的主键
- 对多对:需要建立中间表,中间表包含两个外键,关联两张表的主键
- 多表查询
- 内连接
- 隐式:select ...from 表A,表B where 条件...
- 显式:select ... from 表A inner join 表B on 条件...
- 外连接
- 左外连接:select ...from 表A left join 表B on 条件...
- 右外连接:select ...from 表A right join 表B on 条件...
- 自连接:select ...from 表A 别名1,表A 别名2 where 条件...
- 子查询:
- 单行单列子查询 可放在from后做为临时表结果,也可放到where后使用in
- 单行多列子查询 可放在from后做为临时表结果
- 多行多列子查询 可放在from后做为临时表结果
- 多行单列子查询 可放在from后做为临时表结果,也可放到where后使用in
9.MYSQL内连接和外连接的区别 ?
- 内连接会取出连接表中匹配到的数据,匹配不到的不保留;
- 外连接会取出连接表中匹配到的数据,匹配不到的也会保留,其值为NULL。以某一个表为主表后,进行关联查询,不管能不能关联的上,主表的数据都会保留,关联不上的以NULL显示
- 左外连接,以左边的表为主表
- 右外连接,以右边的表为主表
10.CHAR和VARCHAR的区别?
区别主要有以下几个方面
- 最大长度:char最大长度是255字符,varchar最大长度是65535个字节。
- 定长:char是定长的,不足的部分用隐藏空格填充,varchar是不定长的。
- 空间使用:char会浪费空间,varchar会更加节省空间。char类型会预先分配一定长度的空间,而varchar类型则根据实际存储的字符串长度动态分配空间。例如,如果定义一个char(50)类型的列,那么无论实际存储的字符串长度是多少,都会占用50个字符的空间;而如果定义一个varchar(50)类型的列,那么实际占用的空间将取决于存储的字符串长度,不会浪费空间。
- 查找效率:char查找效率会很高,varchar查找效率会更低。由于char类型的数据长度是固定的,因此在查询时效率更高,因为MySQL可以直接根据偏移量计算出每个字符在磁盘上的位置,而不需要像varchar类型那样需要先遍历整个字符串才能确定位置
- 插入和更新效率:由于char类型的数据长度是固定的,因此在插入和更新数据时,如果实际存储的字符串长度小于指定长度,那么MySQL会使用空格字符填充剩余的空间,这可能会浪费一些存储空间。而varchar类型则可以动态分配空间,不会浪费空间。
- 使用场景: 由于char类型在存储和查询时效率更高,因此适用于存储长度固定的数据,例如身份证号、邮政编码等;而varchar类型则适用于存储长度不确定的数据,例如用户名、地址等。
在项目中的使用,这两种方式都会用到,比如像一些枚举值是固定长度的可以使用char,像一些描述信息或名字类的长度不固定的选择使用varchar。
11.索引是越多越好吗? 什么样的字段需要建索引, 什么样的字段不需要 ?
- 索引是越多越好吗?
- 索引并不是多多益善,索引越多,维护索引结构的代价也就越大,会影响增删改的效率
- 什么样的字段需要建索引?
- 数据量较大,且查询比较频繁的表建立索引。
- 常作为查询条件(where)、排序(order by)、分组(group by)操作的字段建立索引。
- 推荐创建联合索引(即复合索引、也叫多列索引)
- 什么样的字段不需要建立索引?
- 更新频繁字段不适合创建索引
- 若是不能有效区分数据的列不适合做索引列(如性别,男女未知,最多也就三种,区分度实在太低)
- 对于那些查询中很少涉及的列,重复值比较多的列不要建立索引。比如省会、城市、月份、性别(男女)
- 对于定义为text、image和bit的数据类型的列不要建立索引。
- null值过多也不合适
12、什么是回表查询?
- 回表查询:先到二级索引中查找数据,找到主键值,然后再到聚集索引中根据主键值,获取数据的方式,就称之为回表查询。
- 回表的原因是 select查询要的列在二级索引的列中不存在,需要去主键索引获取,因为主键索引含有整行记录值。