目录

十、视图

1、简单视图:

2、复杂视图:

3、视图更新:

十一、函数

1、函数创建:

十二、数据库优化

1、索引优化:

2、查询优化:

3、设计优化:


十、视图

        在 MySQL 中,视图(View)是一种虚拟的表,它是基于一个或多个表的查询结果构建而成的。视图提供了一种方便和灵活的方式来处理复杂查询、控制数据访问和重用查询逻辑。

        通过使用视图,可以提高查询的效率和可维护性,并增强数据库的安全性。

        视图一方面可以帮我们使用表的一部分而不是所有的表,另一方面也可以针对不同的用户制定不同的查询视图。比如,针对一个公司的销售人员,我们只想给他看部分数据,而某些特殊的数 据,比如采购的价格,则不会提供给他。再比如,人员薪酬是个敏感的字段,那么只给某个级别以上的人员开放,其他人的查询视图中则不提供这个字段。

理解视图:

  • 视图(view)是一个虚拟表,非真实存在,其本质是根据SQL语句获取动态的数据集,并为其命名,用户使用时只需使用视图名称即可获取结果集,并可以将其当作表来使用
  • 数据库中只存放了视图的定义,而并没有存放视图中的数据(数据存放在原来的表中
  • 使用视图查询数据时,数据库会从原来的表中取出对应的数据。因此,视图中的数据是依赖于原来的表中的数据的。一旦表中的数据发生改变,显示在视图中的数据也会发生改变

视图优点:

  • 操作简单
  • 减少数据冗余
  • 数据安全
  • 适应多变的需求
  • 能够分解复杂的查询逻辑

视图分类: 简单视图 和 复杂视图

语法:

CREATE [OR REPLACE] VIEW view_name [(字段列表)]

AS

select语句 [WITH [CASCADED |LOCAL] CHECK OPTION]

select语句 :表示一个完整的查询语句,将查询记录映射到视图中

[with [cascaded | local] check option]  :可选项,表示更新视图时要保证在该视图的权限范围之内,cascaded表示级联,local表示只考虑当前视图。

1、简单视图:

        简单视图是基于单个表的查询结果构建的视图。它们通常包含简单的SELECT语句,可以直接从单个表中选择列或进行简单的列计算。简单视图的查询逻辑相对较简单,不涉及复杂的多表连接操作或子查询。

案例1:基于bemp构建视图,数据列只有idname

drop table emp;drop table dept;create table dept(id int primary key,name varchar(20));insert into dept values(1,'java'),(2,'bigdata'),(3,'web');create table emp(id int primary key,name varchar(20),salary double,dept_id int,foreign key(dept_id) references dept(id));insert into emp values(1,'lisi',3000,1),(2,'wangwu',3200,1);insert into emp(id,name,salary) values(5,'zhuqi',3500);insert into emp values(3,'zhansan',2800,1),(4,'zhaoliu',900,2);-- 新建或更新视图create or replace view v_emp(id,username)asselect id,namefrom emp;desc emp;select * from emp;-- 查看视图结构desc v_emp;select * from v_emp;

案例2:基于bemp员工表构建视图,要求有编号、名字、薪水和年薪

create view v_emp1asselect id,name,salary,salary*30from emp;

案例3:基于v_emp1构建视图,只需要名字和薪水

create view v_emp_newasselect name,salary*30 as yearSalfrom v_emp1;select * from v_emp_new;

2、复杂视图:

        复杂视图是基于多个表的连接操作、子查询或其他复杂查询逻辑构建的视图。它们可以涉及多个表之间的关联、聚合函数、子查询、条件逻辑等复杂的查询操作。

案例1:构建视图v_emp_dept,能查询员工信息及所属部门

create view v_emp_deptasselect concat(e.name,'(',d.name,')') as username,e.salary,e.dept_id,d.name dept_namefrom emp e, dept dwhere e.dept_id=d.id;select * from v_emp_dept;

查看当前数据库下的视图语法

show tables;

重命名视图

rename table old_view_name to new_view_name;

修改视图

alter view view_name

as

select查询语句

注意事项:可以使用创建视图替换

删除视图

drop view if exists view_name;

3、视图更新:

        对于简单视图,即只涉及单个表的视图,可以通过直接对底层表进行更新来间接地更新视图。例如,如果有一个视图 my_view ,它是从表 my_table 中选择的某些列,可以通过更新 my_table 来更新视图中的数据。

注意事项:对基表(数据表)进行更新改会影响视图!

案例:基于bemp构建视图,显示编号和名字,并对数据修改

create view v_bempasselect id,namefrom emp;insert into v_bemp values(6,'briup');update v_bemp set name='zhaosi' where id=4;select * from v_bemp;select * from emp;

如果是复杂视图,包含下述结构中的任何一种,那么就不能通过它去更新原来

表中数据:

  • 聚合函数(SUM(), MIN(), MAX(), COUNT()等)
  • select查询列表有数学表达式
  • DISTINCT
  • UNIONUNION ALL
  • 位于选择列表中的子查询
  • GROUP BY
  • HAVING
  • JOIN
  • 常量视图

案例展示:

执行更新操作:

十一、函数

        函数是事先经过编译并存储在数据库中的一段sql语句集合,调用函数可以简化应用开发工作,提高数据处理的效率。

1、函数创建:

mysql8 增加了一个安全选项,需要执行一下代码才能创建函数

set global log_bin_trust_function_creators=TRUE;

基本格式:

delimiter 自定义符号

create function 函数名(形参列表) returns 返回类型 -- 注意是retruns

begin

        函数体 -- 若干sql语句,但是不要直接写查询

        return val;

        end 自定义符号

delimiter ;

-- 格式说明:

delimiter 自定义符号 是为了在函数内写语句方便,制定除了;之外的符号作为函数书写结束标志,一般用$$或者//

形参列表:形参名 类型 类型为mysql支持类型

返回类型: 函数返回的数据类型,mysql支持类型即可

函数体:若干sql语句组成

return: 返回指定类型返回值

 案例1:创建无参数的函数

-- 开启函数创建set global log_bin_trust_function_creators=TRUE;-- 创建无参数的函数delimiter $$create function func01() returns intbeginreturn (select salary from s_emp order by salary desc limit 1);end $$delimiter ;-- delimiter后面必须跟空白字符, 再跟;-- 函数调用select func01();select * from s_emp where salary=func01();

案例2:创建有参数的函数

-- 创建包含参数的函数delimiter $$create function func02(eid int)returns varchar(25)beginreturn (select last_name from s_emp where id=eid);end $$delimiter ;-- 函数调用select func02(1);

设置变量

1)定义用户变量

固定格式:

-- 定义格式

set @[变量名] = ;

-- 使用格式

@[变量名]

具体案例:

set @eid=10;

select func02(@eid);

2)定义局部变量

        可以在函数内部定义局部变量。局部变量只在函数内部可见,其作用域仅限于函数内部。

        局部变量可以使用set赋值。

DECLARE variable_name datatype [DEFAULT initial_value];

-- variable_name 是变量的名称

-- datatype 是变量的数据类型

-- initial_value 是可选的初始值

具体案例:定义函数获取商品总价,传递数量和单价。

DELIMITER //CREATE FUNCTION get_total_price(num INT, price DECIMAL(10, 2))RETURNS DECIMAL(10, 2)BEGINDECLARE total DECIMAL(10, 2);SET total = num * price;RETURN total;END //DELIMITER ;select get_total_price(5,2.5);-- 删除函数drop function get_total_price;

十二、数据库优化

        数据库优化是针对关系型数据库系统的性能和效率进行改进的过程。通过优化数据库,可以提高查询速度、减少资源占用,提升系统的响应性和可扩展性。

以下是一些常见的数据库优化技术和策略:

1、索引优化:

(1)在合适的字段上创建索引

        如果不加索引的话,那么查找任何哪怕只是一条特定的数据都会进行一次全表扫描,如果一张表的数据量很大而符合条件的结果又很少,那么不加索引会引起致命的性能下降。但是也不是什么情况都非得建索引不可,比如性别可能就只有两个值,建索引不仅没什么优势,还会影响到更新速度,这被称为过度索引。

        所以要建在合适的地方,合适的对象上。经常 操作 比较 判断 的字段应该建索引。索引根据实际需要来设置,不是越多越好,索引本身也是占用内存空间的。

(2)复合索引代替单索引

        比如有一条语句是这样的: select * from users where area=’beijing’ and age=22; 如果我们是在areaage上分别创建单个索引的话,由于mysql查询每次只能使用一个索引,所以虽然这样已经相对不做索引时全表扫描提高了很多效率,但是如果在areaage两列上创建复合索引的话将带来更高的效率。如果我们创建了(area, age,salary)的复合索引,那么其实相当于创建了(area,age,salary)(area,age)(area)三个索引,这被称为最佳左前缀特性。

        因此我们在创建复合索引时应该将最常用作限制条件的列放在最左边,依次递减。

(3)使用短索引

        对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个CHAR(255)的列,如果在前10 个或20个字符内,多数值是唯一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。

2、查询优化:

(1)尽量不使用NULL

        通常,索引字段是不存在 NULL 的,所以指定 IS NULL IS NOT NULL 的话会使得索引无法使用,进而导致查询性能低下。

(2)减少子查询

        执行子查询时,会创建临时表,查询完毕后再删除它,所以子查询的速度会收到影响。

(3)减少模糊查询

        一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like "%aaa%" 不会使用索引而 like "aaa%" 可以使用索引。

(4)使用 EXISTS 代替 IN

        在大多时候,[NOT] IN [NOT] EXISTS 返回的结果是相同的。但是两者用于子查询时,EXISTS 的速度会更快一些。

-- exists使用案例-- 参考博文https://blog.csdn.net/zhangzehai2234/article/details/124652056-- exists:外表先进行循环查询,将查询结果放入exists的子查询中进行条件验证,确定外层查询数据是否保留-- 查询存在员工的部门的信息select id,namefrom s_dept as sdwhere exists (select id,last_name,dept_idfrom s_empwhere dept_id = sd.id);-- 查询已分配好部门员工的信息select id,last_name,dept_idfrom s_emp as sewhere exists(select id,namefrom s_deptwhere id = se.dept_id);

(5)避免排序

        我们在查询的时候,虽然我们没有想要进行排序,但是在数据库内部频繁地进行着暗中的排序。因此对于我们来说,了解都有哪些运算会进行排序很有必要,会进行排序的代表性的运算有下面这些

  • group by 子句
  • order by 子句
  • 聚合函数(sumcountavgmaxmin)

        在极值函数(MAX/MIN)中使用索引,使用这两个函数时都会进行排序。但是如果参数字段上建有索引,则只需要扫描索引,不需要扫描整张表。

        能写在 WHERE 子句里的条件不要写在 HAVING 子句里。

  • distinct

        为了排除重复数据,distinct 也会进行排序。如果需要对两张表的连接结果进行去重,可以考虑使用exists代替distinct,以避免排序。

  • 集合运算符(unionintersectexcept)
  • 窗口函数(rankrow_number)

(6)limit 分页机制

        300W数据,select * from tableA limit 1000000,10; 会导致mysql1000000之前的所有数据全部扫描一次,大量浪费了时间。解决办法:

  • 查询字段加索引,可以建立与主键的复合索引
  • limit最大的问题在于要扫描前面不必要的数据,所以可以先对主键的条件做设定,然后记录住主键的位置再取行。 select * from tableA where id > 1000000 order by id limit 10;

(7)增加中间表

        对于需要经常联合查询的表,可以建立中间表以提高查询效率。通过建立中间表,把需要经常联合查询的数据插入到中间表中,然后将原来的联合查询改为对中间表的查询,以此来提高查询效率。

3、设计优化:

(1)默认值设置不为空

        只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL

(2)选取最适用的字段属性

        MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快。因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可能小。

        例如,在定义邮政编码这个字段时,如果将其设置为CHAR(255),显然给数据库增加了不必要的空间,甚至使用VARCHAR这种类型也是多余的,因为CHAR(6)就可以很好的完成任务了。同样的,如果可以的话,我们应该使用MEDIUMINT而不是BIGIN来定义整型字段。

(3)读写分离

        海量数据的存储及访问,通过对数据库进行读写分离,来提升数据的处理能力,数据库的写操作都集中到一个数据库上,而一些读的操作呢,可以分解到其它数据库上。

优点:得数据库的处理压力分解到多个数据库上,从而大大提升数据处理能力

缺点:付出数据复制的成本。

(4)数据库范式化和规范化

        通过合理的范式设计,减少数据冗余和不一致性;使用适当的关系模型和数据结构,以提高查询和更新的效率。

(5)分表

        分表技术比较麻烦,要修改程序代码里的SQL语句,还要手动去创建其他表,也可以用merge存储引擎实现分表,相对简单许多。分表后,程序是对一个总表进行操作,这个总表不存放数据,只有一些分表的关系,以及更新数据的方式,总表会根据不同的查询,将压力分到不同的小表上,因此提高并发能力和磁盘I/O性能。

        分表分为垂直拆分和水平拆分:

        垂直拆分:把原来的一个很多字段的表拆分多个表,解决表的宽度问题。 你可以把不常用的字段单独放到一个表中,也可以把大字段独立放一个表中,或者把关联密切的字段放一个表中。

        水平拆分:把原来一个表拆分成多个表,每个表的结构都一样,解决单表数据量大的问题。

数据库优化是一个持续的过程,需要结合具体的应用场景和需求进行调整和改进。通过综合考虑索引、查询、范式化、缓存、分区、硬件配置等方面的优化策略,可以提升数据库系统的性能和效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/97862.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/97862.shtml
英文地址,请注明出处:http://en.pswp.cn/web/97862.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Docker和虚拟IP在一台服务器上灵活部署多个Neo4j实例

使用Docker和虚拟IP在一台服务器上灵活部署多个Neo4j实例 前言 在现代应用开发中,图数据库Neo4j因其强大的关系处理能力而备受青睐。但有时候我们需要在同一台服务器上运行多个Neo4j实例,比如用于开发测试、多租户环境或者A/B测试。传统的端口映射方式…

K8s学习笔记(一):Kubernetes架构-原理-组件

Kubernetes(简称 K8s)是一款开源的容器编排平台,核心目标是实现容器化应用的自动化部署、扩展、故障恢复和运维管理。其设计遵循 “主从架构”(Control Plane Node),组件分工明确,通过 “声明式…

ensp配置学习笔记 比赛版 vlan 静态路由 ospf bgp dhcp

学习配置VLAN 虚拟局域网,目的让两台在同一网段的设备,在交换机中访问。基础指令:sys 进入系统 sysname R1 修改交换机名字为R1 display cur 查看数据、端口等交换机信息 (在端口中,可以直接display this 可以直接看…

仓颉编程语言青少年基础教程:enum(枚举)类型和Option类型

仓颉编程语言青少年基础教程:enum(枚举)类型和Option类型enum 和 Option 各自解决一类“语义级”问题:enum 让“取值只在有限集合内”的约束从注释变成编译器强制;Option 让“值可能不存在”的语义显式化。enum类型enu…

javaEE-Spring IOCDI

目录 1、什么是Spring: 2.什么是IoC: 3. 什么是控制反转呢? 4.IoC容器具备以下优点: 5.DI是什么: 依赖注⼊方法: 三种注入方法的优缺点: Autowired注解注入存在的问题: Autowired和Resource的区别&#xff…

TensorFlow Lite 全面解析:端侧部署方案与PyTorch Mobile深度对比

1 TensorFlow Lite 基础介绍 TensorFlow Lite (TFLite) 是 Google 为移动设备(Android, iOS)、微控制器(Microcontrollers)和其他嵌入式设备(如 Raspberry Pi)开发的轻量级深度学习推理框架。它的核心目标是…

mapbox进阶,使用jsts实现平角缓冲区

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言 1.1 ☘️mapboxgl.Map 地图对象 1.2 ☘️mapboxgl.Map style属性 1.3 ☘️jsts myBufferOp 缓冲区生成对对象 …

linux装好显卡后如何检查

背景:客户通知装好了显卡,我们去机器上查看一下一. 使用到的命令 watch -n 1 nvidia-smi 可实时查看gpu的使用率nvidia-smi 之查看一次 二、查看内存和显存 内存使用命令 free -h,显存使用 nvidia-smi 这只是查看的navidia, 其他品牌的会不一样

人工智能深度学习——卷积神经网络(CNN)

一、图像卷积运算 对图像矩阵与滤波器矩阵进行对应相乘再求和运算,转化得到新的矩阵。 作用:快速定位图像中某些边缘特征 英文:convolution(CNN)池化层实现维度缩减 池化:按照一个固定规则对图像矩阵进行处…

SaaS 建站从 0 到 1 教程:Vue 动态域名 + 后端子域名管理 + Nginx 配置

SaaS 建站从 0 到 1 教程:Vue 动态域名 后端子域名管理 Nginx 配置 一、什么是 SaaS 建站? SaaS(Software as a Service)建站,就是通过一套统一的系统,支持用户在线注册、绑定域名、快速生成专属网站。…

关于神经网络中回归的概念

神经网络中的回归详解 引言 神经网络(NeuralNetworks)是一种强大的机器学习模型,可用于分类和回归任务。本文聚焦于神经网络中的回归(Regression),即预测连续输出值(如房价、温度)。…

JAVASCRIPT 前端数据库-V9--仙盟数据库架构-—仙盟创梦IDE

老版本 在v1 版本中我们讲述了 基础版的应用JAVASCRIPT 前端数据库-V1--仙盟数据库架构-—-—仙盟创梦IDE-CSDN博客接下载我们做一个更复杂的的其他场景由于,V1查询字段必须 id接下来我们修改了了代码JAVASCRIPT 前端数据库-V2--仙盟数据库架构-—-—仙盟创梦IDE-CS…

k8s核心资料基本操作

NamespaceNamespace是kubernetes系统中的一种非常重要资源,它的主要作用是用来实现多套环境的资源隔离或者多租户的资源隔离。默认情况下,kubernetes集群中的所有的Pod都是可以相互访问的。但是在实际中,可能不想让两个Pod之间进行互相的访问…

PostgreSQL——分区表

分区表一、分区表的意义二、传统分区表2.1、继承表2.2、创建分区表2.3、使用分区表2.4、查询父表还是子表2.5、constraint_exclusion参数2.6、添加分区2.7、删除分区2.8、分区表相关查询2.9、传统分区表注意事项三、内置分区表3.1、创建分区表3.2、使用分区表3.3、内置分区表原…

Linux任务调度全攻略

Linux下的任务调度分为两类,系统任务调度和用户任务调度。系统任务调度:系统周期性所要执行的工作,比如写缓存数据到硬盘、日志清理等。在/etc目录下有一个crontab文件,这个就是系统任务调度的配置文件。/etc/crontab文件包括下面…

回溯算法通关秘籍:像打怪一样刷题

🚀 回溯算法通关秘籍:像打怪一样刷题! 各位同学,今天咱们聊聊 回溯算法(Backtracking)。它听起来玄乎,但其实就是 “暴力搜索 剪枝” 的优雅版。 打个比方:回溯就是在迷宫里探险&am…

嵌入式Linux常用命令

📟 核心文件与目录操作pwd-> 功能: 打印当前工作目录的绝对路径。-> 示例: pwd -> 输出 /home/user/projectls [选项] [目录]-> 功能: 列出目录内容。-> 常用选项:-l: 长格式显示(详细信息)-a: 显示所有文件(包括隐…

深入理解 Linux 内核进程管理

在 Linux 系统中,进程是资源分配和调度的基本单位,内核对进程的高效管理直接决定了系统的性能与稳定性。本文将从进程描述符的结构入手,逐步剖析进程的创建、线程实现与进程终结的完整生命周期,带您深入理解 Linux 内核的进程管理…

ACP(三):让大模型能够回答私域知识问题

让大模型能够回答私域知识问题 未经过特定训练答疑机器人,是无法准确回答“我们公司项目管理用什么工具”这类内部问题。根本原因在于,大模型的知识来源于其训练数据,这些数据通常是公开的互联网信息,不包含任何特定公司的内部文档…

使用Xterminal连接Linux服务器

使用Xterminal连接Linux服务器(VMware虚拟机)的步骤如下,前提是虚拟机已获取IP(如 192.168.31.105)且网络互通: 一、准备工作(服务器端确认)确保SSH服务已安装并启动 Linux服务器需要…