Bootstrap

Mysql必会面试题(第一篇)

Mysql必会面试题(基础篇)



基础

什么是 MySQL?

mysql是一个开源的关系型数据库,

1. 什么是内连接、外连接、交叉连接、笛卡尔积呢?

Mysql中的连接是通过两个或多个表之间的列进行关联,从而获取相关联的数据。

  1. 内连接(inner join):返回两个表中连接字段匹配的行。如果一个表中的行在另一个表中没有匹配的行,则这些行不会出现在查询结果中。

假设有两个表,Employees 和 Departments。

SELECT Employees.Name, Departments.DeptName
FROM Employees
INNER JOIN Departments ON Employees.DeptID = Departments.DeptID;

2.外连接(outer join):不仅返回两个表中匹配的行,还返回左表、右表或两者中未匹配的行。

SELECT Employees.Name, Departments.DeptName
FROM Employees
LEFT OUTER JOIN Departments ON Employees.DeptID = Departments.DeptID;

这个查询将返回所有员工的名字和他们部门的名字,即使某些员工没有分配到部门。

3.交叉连接(cross join):返回第一个表中的每一行与第二个表中的每一行的组合,这种类型的连接通常用于生成笛卡尔积。

SELECT Employees.Name, Departments.DeptName
FROM Employees
CROSS JOIN Departments;

2. MySQL 的内连接、左连接、右连接有什么区别?

MySQL 的连接主要分为内连接和外连接,外连接又可以分为左连接和右连接。

MySQL-joins-来源菜鸟教程

3.说一下数据库的三大范式?

三大范式的作用主要是为了减少数据冗余,提高数据完整性。

1.第一范式(1NF):确保表的每一列都是不可分割的基本数据单元,比如说用户地址,应该拆分为省、市、区、详细信息等四个字段。

2.第二范式(2NF):在第一范式的基础上,要求数据库的每一列都与主键直接相关,而不能只与主键的某一部分相关(主要针对联合主键)。

3.第三范式(3NF):在 2NF 的基础上,消除非主键列对主键的传递依赖,即非主键列只依赖于主键列,不依赖于其他非主键列。

4.varchar 与 char 的区别?

char

  • char 表示定长字符串,长度是固定的;
  • 如果插入数据的长度小于 char 的固定长度时,则用空格填充;
  • 因为长度固定,所以存取速度要比 varchar 快很多,甚至能快 50%,但正因为其长度固定,所以会占据多余的空间,是空间换时间的做法;
  • 对于 char 来说,最多能存放的字符个数为 255,和编码无关

varchar

  • varchar 表示可变长字符串,长度是可变的;
  • 插入的数据是多长,就按照多长来存储;
  • varchar 在存取方面与 char 相反,它存取慢,因为长度不固定,但正因如此,不占据多余的空间,是时间换空间的做法;
  • 对于 varchar 来说,最多能存放的字符个数为 65532

日常的设计,对于长度相对固定的字符串,可以使用 char,对于长度不确定的,使用 varchar 更合适一些。

5.blob 和 text 有什么区别?

  • blob 用于存储二进制数据,而 text 用于存储大字符串。
  • blob 没有字符集,text 有一个字符集,并且根据字符集的校对规则对值进行排序和比较。

6.DATETIME 和 TIMESTAMP 的异同?

相同:

1.两个数据类型存储时间的表现格式一致 YY:mm:DD HH:MM:SS

2.两个数据类型都包含日期和时间部分。

3.两个数据类型都可以存储微秒的小数位数(秒后6位小数秒)。

区别:DATETIME 和 TIMESTAMP 的区别

  1. 日期范围:DATETIME 的日期范围是 1000-01-01 00:00:00.0000009999-12-31 23:59:59.999999;TIMESTAMP 的时间范围是1970-01-01 00:00:01.000000 UTC 到 ``2038-01-09 03:14:07.999999 UTC
  2. 存储空间:DATETIME 的存储空间为 8 字节;TIMESTAMP 的存储空间为 4 字节
  3. 时区相关:DATETIME 存储时间与时区无关;TIMESTAMP 存储时间与时区有关,显示的值也依赖于时区
  4. 默认值:DATETIME 的默认值为 null;TIMESTAMP 的字段默认不为空(not null),默认值为当前时间(CURRENT_TIMESTAMP)

7.MySQL 中 in 和 exists 的区别?

MySQL 中的 in 语句是把外表和内表作 hash 连接,而 exists 语句是对外表作 loop 循环,每次 loop 循环再对内表进行查询。我们可能认为 exists 比 in 语句的效率要高,这种说法其实是不准确的,要区分情景:

  1. 如果查询的两个表大小相当,那么用 in 和 exists 差别不大。
  2. 如果两个表中一个较小,一个是大表,则子查询表大的用 exists,子查询表小的用 in。
  3. not in 和 not exists:如果查询语句使用了 not in,那么内外表都进行全表扫描,没有用到索引;而 not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用 not exists 都比 not in 要快。

8.MySQL 里记录货币用什么字段类型比较好?

货币在数据库中 MySQL 常用 Decimal 和 Numric 类型表示,这两种类型被 MySQL 实现为同样的类型。他们被用于保存与货币有关的数据。

例如 salary DECIMAL(9,2),9(precision)代表将被用于存储值的总的小数位数,而 2(scale)代表将被用于存储小数点后的位数。存储在 salary 列中的值的范围是从-9999999.99 到 9999999.99。

DECIMAL 和 NUMERIC 值作为字符串存储,而不是作为二进制浮点数,以便保存那些值的小数精度。

之所以不使用 float 或者 double 的原因:因为 float 和 double 是以二进制存储的,所以有一定的误差。

10.drop、delete 与 truncate 的区别?

三者都表示删除,但是三者有一些差别:

区别deletetruncatedrop
类型属于 DML属于 DDL属于 DDL
回滚可回滚不可回滚不可回滚
删除内容表结构还在,删除表的全部或者一部分数据行表结构还在,删除表中的所有数据从数据库中删除表,所有数据行,索引和权限也会被删除
删除速度删除速度慢,需要逐行删除删除速度快删除速度最快

因此,在不再需要一张表的时候,用 drop;在想删除部分数据行时候,用 delete;在保留表而删除所有数据的时候用 truncate。

12.count(1)、count(*) 与 count(列名) 的区别?

  • count(*)包括了所有的列,相当于行数,在统计结果的时候,不会忽略列值为 NULL

  • count(1)包括了忽略所有列,用 1 代表代码行,在统计结果的时候,不会忽略列值为 NULL

  • count(列名)只包括列名那一列,在统计结果的时候,会忽略列值为空(这里的空不是只空字符串或者 0,而是表示 null)的计数,即某个字段值为 NULL 时,不统计。

    执行速度

    • 列名为主键,count(列名)会比 count(1)快
    • 列名不为主键,count(1)会比 count(列名)快
    • 如果表多个列并且没有主键,则 count(1) 的执行效率优于 count(*)
    • 如果有主键,则 select count(主键)的执行效率是最优的
    • 如果表只有一个字段,则 select count(*)最优。

13.一条 SQL 查询语句的执行顺序?

查询语句执行顺序

14介绍一下 MySQL 的常用命令

img

说说数据库操作命令?

①、创建数据库:

CREATE DATABASE database_name;

②、删除数据库:

DROP DATABASE database_name;

③、选择数据库:

USE database_name;
说说表操作命令?

①、创建表:

CREATE TABLE table_name (
    column1 datatype,
    column2 datatype,
    ...
);

②、删除表:

DROP TABLE table_name;

③、显示所有表:

SHOW TABLES;

④、查看表结构:

DESCRIBE table_name;

⑤、修改表(添加列):

ALTER TABLE table_name ADD column_name datatype;
说说 CRUD 命令?

①、插入数据:

INSERT INTO table_name (column1, column2, ...) VALUES (value1, value2, ...);

②、查询数据:

SELECT column_names FROM table_name WHERE condition;

③、更新数据:

UPDATE table_name SET column1 = value1, column2 = value2 WHERE condition;

④、删除数据:

DELETE FROM table_name WHERE condition;
说说索引和约束的创建修改命令?

①、创建索引:

CREATE INDEX index_name ON table_name (column_name);

②、添加主键约束:

ALTER TABLE table_name ADD PRIMARY KEY (column_name);

③、添加外键约束:

ALTER TABLE table_name ADD CONSTRAINT fk_name FOREIGN KEY (column_name) REFERENCES parent_table (parent_table (parent_column_name);
说说用户和权限管理的命令?

①、创建用户:

CREATE USER 'username'@'host' IDENTIFIED BY 'password';

②、授予权限:

GRANT ALL PRIVILEGES ON database_name.table_name TO 'username'@'host';

③、撤销权限:

REVOKE ALL PRIVILEGES ON database_name.table_name FROM 'username'@'host';

④、删除用户:

DROP USER 'username'@'host';
#说说事务控制的命令?

①、开始事务:

START TRANSACTION;

②、提交事务:

COMMIT;

③、回滚事务:

ROLLBACK;

15.MySQL 第 3-10 条记录怎么查?

在 MySQL 中,要查询第 3 到第 10 条记录,可以使用 limit 语句,结合偏移量 offset 和行数 row_count 来实现。

limit 语句用于限制查询结果的数量,偏移量表示从哪条记录开始,行数表示返回的记录数量。

SELECT * FROM table_name LIMIT 2, 8;
  • 2:偏移量,表示跳过前两条记录,从第三条记录开始。
  • 8:行数,表示从偏移量开始,返回 8 条记录。

偏移量是从 0 开始的,即第一条记录的偏移量是 0;如果想从第 3 条记录开始,偏移量就应该是 2。

16.用过哪些 MySQL 函数?

用过哪些字符串函数来处理文本?
  • concat():连接两个或者多个字符串
  • length():返回字符串的长度
  • SUBString():从字符串中提取子字符串
  • REPALCE(): 替换字符串中的某部分。
  • lower()和UPPER():分别将字符串换为小写和大写。
  • TRIM(): 去除字符串两侧的空格或其它指定字符。
-- 连接字符串
SELECT CONCAT('沉默', ' ', '王二') AS concatenated_string;

-- 获取字符串长度
SELECT LENGTH('沉默 王二') AS string_length;

-- 提取子字符串
SELECT SUBSTRING('沉默 王二', 1, 5) AS substring;

-- 替换字符串内容
SELECT REPLACE('沉默 王二', '王二', 'MySQL') AS replaced_string;

-- 字符串转小写
SELECT LOWER('HELLO WORLD') AS lower_case;

-- 字符串转大写
SELECT UPPER('hello world') AS upper_case;

-- 去除字符串两侧的空格
SELECT TRIM('  沉默 王二  ') AS trimmed_string;
用过哪些数值函数?
  • ABS():返回一个数的绝对值。
  • CEILING(): 返回大于或等于给定数值的最小整数
  • FLOOE(): 返回小于或者等于给定数值的最大整数
  • ROUND(): 四舍五入到指定的小数位
  • MOD():返回除法操作的小数,取余数
-- 返回绝对值
SELECT ABS(-123) AS absolute_value;

-- 向上取整
SELECT CEILING(123.45) AS ceiling_value;

-- 向下取整
SELECT FLOOR(123.45) AS floor_value;

-- 四舍五入
SELECT ROUND(123.4567, 2) AS rounded_value;

-- 余数
SELECT MOD(10, 3) AS modulus;
用过哪些日期和时间函数?
  • NOW(): 返回当前的日期和时间
  • CURDATE(): 返回当前的日期
  • CURTIME(): 返回当前的时间
  • DATE_ADD()和DATE_SUB():在日期上加上或者减去指定的时间间隔。
  • DATEDIFF():返回两个日期之间的天数
  • DAY() MOUTH() YEAR():分别返回日期的年月日部分
-- 返回当前日期和时间
SELECT NOW() AS current_date_time;

-- 返回当前日期
SELECT CURDATE() AS current_date;

-- 返回当前时间
SELECT CURTIME() AS current_time;

-- 在日期上添加天数
SELECT DATE_ADD(CURDATE(), INTERVAL 10 DAY) AS date_in_future;

-- 计算两个日期之间的天数
SELECT DATEDIFF('2024-12-31', '2024-01-01') AS days_difference;

-- 返回日期的年份
SELECT YEAR(CURDATE()) AS current_year;
用过哪些汇总函数
  • SUM(): 计算数值列的总和
  • AVG():计算数值列的平均值
  • Count(): 计算某列的行数
  • MAX()和MIN():分别返回列中最大和最小值。
  • GROUP_CONCAT : 将多个行值连接为一个字符串。
-- 创建一个表并插入数据进行聚合查询
CREATE TABLE sales (
    product_id INT,
    sales_amount DECIMAL(10, 2)
);

INSERT INTO sales (product_id, sales_amount) VALUES (1, 100.00);
INSERT INTO sales (product_id, sales_amount) VALUES (1, 150.00);
INSERT INTO sales (product_id, sales_amount) VALUES (2, 200.00);

-- 计算总和
SELECT SUM(sales_amount) AS total_sales FROM sales;

-- 计算平均值
SELECT AVG(sales_amount) AS average_sales FROM sales;

-- 计算总行数
SELECT COUNT(*) AS total_entries FROM sales;

-- 最大值和最小值
SELECT MAX(sales_amount) AS max_sale, MIN(sales_amount) AS min_sale FROM sales;
;