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;
<think>我们正在生成MySQL面试题目大全及详细解析。根据引用内容,我们可以看到已有部分题目和解析,但用户要求的是大全,因此我们需要整合并扩展内容。 注意:引用[1]提到有110道题,引用[2]提到15道,引用[3]提到用户与权限1-5道,引用[4]提到慢查询日志分析。我们将从这些引用中提取已有的题目,并补充其他常见面试题,以达到大全的目的。 由于回答篇幅限制,我们不可能在此列出全部110道题,但我们可以给出一个全面的目录和部分典型题目的详细解析,并说明其余题目可以在PDF手册中找到(如引用[1]所述)。 但是,请注意:用户要求的是“题目及详细解析”,因此我们需要在回答中提供一定数量的题目和解析,并尽可能覆盖多个方面。 我们将按照以下主题组织题目: 1. 基础概念 2. 存储引擎 3. 索引 4. 事务与锁 5. 性能优化 6. 复制与高可用 7. 安全与权限 8. 查询语句 9. 日志管理 10. 其他高级特性 下面开始生成内容:</think>### MySQL 面试题目大全及详细解析 以下整合高频 MySQL 面试题及深度解析,覆盖基础概念、性能优化、事务、索引等核心领域,结合企业级应用场景。 --- #### **一、基础概念** 1. **`NOW()` 和 `CURRENT_DATE()` 的区别** - `NOW()`:返回当前日期和时间(格式:`YYYY-MM-DD HH:MM:SS`)。 - `CURRENT_DATE()`:仅返回当前日期(格式:`YYYY-MM-DD`)。 *应用场景*:订单表需精确时间戳用 `NOW()`;统计每日新增用户用 `CURRENT_DATE()`[^1]。 2. **CHAR 和 VARCHAR 的区别** - `CHAR`:定长字符串(固定存储空间),适合存储长度固定的数据(如 MD5 值)。 - `VARCHAR`:变长字符串(按实际长度分配空间),适合长度变化的数据(如用户名)。 *示例*: ```sql CREATE TABLE test ( id CHAR(10), -- 固定占用 10 字节 name VARCHAR(100) -- 实际占用 "Alice" 为 5 字节 ); ``` --- #### **二、索引与性能优化** 3. **B+树索引的优势** - 范围查询高效:叶子节点形成有序链表,支持快速范围扫描(如 `WHERE age > 20`)。 - 减少 I/O 操作:树高度低(通常 3-4 层),百万级数据仅需 3 次磁盘 I/O。 *对比 B 树*:B+树非叶子节点不存数据,可容纳更多键值[^4]。 4. **慢查询日志分析步骤** 1. 启用配置(`my.cnf`): ```ini slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 2 # 超过 2 秒的查询 ``` 2. 分析工具: ```bash mysqldumpslow -t 10 -s at /var/log/mysql/slow.log # 显示耗时 TOP10 ``` 3. 优化建议:添加缺失索引、重写复杂子查询[^4]。 --- #### **三、事务与锁机制** 5. **ACID 特性实现原理** - **原子性(A)**:通过 `Undo Log` 回滚未完成事务。 - **隔离性(I)**:锁机制 + MVCC(多版本并发控制)。 *示例*: ```sql START TRANSACTION; UPDATE accounts SET balance = balance - 100 WHERE user_id = 1; UPDATE accounts SET balance = balance + 100 WHERE user_id = 2; COMMIT; -- 失败时自动回滚 ``` 6. **脏读 vs 幻读** - **脏读**:读取其他事务未提交的数据(隔离级别 `READ COMMITTED` 可解决)。 - **幻读**:同一查询多次返回不同行数(需 `SERIALIZABLE` 或 `Next-Key Locks` 解决)[^3]。 --- #### **四、权限与安全** 7. **用户权限管理命令** - 创建用户: ```sql CREATE USER 'dev'@'192.168.1.%' IDENTIFIED BY 'password'; ``` - 授权并刷新: ```sql GRANT SELECT, INSERT ON db1.* TO 'dev'@'192.168.1.%'; FLUSH PRIVILEGES; -- 立即生效[^3] ``` --- #### **五、高级特性** 8. **Explain 执行计划解读** - `type` 列: - `ALL`:全表扫描(需优化)。 - `index`:索引扫描。 - `ref`:索引查找。 - `Extra` 列: - `Using filesort`:需优化排序字段索引。 - `Using index`:覆盖索引优化成功[^2]。 --- #### **六、高可用与复制** 9. **主从复制延迟解决方案** - 并行复制(`slave_parallel_workers > 1`)。 - 半同步复制(`rpl_semi_sync_master_wait_for_slave_count = 1`)。 - 分库分表减少单库压力。 --- ### 相关问题 1. **如何设计一个支持高并发的订单表?** *考察点*:分库分表策略、索引设计、事务隔离级别选择。 2. **什么情况下索引会失效?** *示例*:对索引列使用函数(`WHERE YEAR(create_time) = 2023`)、隐式类型转换(`WHERE id = '100'`,`id` 为整型)。 3. **InnoDB 为什么推荐用自增主键?** *解析*:自增主键保证数据顺序插入,减少 B+树分裂和页碎片[^4]。 > 更多题目可参考《110 道 MySQL 面试题及答案》PDF 手册[^1],包含锁冲突处理、死锁检测、分页优化等企业级案例。 [^1]: 110 道 MySQL 面试题及答案(持续更新) [^2]: 15 道常见 MySQL 查询语句面试题及解析 [^3]: MySQL 用户与权限管理解析 [^4]: MySQL 性能优化与慢查询日志分析
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值