Mysql必会面试题(基础篇)
文章目录
- Mysql必会面试题(基础篇)
- 基础
- 1. 什么是内连接、外连接、交叉连接、笛卡尔积呢?
- 2. MySQL 的内连接、左连接、右连接有什么区别?
- 3.说一下数据库的三大范式?
- 4.varchar 与 char 的区别?
- 5.blob 和 text 有什么区别?
- 6.DATETIME 和 TIMESTAMP 的异同?
- 7.MySQL 中 in 和 exists 的区别?
- 8.MySQL 里记录货币用什么字段类型比较好?
- 10.drop、delete 与 truncate 的区别?
- 12.count(1)、count(*) 与 count(列名) 的区别?
- 13.一条 SQL 查询语句的执行顺序?
- 14介绍一下 MySQL 的常用命令
- 15.MySQL 第 3-10 条记录怎么查?
- 16.用过哪些 MySQL 函数?
基础
什么是 MySQL?
mysql是一个开源的关系型数据库,
1. 什么是内连接、外连接、交叉连接、笛卡尔积呢?
Mysql中的连接是通过两个或多个表之间的列进行关联,从而获取相关联的数据。
- 内连接(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 的连接主要分为内连接和外连接,外连接又可以分为左连接和右连接。
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 的区别
- 日期范围:DATETIME 的日期范围是
1000-01-01 00:00:00.000000
到9999-12-31 23:59:59.999999
;TIMESTAMP 的时间范围是1970-01-01 00:00:01.000000
UTC到 ``2038-01-09 03:14:07.999999
UTC - 存储空间:DATETIME 的存储空间为 8 字节;TIMESTAMP 的存储空间为 4 字节
- 时区相关:DATETIME 存储时间与时区无关;TIMESTAMP 存储时间与时区有关,显示的值也依赖于时区
- 默认值:DATETIME 的默认值为 null;TIMESTAMP 的字段默认不为空(not null),默认值为当前时间(CURRENT_TIMESTAMP)
7.MySQL 中 in 和 exists 的区别?
MySQL 中的 in 语句是把外表和内表作 hash 连接,而 exists 语句是对外表作 loop 循环,每次 loop 循环再对内表进行查询。我们可能认为 exists 比 in 语句的效率要高,这种说法其实是不准确的,要区分情景:
- 如果查询的两个表大小相当,那么用 in 和 exists 差别不大。
- 如果两个表中一个较小,一个是大表,则子查询表大的用 exists,子查询表小的用 in。
- 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 的区别?
三者都表示删除,但是三者有一些差别:
区别 | delete | truncate | drop |
---|---|---|---|
类型 | 属于 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 的常用命令
说说数据库操作命令?
①、创建数据库:
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;