一、关系型数据库和非关系型数据库
关系型数据库(Relational Database,简称RDBMS)和非关系型数据库(NoSQL Database)是两种不同的数据库类型。
SQL本身叫做结构化查询语言
1、关系型数据库:(MySQL、Oracle)
1)是一种基于表格结构存储数据的数据库系统。
2)使用SQL(Structured Query Language,结构化查询语言)进行数据管理和查询。
3)数据以行和列的形式组织,每行代表一个记录,每列代表一个属性。
4)关系型数据库通常支持事务处理,保证数据的一致性和完整性。
常见的关系型数据库有MySQL、Oracle、Microsoft SQL Server等。
2、非关系型数据库:(MongoDB、Redis)
1)不采用传统的表格形式存储数据,而是使用不同的数据模型,如文档、键值对、图形、列族等。
2)SQL不是其主要的数据操作语言,而是使用特定的语言或API进行数据管理和查询。
3)非关系型数据库通常具有更高的可扩展性、灵活性和性能,适合处理大量非结构化或半结构化数据。
4)常见的非关系型数据库有MongoDB、Cassandra、Redis等。
总的来说,关系型数据库适用于需要高度结构化数据和复杂查询的应用场景,而非关系型数据库则更适合处理大规模、高并发、灵活变化的数据
二、Orcal数据库和MySql数据库的区别
两者都是关系型数据库
1、在数据库的存储处理方面,MySQL更注重运行速度,而Oracle则更注重数据的完整性和安全性。
因此,在大型的数据存储处理上会更倾向于使用Oracle数据库,
而在小型的数据存储处理上,MySQL则是更优的选择
2、在SQL语法上,MySQL对SQL语法的支持较好,完全支持SQL92标准,但是对于在SQL2003和
SQL2008中新增的标准,MySQL存在一些限制。
而Oracle则是对SQL标准的支持较为全面,可以更好地应用更多的SQL语法。
3、MySQL 社区版是开源状态的数据库,可免费使用,安装和部署也相对简单。
而Oracle则是非开源的商业版数据库,需要购买许可证才能使用,同时其安装和部署也更为复杂。
Oracle:Oracle数据库通常用于大型企业级应用,特别是那些需要高度安全性和复杂查询处理的应用。例如,金融、电信、政府等行业往往会选择Oracle作为其核心数据库系统。
MySQL:MySQL适用于中小型企业和个人开发者,特别是那些需要快速部署和低成本运行的应用。由于其开源特性,MySQL也常被用于学习和教学目的。
三、关系型数据库当中什么是约束,包含哪些?
在关系型数据库中,约束是用来确保数据完整性的机制。它们限制了数据库表中数据的值,以确保数据
的准确性和可靠性。约束可以防止无效或不完整的数据被插入到数据库表中。
在关系型数据库中,约束(Constraints)是用来确保数据完整性和一致性的规则。它们帮助数据库管理系统(DBMS)验证和限制数据的输入和修改,从而防止无效数据的插入和更新。
常见的约束类型包括:
1. **主键约束(Primary Key Constraints)**:用于唯一标识表中的每一行数据。主键必须是唯一的、非空的,并且不能重复。通常情况下,主键由一个或多个字段组成,这些字段被称为候选键。
2. **外键约束(Foreign Key Constraints)**:用于建立两个表之间的关联关系。外键引用另一个表的主键或唯一键,确保数据的一致性和完整性。当在一个表中插入或更新数据时,如果违反了外键约束,将会引发错误。
3. **唯一性约束(Unique Constraints)**:用于确保表中的某个或某些列的值是唯一的。唯一性约束可以应用于单个列或多列组合,但不允许有重复的值。
4. **检查约束(Check Constraints)**:用于定义列的取值范围或条件。检查约束允许用户指定特定的条件,只有满足这些条件的数据才能被插入或更新到表中。
5. **默认值约束(Default Constraints)**:用于为表中的列指定默认值。如果没有显式地为该列提供值,则会使用默认值。
6. **空值约束(Null Constraints)**:用于控制列是否允许空值。通过设置NOT NULL约束,可以禁止列为空;而通过设置允许空值,可以允许该列为空。
7. **部分索引约束(Partial Index Constraints)**:用于创建只针对部分数据进行索引的索引。这种约束可以帮助优化查询性能,同时减少索引文件的大小。
以上就是关系型数据库中常见的约束类型及其作用。
在创建表时,可以指定这些约束,以确保数据满足特定的要求和规则。这些约束有助于维护数据的准确
性和一致性,并减少错误和不一致的情况。
四、什么三范式?
三范式是关系型数据库设计中数据库的模式设计规范,
用于确保数据的完整性、一致性和准确性。
三范式包括:
1. 第一范式(1NF):确保每个列都是不可分割的最小单元,即原子性。
2. 第二范式(2NF):在第一范式的基础上,非主键列必须完全依赖于主键,不能只依赖于主键的一
部分。如果一个表有一个联合主键,那么其他列必须依赖于整个联合主键,而不是其中的部分。
3. 第三范式(3NF):在第二范式的基础上,任何列都不能传递依赖。也就是说,如果一个列A依赖
于列B,而列B又依赖于列C,那么列A不能直接依赖于列C。必须通过列B作为中间表。
主要可以减少数据冗余、避免数据不一致性和提高数据库的性能。然而,有时为了提高查询性能或满足
特定的业务需求,设计者可能会选择违反三范式。这需要权衡利弊,并确保在实际应用中实现必要的数
据完整性控制和约束。
简单的说就是:1NF 表示每个属性不可分割,2NF 表示非主属性不存在对主键的部分依赖,3NF 表示
不存在非主属性对主键的依赖传递。
五、数据库语言的分类,分别包含哪些?
DDL—数据定义语言(CREATE,ALTER,DROP,DECLARE)
DML—数据操纵语言(SELECT,DELETE,UPDATE,INSERT)
DCL—数据控制语言(GRANT,REVOKE,COMMIT,ROLLBACK)
在数据库管理中,DDL、DML和DCL是三种不同的数据库语言类型,它们分别用于不同的目的。
一、DDL (Data Definition Language):数据定义语言,用于定义和修改数据库结构。
DDL 语句可以用来创建、修改和删除数据库对象,例如表、索引、视图、存储过程等。常见的 DDL 语句包括:
1、CREATE:创建新的数据库对象。
2、ALTER:修改现有的数据库对象。
3、DROP:删除数据库对象。
4、TRUNCATE:清空表中的所有行,但不删除表结构。
二、DML (Data Manipulation Language):数据操作语言,用于对数据库中的数据进行增删改查操作。
DML 语句可以用来插入、更新、删除和查询数据。常见的 DML 语句包括:
1、SELECT:从数据库中选择数据。
2、INSERT:向数据库中插入新数据。
3、UPDATE:更新数据库中的数据。
4、DELETE:从数据库中删除数据。
三、DCL (Data Control Language):数据控制语言,用于控制数据库的访问权限和安全性。
DCL 语句可以用来授予或撤销用户的权限。常见的 DCL 语句包括:
1、GRANT:授予用户访问数据库的权限。
2、REVOKE:撤销用户的访问权限。
3、COMMIT:提交事务,保存所有更改。
4、ROLLBACK:回滚事务,撤销所有更改。
以上三种语言类型是数据库管理的基础,通过它们可以有效地管理和维护数据库系统
六、什么是事务
在数据库管理系统(DBMS)中,一个事务(Transaction)是一系列操作,
这些操作要么全部成功执行(提交),要么全部失败回滚(撤销)。
事务的目的是保证数据库的完整性和一致性。
一、事务通常具备以下四个关键特性,简称ACID:
1、原子性(Atomicity):事务中的所有操作都是一个不可分割的工作单位。要么全部成功,要么全部失败。
2、一致性(Consistency):事务必须使数据库从一个有效状态转换到另一个有效状态,维护数据的完整性约束。
3、隔离性(Isolation):多个事务并发执行时,每个事务都应该像它是系统中唯一运行的事务一样。事务的结果不会被其他并发事务干扰。
4、持久性(Durability):一旦事务提交,其结果就应该永久保存在数据库中,即使系统故障也不会丢失。
二、事务通常包含以下步骤:
1、开始事务(Begin Transaction):标志着事务的开始。
2、执行操作(Execute Operations):进行一系列数据库操作,例如插入、更新或删除数据。
3、提交事务(Commit Transaction):如果所有操作都成功,事务被提交,所有更改被保存到数据库中。
4、回滚事务(Rollback Transaction):如果在执行操作过程中出现错误或某些条件不满足,事务被回滚,所有更改都被撤销。
使用事务可以确保数据库操作的安全性和可靠性,特别是在多用户并发访问的情况下。
七、MySQL的会吗?一些基本的增删改查会吗?
表的创建:create table 表名 (列名 1 类型 约束,列 2 类型 约束…)
表的删除:drop table 表名
表的更改(结构的更改,不是记录的更新):alter table 表名 add|drop 列名|约束名
插入记录:insert into 表名…values…
更新记录:update 表名 set 列名=值 where 条件
删除记录:delete from 表名 where 条件
八、SQL 的 select 语句完整的执行顺序?
from 子句组装来自不同数据源的数据;
where 子句基于指定的条件对记录行进行筛选;
group by 子句将数据划分为多个分组; 使用聚集函数进行计算; 使用 having 子句筛选分组 计算所有的表达式;
select 的字段; 使用 order by 对结果集进行排序。
GROUP BY 语句用于将结果集按照一个或多个列进行分组。
通常与聚合函数(如 SUM、AVG、MAX、MIN、COUNT)一起使用。
例如:
SELECT column1, column2, AGGREGATE_FUNCTION(column3)
FROM table_name
GROUP BY column1, column2;
HAVING 语句用于对分组后的结果集进行过滤。
它只能在 GROUP BY 之后使用。
例如:
SELECT column1, column2, AGGREGATE_FUNCTION(column3)
FROM table_name
GROUP BY column1, column2
HAVING condition;
九、表的连接查询方式有哪些,有什么区别?
1、内连接
只要有匹配关系,连接的多个表中的所有列都可以返回,但是只返回多个表中匹配的行,不匹配的行将被忽略
1)等值连接(简单内连接)
基于多个表中一个或多个列的值【相等】来连接表,并返回相关表中满足连接条件的匹配行
1.1)两表连接:
1、基本用法
SELECT column1, column2, ...
FROM table1
INNER JOIN table2
ON table1.column_name = table2.column_name;
2、#使用表别名、where字句过滤 的方式:
SELECT o.order_id, c.customer_name
FROM orders AS o
INNER JOIN customers AS c
ON o.customer_id = c.customer_id;
WHERE o.order_date >= '2023-01-01' and c.create_time >= '2023-01-01';
3、#自连接 (Self Join):自连接是指一个表与自身进行连接。通常用于查找表中相似的或相关的记录。例如:
SELECT *
FROM table1 AS t1
INNER JOIN table1 AS t2
ON t1.column_name = t2.column_name;
1)where字句过滤条件错误
ambiguous :歧义
2)where字句过滤条件正确
会把两个表的所有列都汇总在一起返回,相同的列也是也都返回,不会合并
正确:
3)select 读取字段错误:
4)select 读取字段正确:
1.2)多表连接:
SELECT o.order_id, c.customer_name, p.product_name
FROM orders
INNER JOIN customers As c ON orders.customer_id = c.customer_id
INNER JOIN order_items As oi ON o.order_id = oi.order_id
INNER JOIN products As p ON oi.product_id = p.product_id;
2)自然连接(了解即可,高版本中已废弃)
NATURAL JOIN 在 MySQL 8.0 及更高版本中已被弃用
“NATURAL JOIN”是一种特殊的连接两个或多个表的方式。当你使用“NATURAL JOIN”时,MySQL会自动找出两个表中所有名称相同、数据类型也相同的列,并基于这些列进行连接。
1、INNER JOIN:你需要明确指定连接的条件
2、NATURAL JOIN:与上述JOIN类型不同,你不需要明确指定连接条件。MySQL会自动找出两个表中所有名称和数据类型都相同的列,并基于这些列进行连接
3、使用 NATURAL JOIN 可能会带来一些风险,因为它依赖于列名的匹配。如果表的结构发生变化,可能会导致意外的连接结果。因此,通常建议使用 ON
或 USING
子句来明确指定连接条件。例如:
SELECT *
FROM table1
NATURAL JOIN table2;
已经弃用,使用会报语法错误
2、外连接
1、连接的方向(左或右)并不决定结果集的列顺序,而是取决于你在 FROM
和 JOIN
子句中指定的表的顺序。from A, 那么返回结果里 A的列就在左边 ,与左右连接无关。
2、当使用了多个 LEFT JOIN 来连接不同的表,但是每个 LEFT JOIN 的结果都会被视为一个新的“左表”,并与下一个表进行连接。这时,from A, 那么返回结果里 A的列就在左边,LEFT JOIN B,LEFT JOIN C,LEFT JOIN D,那么返回的结果从左到右的顺序就是 A、B、C、D
1)左外连接
返回左表(table1)的所有行,并包括右表(table2)中匹配的行,如果右表中没有匹配的行,将返回 NULL 值
1、基本用法:
SELECT column1, column2, ...
FROM table1
LEFT JOIN table2
ON table1.column_name = table2.column_name;
2、使用表别名、where过滤条件字句:
SELECT c.customer_id, c.customer_name, o.order_id
FROM customers As c
LEFT JOIN orders As a
ON c.customer_id = o.customer_id
WHERE o.order_date >= '2023-01-01' OR o.order_id IS NULL;
3、多表连接:
SELECT customers.customer_id, customers.customer_name, orders.order_id, products.product_name
FROM customers
LEFT JOIN orders ON customers.customer_id = orders.customer_id
LEFT JOIN order_items ON orders.order_id = order_items.order_id
LEFT JOIN products ON order_items.product_id = products.product_id;
正确使用:
均有值
或者:
右表无值:默认是按1返回的
2)右外连接
返回右表(table2)的所有行,并包括左表(table1)中匹配的行,如果左表中没有匹配的行,将返回 NULL 值
1、基本用法:
SELECT column1, column2, ...
FROM table1
RIGHT JOIN table2
ON table1.column_name = table2.column_name;
2、使用表别名、where过滤条件字句:
SELECT c.customer_id, c.customer_name, o.order_id
FROM customers As c
RIGHT JOIN orders As a
ON c.customer_id = o.customer_id
WHERE o.order_date >= '2023-01-01' OR o.order_id IS NULL;
3、多表连接:
SELECT customers.customer_id, customers.customer_name, orders.order_id, products.product_name
FROM customers
RIGHT JOIN orders ON customers.customer_id = orders.customer_id
RIGHT JOIN order_items ON orders.order_id = order_items.order_id
RIGHT JOIN products ON order_items.product_id = products.product_id;
左表无值:默认是按1返回的
查询中指定的表是哪个,哪个就在左边
3)全外连接
SELECT *
FROM tablel
LEFT J0IN table2
ON tablel.id = table2.id
UNION ALL
SELECT *
FROM tablel
RIGHT J0IN table2
ON tablel.id = table2.id
WHERE tablel.id IS NULL:
内连接和全外连接的区别:
内连接(INNER JOIN)返回两个表中都存在的行,即匹配的行。它只会显示在两个表中都有对应的值的记录。
全外连接(FULL OUTER JOIN)则返回所有的行,即使在两个表中的某一侧没有匹配的行。对于没有匹配的行,缺失的列将被填充为 NULL 值。
以下是它们之间的主要区别:
1、返回结果:内连接只返回两个表中都有的行,而全外连接返回所有的行,包括没有匹配的行。
2、NULL 值处理:在全外连接中,缺失的列将被填充为 NULL 值,而在内连接中,缺失的行将被忽略。
3、用途:内连接用于查找两个表之间的相似之处,而全外连接用于查找两个表之间的所有数据,包括不匹配的部分。
不匹配的行,可以理解为,A表共10行数据满足连接条件,B表只有7行数据满足连接条件
内连接的时候,汇总结果是返回7行
外连接的时候,汇总结果是返回10行,其中B表中无匹配的三行,会填充为null
3、交叉连接
交叉连接(CROSS JOIN
)是一种特殊类型的 SQL 连接操作,它将一个表中的每一行与另一个表中的每一行进行组合,生成一个笛卡尔积。换句话说,交叉连接会返回所有可能的行组合,忽略任何匹配条件
cross join,就是笛卡尔乘积
SQL 中连接按结果集分为:内连接,外连接,交叉连接
一、内连接:inner join on,两表都满足的组合。内连接分为等值连接,不等连接,自然连接。
1、等值连接:两表中相同的列都会出现在结果集中。(获取两个表中字段匹配关系的记录)
2、自然连接:两表中具体相同列表的列会合并为同一列出现在结果集中。
二、外连接:分为左(外)连接,右(外)连接,全连接
1、左(外)连接:A left (outer) join B,以 A 表为基础,A 表的全部数据,B 表有的组合,没有
的为null。
2、右(外)连接:A right(outer) join B,以 B 表为基础,B 表的全部数据,A 表有的组合,没有的
位 null。
3、全(外)连接:A full (outer) join 两表相同的组合在一起,A 表有,B 表没有的数据(显示为
null),同样 B表有,A 表没有的显示为 null。
三、交叉连接:cross join,就是笛卡尔乘积
十、为什么要使用数据库?(一般什么情况下使用数据库)
1、当需要存储和管理大量结构化数据时。
2、当多个用户或系统需要共享和协作处理同一组数据时。
3、当数据的安全性和完整性非常重要时。
4、当需要进行复杂的数据分析和报告生成时。
5、当需要快速地检索和处理大量数据时。
6、在软件开发中,需要一个可靠的后端数据存储解决方案时。
一般如何使用数据库
1、在执行测试用例时,有时候需要去数据库去添加测试数据
2、在执行测试用例时,有时需要到数据库验证数据的准确性与完整性
3、进行bug定位时,有时需要到数据库查看数据的详细信息
4、构造某种测试场景时,可以在数据库里直接修改数据,要比使用界面更有效率(支付-支付完成
数据库改一个状态就可以了。)
5、软件升级过程中,经常会涉及到对历史数据的处理,这种情况需要执行升级sql,并验证结果。
十一、怎么显示前几行的数据?
可以使用 LIMIT 子句来限制查询结果的行数。LIMIT 后面跟着你想要的行数。
例如,如果你想显示表 employees 中的前5行,你可以这样写:
SELECT FROM employees LIMIT 5;
降序:薪水最低的前5名
SELECT FROM employees ORDER BY salary DESC -- 以薪水降序排序
LIMIT 5;
无返回结果
有返回结果:
升序:薪水最高的前5名
SELECT * FROM employees ORDER BY salary ASC -- 以薪水升序排序
LIMIT 5;
十二、怎么去除重复的数据?
可以使用 DISTINCT 关键字来去除重复的数据。比如:
SELECT DISTINCT column1, column2, ... FROM your_table;
说明:
1、your_table 是你要查询的表的名称
2、column1, column2, ... 是你指定的列。
3、DISTINCT 将对指定列 的值进行去重。
例如,如果你有一个名为 employees 的表,并且想要获取不重复的职位信息,可以这样写:
SELECT DISTINCT job_title FROM employees;
十三、Mysql 数据库中怎么实现分页?
1、LIMIT
select * from table limit (start-1)*limit,limit;
常见的分页查询模式,用于从一个名为 table
的表中获取特定的页数
其中 start 是页码,limit 是每页显示的条数。
-
(start-1)*limit
是计算偏移量的公式,其中start
是要显示的页码,limit
是每页显示的记录数。这个公式计算出要跳过的前面页的总记录数。limit
是每页显示的记录数。
例如,如果你想在每页显示 10 条记录,并且你想要查看第 3 页的数据,那么查询将变成:
SELECT * FROM table LIMIT (3-1)*10,10;
这将跳过前面两页的 20 条记录,然后返回接下来的 10 条记录,即第 3 页的数据。
请注意,这种方法在处理大型表时可能会遇到性能问题,因为它需要扫描整个表来找到偏移量之后的行。对于更高效的分页查询,可以考虑使用 ROW_NUMBER()
函数(如果你使用的是 MySQL 8.0 或更高版本)
LIMIT 关键字后面的两个参数实际上总是相等的。这是因为第一个limit参数 (start-1)*limit 是用来计算偏移量的,而第二个limit参数则指定了要返回的行数,也就是每页的记录数。
虽然在这种情况下,两个参数相等,但它们在语义上仍然有所不同。
第一个参数定义了结果集的起始点(通过跳过前面的行),而第二个参数定义了结果集的大小(即每页的记录数)。
2、OFFSET
1. 简单分页
假设你有一个名为 employees 的表,并且你想要每页显示 10 条记录。以下是第一页的查询:
SELECT * FROM employees LIMIT 10;
这将返回表的前 10 行数据。
2. 分页查询(带偏移量)
如果你想要查看第二页的记录(从第 11 条记录开始),可以使用 LIMIT 和 OFFSET 一起:
SELECT * FROM employees LIMIT 10 OFFSET 10;
这将跳过前 10 行,然后返回接下来的 10 行数据。
3. 动态分页
在实际应用中,你可能需要根据用户输入的页码来动态生成分页查询。例如,如果用户请求第 3 页,且每页显示 10 条记录,你可以这样写查询:
SELECT * FROM employees LIMIT 10 OFFSET (3 - 1) * 10;
这里我们使用了一个简单的计算 (页码 - 1) * 每页显示的记录数 来计算偏移量。
4. 使用 ROW_NUMBER()
MySQL 8.0 及更高版本支持使用 ROW_NUMBER() 函数来实现分页。例如:
SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY id) AS row_num
FROM employees
) t
WHERE t.row_num BETWEEN 11 AND 20;
这将返回第 2 页的记录(从第 11 条记录到第 20 条记录)。
十四、Mysql数据库的操作
修改表结构: 修改字段名与类型:使用ALTER TABLE语句,配合CHANGE关键字。 例如,将students表中的birthday字段更名为birth,并更改其数据类型为DATETIME:
修改字段属性:使用ALTER TABLE语句,配合MODIFY关键字。 例如,将students表中的birth字段的数据类型更改为DATE:
插入数据:
1 SELECT DISTINCT column1, column2, ... FROM your_table;
1 SELECT DISTINCT job_title FROM employees;
1 ALTER TABLE 表名 CHANGE 原字段名 新字段名 数据类型 [约束];
1 ALTER TABLE students CHANGE birthday birth DATETIME NOT NULL;
1 ALTER TABLE 表名 MODIFY 列名 数据类型 [约束];
1 ALTER TABLE students MODIFY birth DATE NOT NULL;
全列插入:使用INSERT INTO语句。 例如,向students表中插入一条记录:
部分列插入:指定要插入的列,然后提供对应的值。值的顺序与列的顺序对应。 例如,向students表的name和birthday列中插入数据:
更新数据:
使用UPDATE语句,配合SET子句指定要更新的列及其新值。使用WHERE子句来指定更新的条件。 例如,更新students表中某个学生的性别和家乡信息:
备份与恢复数据: 使用mysqldump命令进行备份,使用mysql命令进行恢复。
备份:备份整个数据库。
恢复:从备份文件中恢复数据到数据
十五、Mysql如何进行模糊查询
select * from member where 列名 like 'x%';
模糊查询的语法为:SELECT 字段 FROM 表 WHERE 某字段 LIKE 条件;
SQL 提供了多种模糊匹配方式,比较常用的有如下:
1、%:表示零个或多个字符,可以匹配任意类型和任意长度的字符,如
select * from member where 列名 like 'x%';-- 以 x 开头
select * from member where 列名 like '%x';-- 以 x 结尾
select * from member where 列名 like '%x%'; -- 包含 x
十六、数据库怎么优化查询效率?
1. 选择合适的存储引擎:
根据应用的需求选择合适的存储引擎,如InnoDB或MyISAM。InnoDB支持 事务处理,适用于需要高并发写入的场景;而MyISAM在读密集的场景中表现较好。
2. 分表分库与读写分离:
对于大型数据库,可以通过分表分库策略将数据分散到多个物理表中,提 高查询效率。同时,利用主从复制技术实现读写分离,减轻主服务器的负载。
3、索引优化:
1)选择性原则:索引列的选择性越高(唯一值的数量越多),索引的效果越好。
2)覆盖索引:如果一个查询只需要访问索引中的数据,而不需要访问数据行,这种索引被称为 覆盖索引,它可以显著提高查询速度。
3)复合索引:根据查询模式创建复合索引,确保索引的前缀能够覆盖大部分查询条件。
4)避免全表扫描:尽量避免在没有索引的列上进行查询,这会导致全表扫描。
4、避免NULL值判断:
在where子句中对NULL值进行判断会导致索引失效,进而进行全表扫描。尽量 避免使用IS NULL或IS NOT NULL操作符。
5. 避免使用!=或<>操作符:
这些操作符会导致索引失效。尽量使用代替<>,或者重构查询以避 免使用它们。
6. 避免使用OR连接条件:
当在where子句中使用OR连接条件时,如果其中一个字段有索引,另一个 没有,那么索引可能不会被使用。尽量避免使用OR,或者考虑将查询重构为多个查询并使用UNION。
7. 减少不必要的更新操作:
只更新必要的字段而不是整个记录,以减少I/O操作和日志记录的开销。
8. 优化JOIN操作:
1)小表驱动大表:先处理小表可以提高查询效率。
2)使用内连接代替外连接:当不需要返回所有的记录时,使用内连接代替外连接可以减少结果 集的大小。
3)分页JOIN:对于大数据量的表JOIN操作,先进行分页再JOIN可以提高性能。
9. 使用查询缓存:
根据数据库的配置,开启查询缓存可以避免重复执行相同的查询。
10. 定期进行数据库维护:
如优化表(OPTIMIZE TABLE),修复表(REPAIR TABLE)等操作可以 保持数据库和索引的健康状态。
11. 考虑使用数据库代理:
如ProxySQL、Vitess等可以帮助实现查询路由、缓存、限流等功能,进一 步优化数据库性能。
12. 硬件和配置优化:
根据数据库的工作负载类型(如OLTP、OLAP等)对硬件进行优化配置,如增加
RAM、使用SSD、调整I/O配置等。
13. 监控与调优:
持续监控数据库的性能指标,如查询响应时间、磁盘I/O、CPU利用率等,根据监控 数据进行针对性的调优。
十七、什么是事务?
数据库事务是指作为【单个逻辑】【工作单元】执行的一系列操作。这些操作要么全部执行,要么全部不执行
比如:一个简单的事务实例是转账过程:
用户A要将100元转账给用户B,这一过程中需要将两个
用户的账户余额分别减少100元和增加100元。
如果操作中途出现问题或中断,可能会导致用户的钱无法转出或转入,造成财务问题。
因此,数据库事务的目的是确保这一系列操作能够完整、准确地完成,以保证数据的完整性和一致性。
十八、事务的特性?
1、原子性:事务中的全部操作在数据库中是不可分割的,要么全部完成,要么均不执
行。
2、一致性:几个并行执行的事务,其执行结果必须与按某一顺序串行执行的结果相一致。
3、隔离性:事务的执行不受其他事务的干扰,事务执行的中间结果对其他事务必须是透明的。
4、持久性:对于任意已提交事务,系统必须保证该事务对数据库的改变不被丢失,即使数据库出现故障
十九、简述什么是存储过程和触发器?
存储过程是数据库中预编译的SQL语句集合,这些语句可以在一个名称下存储并作为一个单元进行处 理。存储过程可以接受参数、返回结果,并且可以像函数一样被多次调用。 举个例子,假设我们有一个名为“GetEmployee”的存储过程,它接受一个参数(员工ID),并返回该员 工的详细信息。在调用该存储过程时,我们可以传递一个具体的员工ID,存储过程将返回相应的员工信 息。这样,如果我们在应用程序中需要获取员工信息,只需要调用这个存储过程即可,而不需要每次都 编写完整的SQL查询语句。同时可以提高数据库操作的效率和性能,因为它可以减少网络传输的次数、 避免重复编写相同的SQL语句,并在存储过程中可以加入一些数据验证和安全性检查。 触发器是一种特殊的存储过程,它会在指定的数据库表发生数据修改操作(如INSERT、UPDATE或
DELETE)时自动执行。触发器可以用来维护数据的完整性、自动记录数据变更历史、实现复杂的业务 逻辑等。与存储过程不同的是,触发器是由数据库系统自动调用的,而不是由应用程序显式调用的。 举个例子,假设我们有一个订单表和另一个库存表,我们希望在每次插入新的订单时自动更新库存数 量。我们可以创建一个触发器,当在订单表中插入新的记录时,触发器会自动更新库存表中的相应记 录,以确保库存数量与订单数据保持一致。这样,我们就不需要在应用程序中编写额外的逻辑来处理库 存更新操作,而是由触发器自动处理。
二十、存储过程和函数的区别?
1、相同点:
两者都是为了可重复执行数据库操作而设计的。 两者在首次调用时都会被编译并缓存,之后的调用可以直接使用已编译的SQL语句,减少了网络交 互和流量。
2、不同点:
标识符:函数是“function”,而存储过程是“proceduce”。 返回值:函数必须有返回值,而存储过程没有。尽管过程不能直接返回值,但可以通过参数类型 (如in、out)来实现多参数或返回值。 调用方式:函数通常使用“select”语句调用,而存储过程使用“call”语句调用。
SQL语句的使用:除了“select…into”之外,其他“select”语句不能在函数中使用。而在存储过 程中,可以调用“select”语句。 灵活性:通过使用in、out参数,存储过程相对于函数更加灵活,可以返回多个结果。
二十一、你用的 Mysql 是哪个引擎,各引擎之间有什么区别?
主要 MyISAM 与 InnoDB 两个引擎。它们的区别主要如下:
1. 事务支持:InnoDB 支持ACID事务,而MyISAM不支持。这意味着InnoDB可以提供更高级的事务处 理功能,如事务的回滚、隔离级别等。
2. 锁定机制:InnoDB使用行级锁定,而MyISAM使用表级锁定。这会影响并发操作的性能和数据完整 性。
3. 外键支持:InnoDB支持外键约束,这有助于维护数据库的引用完整性。而MyISAM不支持外键,需 要其他方式来维护数据完整性。
4. 崩溃恢复:InnoDB有一个日志文件,可以用来在数据库崩溃后恢复数据。而MyISAM在崩溃后可能 会导致数据损坏。
5. 全文搜索:虽然InnoDB不支持FULLTEXT类型的索引,但可以使用其他方法来实现全文搜索,例如 使用专门的搜索引擎或第三方工具。
6. 索引类型和优化:InnoDB和MyISAM在索引实现上有一些差异,如B-tree索引、聚簇索引和非聚 簇索引等。这些差异会影响查询性能和数据存储。
7. 扩展性和复制:InnoDB支持表空间、分区等高级功能,并且可以通过复制来扩展或备份数据库。 而MyISAM在某些场景下可能更适合简单的应用。
二十二、除了MyISAM 与 InnoDB两个引擎,还有别的了解吗?
| 参考回答:
不是非常的了解,目前的知识只限于MyISAM和InnoDB引擎。
但是了解MySQL中其他常见的存储引擎, 例如MEMORY、Archive、NDB等。
这些引擎各自具有不同的特点和适用场景,例如:
MEMORY引擎使用内存 存储数据,适用于临时表和缓存;
Archive引擎适用于存储归档数据;NDB引擎支持分布式存储和事务 处理等。
二十三、问题:SQL 注入是如何产生的,如何防止?
主要的原因是运维程序开发过程中不注意规范书写SQL语句和对特殊字符进行过滤,导致客户端可以通 过 POST和 GET 提交一些恶意的SQL代码语句。从而影响应用程序的行为或提取敏感信息。
SQL注入是由于程序在构建SQL查询时未正确处理用户输入导致的。当应用程序未对用户输入进行适当的 验证和转义,攻击者可以利用这一点输入恶意的SQL代码,从而影响应用程序的行为或提取敏感信息。
比如说:
1、未转义用户输入:
例如,一个简单的登录查询可能看起来像这样: 如果用户输入的用户名为 ' OR '1'='1' --,那么查询将变为:
SELECT * FROM users WHERE username = '输入的用户名' AND password = '输入的密码';
如果用户输入的用户名为 ' OR '1'='1' --,那么查询将变为:
SELECT * FROM users WHERE username = '' OR '1'='1' -- ' AND password = '输入的密码';
这会导致选择所有用户,从而绕过登录验证。
2、使用动态SQL:
使用字符串拼接来构建SQL查询,而不是使用参数化查询或预编译语句,也是导致
SQL注入的一个常见原因。例如:
query = "SELECT * FROM users WHERE username = '" + username + "' AND
password = '" + password + "';"
如果用户输入的用户名为 '; DROP TABLE users; --,那么查询将变为:
SELECT * FROM users WHERE username = ''; DROP TABLE users; -- ' AND
password = '...';
这将导致users表被删除。
3、为了防止SQL注入,可以采取以下措施:
a. 使用参数化查询或预编译语句:
这是防止SQL注入的最有效方法。参数化查询确保用户输入被当作 数据而不是SQL代码处理。例如,在Python的SQLite库中,可以这样做:
cursor.execute("SELECT * FROM users WHERE username = ? AND password = ?",
(username, password))
b. 验证和清理输入:对所有用户输入进行验证,确保它们符合预期的格式,并使用适当的函数清理或 转义用户输入。例如,在Python中,可以使用html.escape()来转义特殊字符。
c. 最小权限原则:数据库账户应具有执行所需任务所需的最小权限。例如,如果一个应用程序只需要 从数据库中读取数据,那么它不应该有写入权限。
d. 错误处理:不要在生产环境中显示详细的数据库错误信息给用户。这可以防止攻击者利用错误信息 进行进一步的攻击。
e. 更新和打补丁:保持数据库管理系统、Web服务器和应用程序框架的更新,以确保它们包含最新的 安全补丁。
f. 使用Web应用防火墙(WAF):WAF可以帮助检测和阻止SQL注入攻击。
g. 审计和监控:定期审计应用程序和数据库的安全性,并监控任何可疑活动。
h. 安全编码培训:为开发人员提供安全编码培训,确保他们了解常见的安全漏洞和如何避免它们。
二十四、MySQL 与 MongoDB 本质之间最基本的差别是什么
MySQL与MongoDB在差别在多方面,比如:数据模型、查询语言、事务处理、扩展性、索引、存储引
擎、数据一致性和应用场景等方面存在本质差别
如下:
1. 数据模型:MySQL是关系型数据库,数据以表格的形式存储,每个表都有预定义的字段和数据类
型。而MongoDB是非关系型数据库,数据以文档的形式存储,每个文档可以包含不同的字段和数据
类型。
2. 查询语言:MySQL使用结构化查询语言(SQL)进行数据操作,而MongoDB使用类似于JavaScript的语言进行查询。
3. 事务处理:MySQL支持完整的事务处理,即ACID事务(原子性、一致性、隔离性和持久性),而
MongoDB的事务支持相对较弱,更多的是面向读优化的场景。
4. 扩展性:MongoDB的设计使其更容易实现水平扩展,通过分片技术可以将数据分布到多个服务器
上。而MySQL的扩展性相对较差,通常需要借助主从复制等技术来实现。
5. 索引:MySQL的索引使用B树结构,而MongoDB支持多种索引类型,包括单字段、复合、地理空间
和文本等索引。
6. 存储引擎:MySQL支持多种存储引擎,如InnoDB、MyISAM等,每种引擎都有自己的特点和适用场
景。而MongoDB的存储引擎较为统一,不支持多种引擎。
7. 数据一致性:MongoDB默认采用最终一致性模型,而MySQL则根据存储引擎和具体配置有所不同。
8. 应用场景:MySQL广泛应用于传统的关系型数据库应用场景,如金融、电商等。而MongoDB则更多
用于文档存储、日志分析、大数据处理等场景。
二十五、 说一下 Mysql 数据库存储过程的原理?
储存过程是一个可编程的函数,它在数据库中创建并保存。它可以有 SQL 语句和一些特殊的控制结构
组成。当希望在不同的应用程序或平台上执行相同的函数,或者封装特定功能时,存储过程是非常有
用的。数据库中的存储过程可以看做是对编程中面向对象方法的模拟。它允许控制数据的访问方式。
存储过程通常有以下优点:
1、存储过程能实现较快的执行速度
2、存储过程允许标准组件是编程。
3、存储过程可以用流程控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。
4、存储过程可被作为一种安全机制来充分利用。
5、存储过程能够减少网络流量
二十六、 进行多表联查时,应该注意什么
1、多表联查的关键在于找出表与表之间的关联字段,
一般设计表的时候会根据具体业务和模块将数据拆分保存到多个表中间,
在一个表中设计字段指代另一个表的字段,从而保证数据间的关系。
2、另外多表联查要根据需要选择合适的连接查询方式,如内连接,左外连接,右外连接等
二十七、 如何对查询结果进行条件映射过滤
条件查询相当于对结果集进行的过滤筛选。
这时候我们会使用 where 字句,后面使用一个或者多个条件表达式,
多个条件表达式之间使用 and 或者 or 进行连接
1、使用 CASE 表达式和聚合函数:
SELECT
SUM(CASE WHEN condition1 THEN value ELSE 0 END) AS result1,
SUM(CASE WHEN condition2 THEN value ELSE 0 END) AS result2,
...
FROM table_name;
在这个例子中,CASE 表达式根据不同的条件将值分配到不同的结果列中。SUM 函数然后对每个结果列的值进行聚合。
2、使用 GROUP BY 和 HAVING:
SELECT
condition,
SUM(value) AS total
FROM table_name
GROUP BY condition
HAVING condition IN (condition1, condition2,...);
在这个例子中,GROUP BY 将结果按照条件分组,SUM 函数对每个组的值进行聚合。HAVING 子句用于过滤不需要的条件组。
二十八、如何使用group by 和 having
GROUP BY
和 HAVING
是 SQL 中用于聚合和过滤分组数据的关键字
1、GROUP BY聚合语句
GROUP BY 语句根据一个或多个列对结果集进行分组。
在分组的列上我们可以使用 COUNT, SUM, AVG,等函数。
GROUP BY 语句是 SQL 查询中用于汇总和分析数据的重要工具,尤其在处理大量数据时,它能够提供有用的汇总信息。
假设我们有一个名为 employees 的表,包含了员工的信息,包括他们所属的部门和工资。
我们想知道每个部门的平均工资。
SELECT department, AVG(salary) AS average_salary
FROM employees
GROUP BY department;
1)当没有使用聚合函数的时候,结果不准确
下面这种纯查询的loan_amount 不准确
2)使用聚合函数
SUM
AVG
COUNT
MAX
MIN
2、HAVING过滤语句
HAVING
是一个 SQL 关键字,用于在聚合函数应用于分组数据后,过滤分组结果。它通常与 GROUP BY
一起使用,但并不总是必须跟在 GROUP BY
后面。
1、在 HAVING 子句中,可以使用聚合函数(如 AVG、SUM、MAX、MIN 等),以及常量、列名和表达式。
2、HAVING 子句的执行顺序在 WHERE 和 GROUP BY 之后。
3、与 WHERE 子句不同,HAVING 子句可以直接引用聚合函数的结果。
总的来说,HAVING 子句的主要作用是在分组数据上执行条件过滤,通常与 GROUP BY 一起使用。
1、独立使用:不常用,可被where替代
SELECT AVG(salary) AS average_salary
FROM employees
HAVING AVG(salary) > 50000;
2、与 GROUP BY
一起使用:常用
找出平均工资超过某个值的部门
如果我们想找出平均工资超过 $50,000 的部门,我们可以使用 HAVING 子句来过滤结果。
SELECT department, AVG(salary) AS average_salary
FROM employees
GROUP BY department
HAVING AVG(salary) > 50000;
在这个例子中,HAVING 子句用于筛选出平均工资大于 $50,000 的部门。
汇总
二十九、UNION去重
UNION
是 SQL 中的一个操作符,用于将两个或多个 SELECT 语句的结果集合并成一个结果集。默认情况下,UNION
会自动去除重复的行。
请注意,使用 UNION
进行去重可能会影响查询性能,特别是当结果集很大时。UNION会对SQL结果集去重排序,增加CPU、内存等消耗
以下是一个使用 UNION
去重的简单例子:
SELECT column1, column2 FROM table1
UNION
SELECT column1, column2 FROM table2;
这将返回 table1
和 table2
中的所有不重复的行。
如果你不想去除重复的行,可以使用 UNION ALL
:
SELECT column1, column2 FROM table1
UNION ALL
SELECT column1, column2 FROM table2;
这将返回 table1
和 table2
中的所有行,包括重复的行。