(1)MySQL 是一种关系型数据库,主要用于持久化存储系统中的一些数据,例如用户信息。由于 MySQL 是开源免费并且比较成熟的数据库,因此,MySQL 被大量使用在各种系统中。任何人都可以在 GPL (General Public License) 的许可下下载并根据个性化的需要对其进行修改。MySQL 的默认端口号是 3306
。
(2)MySQL 主要具有下面这些优点:
(1)在 MySQL 中,DDL 和 DML 都是 SQL 语言中的重要概念,它们分别代表数据定义语言 (Data Definition Language)
和数据操作语言 (Data Manipulation Language)
。
CREATE
:创建数据库对象,如表、索引、约束和视图等。ALTER
:修改数据库对象的结构,如修改表的列、约束和索引等。DROP
:删除数据库对象,如表、索引、约束和视图等。SELECT
:从表中获取数据。INSERT
:向表中插入新数据。UPDATE
:更新表中的数据。DELETE
:删除表中的数据。(2)总之,DML 和 DDL 都是 SQL 语言中非常重要的概念,DML 用于查询和修改表中的数据,DDL 用于定义和管理数据库结构,如创建、修改和删除表、索引、约束和视图等。
在 MySQL 中,varchar 和 char 都是用来存储文本类型数据的。其主要区别如下:
在 MySQL 中,BLOB 和 TEXT 都是用来存储大型二进制和文本数据的类型。它们的主要区别在于:
MySQL 中的 DATETIME 和 TIMESTAMP 都是用来存储日期和时间类型的数据,它们的相同点和不同点如下:
1000-01-01 00:00:00 ~ 9999-12-31 23:59:59
;而 TIMESTAMP 类型可以存储的日期和时间范围为 1970-01-01 00:00:01 ~ 2038-01-19 03:14:07
。8 字节
和 4 字节
。但是从 MySQL 5.6.4 开始,它们的存储空间会根据毫秒精度的不同而变化,DateTime 的范围是 5 ~ 8 字节
,Timestamp 的范围是 4 ~ 7 字节
。NULL
,对于 TIMESTAMP 类型,默认值为当前时间。相关文章:
美团面试:MySQL 保存日期用哪种数据类型?Datetime?Timestamp?数值时间戳?
(1)在 MySQL 中,IN 和 EXISTS 都是用来查询数据的关键字,它们的主要区别如下:
(2)总之,IN 和 EXISTS 都是用于查询数据的关键字,它们的功能、执行顺序、返回结果和数据类型都存在一定的区别,使用时需要根据实际需要选择合适的查询方式。在处理大量数据时,应该优先考虑使用 EXISTS 关键字,因为它的执行效率更高。
(1)在 MySQL 中记录货币建议使用 DECIMAL
字段类型。DECIMAL 是一种精确的定点数值类型,它可以精确地表示小数点前后的数字,并且支持大范围的数字精度和范围。在存储货币等金额数据时,精度和精确度非常重要,因为不能出现计算误差,否则会造成严重的财务问题。
(2)DECIMAL 类型有两个参数,第一个参数表示总共的数字个数(整数部分 + 小数部分),第二个参数表示小数部分的数字个数。例如,DECIMAL(10, 2) 可以存储 10 位数字中的小数点后两位,因此可以存储金额数值,保留两位小数。
(3)需要注意的是,虽然 FLOAT 或 DOUBLE 也可以用来存储金额,但这两个类型是近似数值类型,是以二进制存储的,计算机在表示一个数字时,其宽度是有限的,因此无限循环的小数存储在计算机时,只能被截断,所以就会导致小数精度丢失的情况。例如,十进制下的 0.2 就无法精确转换成二进制小数。因此,在处理货币金额时,建议使用DECIMAL类型来保证精确度。
/*
0.2 转换为二进制数的过程如下:
(1) 不断乘以 2,直到不存在小数为止;
(2) 在计算过程中,得到的整数部分从上到下排列就是二进制的结果;
*/
0.2 * 2 = 0.4 -> 0
0.4 * 2 = 0.8 -> 0
0.8 * 2 = 1.6 -> 1
0.6 * 2 = 1.2 -> 1
0.2 * 2 = 0.4 -> 0(发生循环)
...
(1)在 MySQL 中存储 Emoji 表情可以使用 utf8mb4
字符集,因为 Emoji 表情并不是标准的 Unicode 字符,需要使用 4 个字节来表示。
(2)以下是存储 Emoji 表情的步骤:
CREATE DATABASE mydatabase CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE TABLE mytable (
id INT PRIMARY KEY,
name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
SET NAMES utf8mb4;
INSERT INTO mytable (id, name) VALUES (1, '');
INSERT INTO mytable (id, name) VALUES (2, '\U0001F603');
# 第一个例子直接使用了 UTF-8 编码的表情字符,第二个例子使用了 Unicode 编码。
(3)总之,要在 MySQL 中存储 Emoji 表情,需要使用 utf8mb4 字符集,并将连接的字符集设置为 utf8mb4,然后可以直接使用 UTF-8 编码的表情字符或 Unicode 编码来插入 Emoji 表情。
(1)在 MySQL 中,DROP、DELETE 和 TRUNCATE 都可以删除表或清空表中的数据,但它们之间的区别如下:
delete | truncate | drop | |
---|---|---|---|
类型 | 属于 DML | 属于 DDL | 属于 DDL |
回滚 | 可回滚 | 不可回滚 | 不可回滚 |
删除内容 | 表结构还在,删除表的全部或者一部分数据行 | 表结构还在,删除表中的所有数据 | 从数据库中删除表,所有数据行,索引和权限也会被删除 |
删除速度 | 删除速度慢,需要逐行删除 | 删除速度快 | 删除速度最快 |
(2)因此,在不再需要一张表的时候,用 drop;在想删除部分数据行时候,用 delete;在保留表而删除所有数据的时候,用 truncate。
在 MySQL 中,UNION 和 UNION ALL 都用于将多个 SELECT 语句的结果组合到一个结果集中。但是它们之间有一些重要的区别:
(1)在 MySQL 中,聚合函数 COUNT() 函数用于返回查询结果中的行数。但是,COUNT() 函数的三种不同写法 COUNT(1)、COUNT(*)、COUNT(column_name) 之间有一些区别:
因此,当需要计算结果集中的行数时,可以使用 COUNT(1) 或 COUNT(*)。当需要计算特定列中的非 NULL 值数量时,可以使用 COUNT(column_name)。在大多数情况下,COUNT(*) 是最常用的写法,因为它比 COUNT(1) 更容易理解,而且性能相差不大。
(2)执行速度:
(1)在 MySQL 中,CUBE 和 ROLLUP 都是用于生成聚合数据的查询扩展,它们可以在一次查询中生成多个聚合结果,并在结果集中添加一个或多个小计行。它们的区别在于生成小计行的方式和范围不同
。CUBE 子句会在所有可能的维度上生成总计,而 ROLLUP 子句则是在指定的列上按层次结构生成总计。
SELECT column_1, column_2, column_3, SUM(value)
FROM table_name
GROUP BY CUBE(column_1, column_2, column_3);
SELECT column_1, column_2, column_3, SUM(value)
FROM table_name
GROUP BY column_1, column_2, column_3 WITH ROLLUP;
(2)因此,CUBE 子句适用于需要生成所有可能维度的聚合数据的情况,而 ROLLUP 子句则适用于按层次结构生成聚合数据的情况。同时,需要注意,使用 CUBE 或 ROLLUP 都会增加查询的计算量和数据量,可能会影响查询的性能。
的记录才被插入虚拟表 VT7 中;上述过程可简单表述为:
FROM
:从指定的表或视图中选择要查询的数据源;ON
与 JOIN
:将多个表连接起来,根据指定的连接条件进行关联;WHERE
:对数据进行筛选,只选择满足条件的记录;GROUP BY
:按指定的列进行分组;HAVING
:对分组后的数据进行筛选,只选择满足条件的分组;SELECT
:选择要查询的列或表达式,计算所需的结果。DISTINCT
:去除重复的记录。ORDER BY
:按指定的列对结果集进行排序。LIMIT
:限制结果集的数量。UNION (ALL)
:合并多个查询的结果集。OFFSET
:指定结果集开始的位置。注意:一般来说,一条 SQL 不会覆盖上面所有的执行过程!
(2)在 MySQL中,SQL 语句的执行过程通常分为以下几个步骤:
MySQL中的内连接、左连接和右连接是用来连接两个或多个表的操作,它们之间的区别如下:
NULL
。NULL
。(1)JDBC (Java Database Connectivity) 是 Java 语言中用于与关系型数据库进行交互的标准 API。它定义了一组 Java 接口和类,使得 Java 应用程序可以通过标准的方式连接、查询和操作各种关系型数据库,如 MySQL、Oracle、PostgreSQL、SQL Server 等。
(2)JDBC API 提供了一组标准的 Java 接口,用于连接数据库、执行 SQL 语句、处理结果集、事务处理等,使得 Java 程序员可以通过 Java 代码来操作数据库,而无需了解底层数据库的细节和特性。它将 Java 应用程序和各种关系型数据库解耦,使得 Java 应用程序能够以一种独立于数据库的方式进行开发和维护。
(3)JDBC API 包含两个层次:JDBC API
和 JDBC 驱动程序
:
(4)JDBC API 的使用非常广泛,几乎所有的 Java 应用程序都需要与数据库进行交互,包括 Web 应用程序、桌面应用程序、移动应用程序等。由于 JDBC API 是 Java 标准 API 的一部分,因此它与 Java 平台的兼容性非常好,而且各种数据库厂商都提供了相应的 JDBC 驱动程序,使得 Java 程序员可以方便地与各种数据库进行交互。
(1)使用 JDBC 进行查询通常包括以下步骤:
Class.forName()
方法加载数据库驱动程序,例如:Class.forName("com.mysql.jdbc.Driver");
DriverManager.getConnection()
方法创建与数据库的连接,例如:String url = "jdbc:mysql://localhost:3306/mydatabase";
String user = "myuser";
String password = "mypassword";
Connection conn = DriverManager.getConnection(url, user, password);
createStatement()
方法创建 Statement 对象,然后使用 Statement 对象创建 SQL 查询语句,例如:Statement stmt = conn.createStatement();
String sql = "SELECT * FROM customers WHERE city = 'London'";
executeQuery()
方法执行 SQL 查询语句,例如://这里将 SQL 查询语句传递给 executeQuery() 方法,它会返回一个 ResultSet 对象,该对象包含查询结果的数据
ResultSet rs = stmt.executeQuery(sql);
getXXX()
方法获取查询结果的数据,例如:while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
String email = rs.getString("email");
System.out.println("id: " + id + ", name: " + name + ", email: " + email);
}
close()
方法关闭连接和资源,例如:rs.close();
stmt.close();
conn.close();
(2)综上所述,使用 JDBC 进行查询的步骤包括:加载 JDBC 驱动程序、创建数据库连接、创建 SQL 查询语句、执行 SQL 查询语句、处理查询结果和关闭连接和资源。
(1)PreparedStatement
和 Statement
是 Java 中用于与数据库交互的两种不同类型的接口,并且前者是后者的子接口,都可以用于执行 SQL 语句,但是它们之间有几个主要的区别:
(2)综上所述,PreparedStatement 比 Statement 更加安全、易于阅读和理解,并且在执行相同 SQL 语句的情况下,性能更好。因此,在实际开发中,PreparedStatement 更常用。
与 SQL 注入攻击有关的知识可以参考 SQL 注入攻击介绍这篇文章。
(1)在 MySQL 中,删除数据的原理可以简单地概括为以下几个步骤:
(2)需要注意的是,MySQL 的删除操作是一个原子操作,要么全部删除,要么一个都不删除。此外,删除操作的性能受多种因素影响,如表的大小、索引的使用、删除条件的复杂性等。对于大表的删除操作,可能需要较长的执行时间。为了保证删除操作的效率,可以考虑合理设计表结构、创建适当的索引和优化查询语句。
(1)在 MySQL 中,视图 (View) 是基于查询结果的虚拟表。视图以查询的形式定义,并且可以像表一样使用。它提供了一种简化复杂查询、重用查询逻辑和实现安全性控制的方法。
(2)MySQL 中的视图有以下几个主要作用:
需要注意的是,尽管视图提供了上述的便利和功能,但它们并不是实际的物理表,它们只是存储在数据库中的查询定义。因此,在对视图进行查询时,实际上是执行视图定义的查询语句,而不是直接访问底层数据表。
(3)创建 MySQL 视图可以通过以下步骤:
CREATE VIEW
语句创建视图,并指定视图的名称。其中,view_name 是视图的名称,column1、column2 等是要选择的列,table_name 是用于构建视图的表,condition 是一个可选的 WHERE 子句,用于过滤数据。CREATE VIEW view_name AS
SELECT column1, column2, ...
FROM table_name
WHERE condition;
CREATE VIEW
语句后,视图会被创建并存储在数据库中。你可以像使用表一样使用这个视图,对它进行查询等操作。(4)下面是一个实际的创建视图的示例:
假设我们有一个名为 “employees” 的表,包含 “emp_id”、“emp_name” 和 “salary” 等列。我们可以创建一个为 “high_salary_employees” 的视图,只包含薪资高于 100000 的员工:
CREATE VIEW high_salary_employees AS
SELECT emp_id, emp_name
FROM employees
WHERE salary > 100000;
这样,当我们查询 high_salary_employees 视图时,将只返回薪资高于 100000 的员工的员工编号和姓名。注意,视图只是一个虚拟的表,它实际上并不存储数据。它只是一个查询定义的结果集。因此,当查询视图时,实际上是执行视图定义的查询语句。
(1)使用 limit 进行分页查询存在的问题主要包括以下几点:
LIMIT
进行分页查询时,数据库需要执行完整的查询,然后再将结果集中的部分数据截取出来。这意味着,在每次分页查询时,数据库需要获取和处理全部记录,即使只返回了部分数据。对于大数据量和复杂的查询,这可能导致性能问题,特别是在较高的页数或者需要获取很多数据时。LIMIT
进行分页查询,只能获取当前页的数据,而无法直观地看到总页数和总记录数。如果需要获取总页数和总记录数,通常需要额外执行一次查询来计算。(2)基于游标和使用 ROW_NUMBER()
函数都是实现分页查询的常见方法,它们的原理如下:
ROW_NUMBER()
函数可以给查询结果中的每一行分配一个序号。在分页查询时,可以利用 ROW_NUMBER()
函数给结果集中的每条记录编号,然后通过条件语句选择指定区间的序号范围来返回对应的分页数据。通常情况下,结合子查询进行使用,以便在外部查询中使用 LIMIT
或其他分页限制来获取指定的数据范围。(3)这两种分页查询方式都可以在数据库中进行操作,但它们的实现方式略有不同:
ROW_NUMBER()
函数可以在数据库层面进行排序和筛选,适用于大数据量和更精确的分页场景。(4)以下是基于游标和使用 ROW_NUMBER() 函数的分页查询示例:
DECLARE cur CURSOR FOR
SELECT column1, column2
FROM your_table
ORDER BY column1; -- 假设按列 column1 排序
SET @offset = 20; -- 起始位置
SET @limit = 10; -- 每页数据量
SELECT * FROM (
SELECT column1, column2, (@row_number:=@row_number + 1) AS row_num
FROM your_table, (SELECT @row_number := 0) AS t
ORDER BY column1
) AS subquery
WHERE row_num > @offset
LIMIT @limit;
SELECT column1, column2
FROM (
SELECT column1, column2, ROW_NUMBER() OVER (ORDER BY column1) AS row_num
FROM your_table
) AS subquery
WHERE row_num BETWEEN 21 AND 30; -- 起始位置为 20,每页数据量为 10