1. 为什么要使用数据库
2. 数据库与数据库管理系统
2.1数据库的相关概念
DB:数据库(Database) :即存储数据的“仓库”,其本质是一个文件系统。它保存了一系列有组织的数据。
DBMS:数据库管理系统(Database Management System) :是一种操纵和管理数据库的大型软件,用于建立、使用和维护数据库,对数据库进行统一管理和控制。用户通过数据库管理系统访问数据库中表内的数据。
SQL:结构化查询语言(Structured Query Language) :专门用来与数据库通信的语言。
2.2数据库与数据库系统的关系
数据库管理系统(DBMS)可以管理多个数据库,一般开发人员会针对每一个应用创建一个数据库。为保存应用中实体的数据,一般会在数据库创建多个表,以保存程序中实体用户的数据。
3.关系型数据库与非关系型数据库
3.1关系型数据库RDBMS
3.1.1实质
关系型数据库模型是把复杂的数据结构归结为简单的二元关系 (即二维表格形式)。
关系型数据库以行(row) 和列(column) 的形式存储数据,以便于用户理解。这一系列的行和列被称为表(table) ,一组表组成了一个库(database)。
表与表之间的数据记录有关系(relationship)。现实世界中的各种实体以及实体之间的各种联系均用关系模型 来表示。关系型数据库,就是建立在关系模型 基础上的数据库。
3.1.2优势
3.2非关系型数据库
3.2.1介绍
非关系型数据库可看成传统关系型数据库的功能阉割版本 ,基于键值对存储数据,不需要经过SQL层的解析,性能非常高 。同时,通过减少不常用的功能,进一步提高性能。
?
4.SQL概述
4.1SQL分类
DDL(Data Definition Languages、数据定义语言),这些语句定义了不同的数据库、表、视图、索引等数据库对象,还可以用来创建、删除、修改数据库和数据表的结构。
DML(Data Manipulation Language、数据操作语言),用于添加、删除、更新和查询数据库记录,并检查数据完整性。
DCL(Data Control Language、数据控制语言),用于定义数据库、表、字段、用户的访问权限和安全级别。
4.2基本select语句
在SELECT语句中使用关键字DISTINCT去除重复行,select distinct
查询常数:select '常数' as 字段名 from 表名
使用DESCRIBE 或 DESC 命令,表示表结构:DESCRIBE employees;或? DESC employees;
?
4.3运算符
4.3.1算术运算符
算术运算符主要用于数学运算,其可以连接运算符前后的两个数值或表达式,对数值或表达式进行加(+)、减(-)、乘(*)、除(/)和取模(%)运算。
4.3.2比较运算符
比较运算符用来对表达式左边的操作数和右边的操作数进行比较,比较的结果为真则返回1,比较的结果为假则返回0,其他情况则返回NULL。=? ?<=>? ?<> !=? ? is null? like.....
?
4.4排序和分页
4.4.1排序数据
asc升序、desc降序、order by 字段名 放在select语句的结尾
4.4.2分页
分页显示,就是将数据库中的结果集,一段一段显示出来需要的条件。
MySQL中使用 LIMIT 实现分页: limit? ?位置偏移量,条数。位置偏移量可省略,为从0开始
SELECT * FROM table
LIMIT(PageNo - 1)*PageSize,PageSize;
?
4.5多表查询
多表查询,也称为关联查询,指两个或更多个表一起完成查询操作。
前提条件:这些一起查询的表之间是有关系的(一对一、一对多),它们之间一定是有关联字段,这个关联字段可能建立了外键,也可能没有建立外键。比如:员工表和部门表,这两个表依靠“部门编号”进行关联。
4.5.1笛卡尔积(交叉连接)
笛卡尔乘积是一个数学运算。假设我有两个集合 X 和 Y,那么 X 和 Y 的笛卡尔积就是 X 和 Y 的所有可能组合,也就是第一个对象来自于 X,第二个对象来自于 Y 的所有可能。组合的个数即为两个集合中元素个数的乘积数。
#案例:查询员工的姓名及其部门名称
SELECT last_name, department_name
FROM employees, departments;
2889行
SELECT COUNT(employee_id) FROM employees;
#输出107行
SELECT COUNT(department_id)FROM departments;
#输出27行
SELECT 107*27 FROM dual;
- 为了避免笛卡尔积, 可以在 WHERE 加入有效的连接条件。
SELECT table1.column, table2.column
FROM table1, table2
WHERE table1.column1 = table2.column2; #连接条件
4.5.2多表查询的分类
一、等值连接和非等值连接
等值连接
SELECT employees.employee_id, employees.last_name,
employees.department_id, departments.department_id,
departments.location_id
FROM employees, departments
WHERE employees.department_id = departments.department_id;
非等值连接
SELECT e.last_name, e.salary, j.grade_level
FROM employees e, job_grades j
WHERE e.salary BETWEEN j.lowest_sal AND j.highest_sal;
二、自连接和非自连接
自连接
SELECT CONCAT(worker.last_name ,' works for '
, manager.last_name)
FROM employees worker, employees manager
WHERE worker.manager_id = manager.employee_id ;
查询employees表,返回“Xxx works for Xxx”
三、内连接和外连接
-
内连接: 合并具有同一列的两个以上的表的行, 结果集中不包含一个表与另一个表不匹配的行 -
外连接: 两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的行 ,这种连接称为左(或右) 外连接。没有匹配的行时, 结果表中相应的列为空(NULL)。 -
如果是左外连接,则连接条件中左边的表也称为主表 ,右边的表称为从表 。 -
果是右外连接,则连接条件中右边的表也称为主表 ,左边的表称为从表 。
#左外连接
SELECT last_name,department_name
FROM employees ,departments
WHERE employees.department_id = departments.department_id(+);
#右外连接
SELECT last_name,department_name
FROM employees ,departments
WHERE employees.department_id(+) = departments.department_id;
SELECT table1.column, table2.column,table3.column
FROM table1
JOIN table2 ON table1 和 table2 的连接条件
JOIN table3 ON table2 和 table3 的连接条件
内连接(INNER JOIN)的实现
左外连接(LEFT OUTER JOIN)
SELECT 字段列表
FROM A表 INNER JOIN B表
ON 关联条件
WHERE 等其他子句;
右外连接(RIGHT OUTER JOIN)
#实现查询结果是B
SELECT 字段列表
FROM A表 RIGHT JOIN B表
ON 关联条件
WHERE 等其他子句;
外连接(OUTER JOIN)的实现
#实现查询结果是A
SELECT 字段列表
FROM A表 LEFT JOIN B表
ON 关联条件
WHERE 等其他子句;
利用UNION关键字,可以给出多条SELECT语句,并将它们的结果组合成单个结果集。合并时,两个表对应的列数和数据类型必须相同,并且相互对应。各个SELECT语句之间使用UNION或UNION ALL关键字分隔。
SELECT column,... FROM table1
UNION [ALL]
SELECT column,... FROM table2
#中图:内连接 A∩B
SELECT employee_id,last_name,department_name
FROM employees e JOIN departments d
ON e.`department_id` = d.`department_id`;
#左上图:左外连接
SELECT employee_id,last_name,department_name
FROM employees e LEFT JOIN departments d
ON e.`department_id` = d.`department_id`;
#右上图:右外连接
SELECT employee_id,last_name,department_name
FROM employees e RIGHT JOIN departments d
ON e.`department_id` = d.`department_id`;
#左中图:A - A∩B
SELECT employee_id,last_name,department_name
FROM employees e LEFT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE d.`department_id` IS NULL
#右中图:B-A∩B
SELECT employee_id,last_name,department_name
FROM employees e RIGHT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE e.`department_id` IS NULL
#左下图:满外连接
# 左中图 + 右上图 A∪B
SELECT employee_id,last_name,department_name
FROM employees e LEFT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE d.`department_id` IS NULL
UNION ALL #没有去重操作,效率高
SELECT employee_id,last_name,department_name
FROM employees e RIGHT JOIN departments d
ON e.`department_id` = d.`department_id`;
#右下图
#左中图 + 右中图 A ∪B- A∩B 或者 (A - A∩B) ∪ (B - A∩B)
SELECT employee_id,last_name,department_name
FROM employees e LEFT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE d.`department_id` IS NULL
UNION ALL
SELECT employee_id,last_name,department_name
FROM employees e RIGHT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE e.`department_id` IS NULL
?
表连接的约束条件可以有三种方式:WHERE, ON, USING
#关联条件
#把关联条件写在where后面
SELECT last_name,department_name
FROM employees,departments
WHERE employees.department_id = departments.department_id;
#把关联条件写在on后面,只能和JOIN一起使用
SELECT last_name,department_name
FROM employees INNER JOIN departments
ON employees.department_id = departments.department_id;
SELECT last_name,department_name
FROM employees CROSS JOIN departments
ON employees.department_id = departments.department_id;
SELECT last_name,department_name
FROM employees JOIN departments
ON employees.department_id = departments.department_id;
#把关联字段写在using()中,只能和JOIN一起使用
#而且两个表中的关联字段必须名称相同,而且只能表示=
#查询员工姓名与基本工资
SELECT last_name,job_title
FROM employees INNER JOIN jobs USING(job_id);
#n张表关联,需要n-1个关联条件
#查询员工姓名,基本工资,部门名称
SELECT last_name,job_title,department_name FROM employees,departments,jobs
WHERE employees.department_id = departments.department_id
AND employees.job_id = jobs.job_id;
SELECT last_name,job_title,department_name
FROM employees INNER JOIN departments INNER JOIN jobs
ON employees.department_id = departments.department_id
AND employees.job_id = jobs.job_id;
4.6约束
约束是表级的强制规定。
可以在创建表时规定约束(通过 CREATE TABLE 语句),或者在表创建之后通过 ALTER TABLE 语句规定约束。
根据约束起的作用,约束可分为:
- NOT NULL 非空约束,规定某个字段不能为空
- UNIQUE 唯一约束,规定某个字段在整个表中是唯一的
- PRIMARY KEY 主键(非空且唯一)约束
- FOREIGN KEY 外键约束
- CHECK 检查约束
- DEFAULT 默认值约束
4.7视图
视图一方面可以帮我们使用表的一部分而不是所有的表,另一方面也可以针对不同的用户制定不同的查询视图。比如,针对一个公司的销售人员,我们只想给他看部分数据,而某些特殊的数据,比如采购的价格,则不会提供给他。再比如,人员薪酬是个敏感的字段,那么只给某个级别以上的人员开放,其他人的查询视图中则不提供这个字段。
视图的理解:
-
视图是一种虚拟表 ,本身是不具有数据 的,占用很少的内存空间,它是 SQL 中的一个重要概念。 -
视图建立在已有表的基础上, 视图赖以建立的这些表称为基表。 -
视图的创建和删除只影响视图本身,不影响对应的基表。但是当对视图中的数据进行增加、删除和修改操作时,数据表中的数据会相应地发生变化,反之亦然。 -
向视图提供数据内容的语句为 SELECT 语句, 可以将视图理解为存储起来的 SELECT 语句
-
视图,是向用户提供基表数据的另一种表现形式。通常情况下,小型项目的数据库可以不使用视图,但是在大型项目中,以及数据表比较复杂的情况下,视图的价值就凸显出来了,它可以帮助我们把经常查询的结果集放到虚拟表中,提升使用效率。理解和使用起来都非常方便。
创建视图:
CREATE [OR REPLACE]
[ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
VIEW 视图名称 [(字段列表)]
AS 查询语句
[WITH [CASCADED|LOCAL] CHECK OPTION]
查看视图
语法1:查看数据库的表对象、视图对象
SHOW TABLES;
语法2:查看视图的结构
DESC / DESCRIBE 视图名称;
语法3:查看视图的属性信息
# 查看视图信息(显示数据表的存储引擎、版本、数据行数和数据大小等)
SHOW TABLE STATUS LIKE '视图名称'
语法4:查看视图的详细定义信息
SHOW CREATE VIEW 视图名称;
MySQL支持使用INSERT、UPDATE和DELETE语句对视图中的数据进行插入、更新和删除操作。当视图中的数据发生变化时,数据表中的数据也会发生变化,反之亦然。
修改视图
方式1:使用CREATE OR REPLACE VIEW 子句修改视图
CREATE OR REPLACE VIEW empvu80
(id_number, name, sal, department_id)
AS
SELECT employee_id, first_name || ' ' || last_name, salary, department_id
FROM employees
WHERE department_id = 80;
方式2:ALTER VIEW
ALTER VIEW 视图名称
AS
查询语句
删除视图
DROP VIEW IF EXISTS 视图名称;
DROP VIEW IF EXISTS 视图名称1,视图名称2,视图名称3,...;
视图优点
**1. 操作简单**
将经常使用的查询操作定义为视图,可以使开发人员不需要关心视图对应的数据表的结构、
表与表之间的关联关系,也不需要关心数据表之间的业务逻辑和查询条件,而只需要简单
地操作视图即可,极大简化了开发人员对数据库的操作。
**2. 减少数据冗余**
视图跟实际数据表不一样,它存储的是查询语句。所以,在使用的时候,我们要通过定义
视图的查询语句来获取结果集。而视图本身不存储数据,不占用数据存储的资源,减少了数据
冗余。
**3. 数据安全**
MySQL将用户对数据的`访问限制`在某些数据的结果集上,而这些数据的结果集可以使用
视图来实现。用户不必直接查询或操作数据表。这也可以理解为视图具有`隔离性`。视图
相当于在用户和实际的数据表之间加了一层虚拟表。同时,MySQL可以根据权限将用户对数据
的访问限制在某些视图上,用户不需要查询数据表,可以直接通过视图获取数据表中的信息。
这在一定程度上保障了数据表中数据的安全性。
**4. 适应灵活多变的需求**
当业务系统的需求发生变化后,如果需要改动数据表的结构,则工作量相对较大,可以使
用视图来减少改动的工作量。这种方式在实际工作中使用得比较多。
**5. 能够分解复杂的查询逻辑**
数据库中如果存在复杂的查询逻辑,则可以将问题进行分解,创建多个视图获取数据,再将
创建的多个视图结合起来,完成复杂的查询逻辑。
视图不足
如果我们在实际数据表的基础上创建了视图,那么,如果实际数据表的结构变更了,
我们就需要及时对相关的视图进行相应的维护。特别是嵌套的视图(就是在视图的基础上创建视图)
,维护会变得比较复杂,`可读性不好`,容易变成系统的潜在隐患。因为创建视图的 SQL 查询
可能会对字段重命名,也可能包含复杂的逻辑,这些都会增加维护的成本。
实际项目中,如果视图过多,会导致数据库维护成本的问题。
|