RabbitMQ使用

目录

初识MQ

同步通讯和异步通讯​编辑

同步通讯

同步调用存在的问题

总结

同步调用优点:

同步调用的问题:

异步通讯

事件驱动优势

总结

什么是MQ

RabbitMQ快速入门

RabbitMQ概述和安装

RabbitMQ结构和概念​编辑

总结

常见消息模型

不同消息模型

HelloWorld案例

案例:完成官方Demo中Hello world案例

总结

SpringAMQP

什么是AMQP

什么是SprngAMQP

Basic Queue 简单队列模型

案例:利用SpringAMQP实现Helloworld中的基础消息队列功能

发送消息

总结

接收消息

总结

Work Queue 工作队列模型​编辑

案例:模拟Work Queue,实现一个队列绑定多个消费者

总结

发布,订阅模型-Fanout​编辑

案例:利用SpringAMQP演示FanoutExchange的使用

总结

发布,订阅模型-Direct

案例:利用SpringAMQP演示DirectExchange的使用

总结

发布,订阅模型-Topic

案例:利用SpringAMQP演示TopicExchange的使用

总结

消息转换器

测试发送Object类型消息

修改序列化(推荐JSON序列化)

发送消息

接送消息

总结


初识MQ

同步通讯和异步通讯

同步通讯

微服务间基于Feign的调用就属于同步方式,存在一些问题

同步调用存在的问题

  1. 耦合度高:每次加入新需求,都要修改原来的代码

  2. 性能下降:调用者需要等待服务提供者响应,如果调用链过长则响应时间等于每次调用时间之和

  3. 浪费资源:调用链中的每个服务在等待响应过程中,不能释放请求占用的资源,高并发场景下回极度浪费系统资源

  4. 级联失败:如果服务提供者出现问题,所有调用方都会跟着出问题,如同多米诺骨牌一样,迅速导致镇整个微服务群故障

总结

同步调用优点:
  1. 时效性较强,可以立即得到结果

同步调用的问题:
  1. 耦合度高

  2. 性能和吞吐能力下降

  3. 有额外的资源消耗

  4. 有级联失败问题

异步通讯

异步调用常见实现就是事件驱动模式

事件驱动优势

优势一:服务解耦

优势二:新能提示,吞吐量提高

优势三:服务没有强依赖,不担心级联失败问题

优势四:流浪削峰

总结

异步通信的优点:

  1. 耦合度低

  2. 吞吐量提示

  3. 故障隔离

  4. 流量削峰

异步通讯的缺点:

  1. 依赖于Broker的可靠性,安全性,吞吐能力

  2. 架构复杂了,业务没有明显的流程线,不好追踪管理

什么是MQ

MQ(MessageQueue),中文解释是消息队列,字面来看就是存放消息的队列,也就是时间驱动架构中的Broker。

RabbitMQ快速入门

RabbitMQ概述和安装

RabbitMQ是基于Erlang语言开发的开源的消息中间件,官网地址:RabbitMQ: easy to use, flexible messaging and streaming | RabbitMQ

安装RabbitMQ,参考课前资料

Docker运行RabbitMQ:

docker run \-e RABBITMQ_DEFAULT_USER=itcast \-e RABBITMQ_DEFAULT_PASS=123321 \--name mq \--hostname mq1 \-p 15672:15672 \-p 5672:5672 \-d \rabbitmq:3-management

输入端口,输入密码,进入RabbitMQ

RabbitMQ结构和概念

总结

RabbitMQ中的几个概念:

  1. channel:操作MQ的工具

  2. exchange:路由消息到队列中

  3. queue:缓存消息

  4. cirtual host:虚拟主机,是对queue,exchange等资源的逻辑分组

常见消息模型

MQ的官方文档中给出了5个MQ的Demo示例,对应了几种不同的用法:

  1. 基本消息队列(BasicQueue)

  2. 工作消息队列(WorkQueue)

  3. 发布订阅(Publish,Subscribe),又根据交换机类型不同分为三种:

    1. Fanout Exchange:广播

    2. Diect Exchange:路由

    3. Topic Exchange:主题

不同消息模型

HelloWorld案例

官方的HelloWorld是基于最基础的消息队列模型来实现的,只包括三个角色:

  1. publisher:消息发布者,将消息发送到队列queue

  2. queue:消息队列,负责接收并缓存消息

  3. consumer:订阅列队,处理队列中的消息

案例:完成官方Demo中Hello world案例

实现步骤:

  1. 导入课前资料中的demo工程

  2. 运行publisher服务中测试类publisherTest中的测试方法testSendMessage()

  3. 查看RabbitMQ控制台的消息

  4. 启动consumer服务,查看是否能接收消息

总结

基本消息队列的消息发送流程:

  1. 创建connection

  2. 创建channel

  3. 利用channel声明队列

  4. 利用channel向队列发送消息

基本消息队列的消息接收流程:

  1. 创建connection

  2. 创建channel

  3. 利用channel声明队列

  4. 定义consumer的消费行为handleDelivery()

  5. 利用channel将消费者与队列绑定

SpringAMQP

什么是AMQP

Advanced Message Queuing Protocol,适用于在应用程序或之间传递业务消息的开放标准。该协议与语言和平台无关,更符合微服务中独立性的要求。

什么是SprngAMQP

Spring AMQP是基于AMQP协议定义的一套API规范,提供了模板来发送和接收消息。包含两部分,其中Spring-AMPQ是基础抽象,Spring-rabbit是底层的默认实现

SpringAmqp的官方地址:Spring AMQP

Basic Queue 简单队列模型

案例:利用SpringAMQP实现Helloworld中的基础消息队列功能

发送消息

流程如下:

  1. 在父工程中引入spring-adqp的依赖

    <!-- AMQP依赖,包含RabbitMQ-->
    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>

  2. 在publisher服务中利用RabbitTemplate发送消息到simple.queue这个队列

    1. 在publisher服务中编写application.yml,添加mq连接信息:

      spring:rabbitmq:host: ip #(填写自己的ip)port: 5672username: itcastpassword: 123321virtual-host: /

    2. 在publisher服务中新建一个测试类,编写测试方法:

      @RunWith(SpringRunner.class)
      @SpringBootTest
      public class SpringAmqpTest {
      ​@Autowiredprivate RabbitTemplate rabbitTemplate;
      ​@Testpublic void testSendMessage2SimpleQueue(){String queueName = "simple.queue";String message = "Hello World!spring amqp!!";rabbitTemplate.convertAndSend(queueName, message);}
      }

  3. 在consumer服务中编写消费逻辑,绑定simple.queue这个队列

 String queueName = "simple.queue";String message = "Hello World!spring amqp!!";rabbitTemplate.convertAndSend(queueName, message);
总结

什么是AMQP?

应用间消息通信的一种协议,与语言和平台无关。

SpringAMQP如何发送消息?

  1. 引入amqp的starter依赖

  2. 配置RabbitMQ地址

  3. 利用RabbitTemplate的convertAndSend方法

接收消息

在consumer中编写消费逻辑,监听simple.queue

  1. 在consumer服务中编写application.yml,添加mq连接信息:

    spring:rabbitmq:host: ipport: 5672username: itcastpassword: 123321virtual-host: /

  2. 在consumer服务中新建一个类,编写消费逻辑:

    @Component
    public class SpringRabbitListener {@RabbitListener(queues = "simple.queue")public void listenSimpleQueue(String msg){System.out.println("消费者接收到simple.queue的消息:{"+msg+"}");}
    }

总结

SpringAMQP如何接收消息?

  1. 映入amqp的starter依赖

  2. 配置RabbitMQ地址

  3. 定义类,添加@Component注解

  4. 类中声明方法,添加@RabbitListener注解,方法参数就时消息

Work Queue 工作队列模型

案例:模拟Work Queue,实现一个队列绑定多个消费者

基本思路如下:

  1. 在publisher服务中定义测试方法,每秒产生50条消息,发送到simple.queue

    @Test
    public void testSendMessage2WorkQueue() throws InterruptedException {String queueName = "simple.queue";String message = "Hello World!spring amqp!!__";for (int i = 1; i < 50; i++) {rabbitTemplate.convertAndSend(queueName, message+i);Thread.sleep(20);}
    }

  2. 在consumer服务中定义两个消息监听者,都监听simple.queue队列

    @RabbitListener(queues = "simple.queue")
    public void listenWorkQueue1(String msg) throws InterruptedException {System.out.println("消费者1接收到simple.queue的消息:{"+msg+"}"+ LocalTime.now());Thread.sleep(20);
    }
    @RabbitListener(queues = "simple.queue")
    public void listenWorkQueue2(String msg) throws InterruptedException {System.out.println("消费者2接收到simple.queue的消息:{"+msg+"}"+ LocalTime.now());Thread.sleep(50);
    }

  3. 消费者 1 每秒处理50条消息,消费者 2 每秒处理10条消息

总结

Work模型的使用:

  1. 多个消费者绑定到一个队列,同一条信息只会被一个消费者处理

  2. 通过设置prefetch来控制消费者预取的消息数量

发布,订阅模型-Fanout

发布订阅与之前案例的区别就是允许将同一消息发送给多个消费者。实现方式是加入exchange(交换机)。

案例:利用SpringAMQP演示FanoutExchange的使用

实现思路

  1. 在consumer服务中,利用代码声明队列,交换机,将两者绑定

    在consumer服务声明Exchang,Queue,Bingding

    SpringAMQP提供了交换机,队列,绑定关系的API,例如:

    @Configuration
    public class FanoutConfig {//itcast.fanout(交换机)@Beanpublic FanoutExchange fanoutExchange(){return new FanoutExchange("itcast.fanout");}//itcast.queue1(队列一)@Beanpublic Queue fanoutQueue1(){return new Queue("fanout.queue1");}//绑定队列1到交换机@Beanpublic Binding fanoutBinding1(Queue fanoutQueue1, FanoutExchange fanoutExchange){return BindingBuilder.bind(fanoutQueue1).to(fanoutExchange);}//itcast.queue2(队列二)@Beanpublic Queue fanoutQueue2(){return new Queue("fanout.queue2");}//绑定队列2到交换机@Beanpublic Binding fanoutBinding2(Queue fanoutQueue2, FanoutExchange fanoutExchange){return BindingBuilder.bind(fanoutQueue2).to(fanoutExchange);}}

  2. 在consumer服务中,编写两个消费者方法,分别监听fanout.queue1和fanout.queue2

    @RabbitListener(queues = "fanout.queue1")
    public void listenFanoutQueue1(String msg){System.out.println("消费者2接收到fanout.queue1的消息:{"+msg+"}");
    }@RabbitListener(queues = "fanout.queue2")
    public void listenFanoutQueue2(String msg){System.out.println("消费者2接收到fanout.queue2的消息:{"+msg+"}");
    }

  3. 在publisher中编写测试方法,向itcast.fanout发送消息

        @Testpublic void testSendFanoutExchange(){//交换机名称String exchangeName = "itcast.fanout";//消息String message = "hello,every one!";//发送消息,参数分别是:交换机名称,RoutingKey(暂时为空),消息rabbitTemplate.convertAndSend(exchangeName, "", message);}

总结

交换机的作用是什么?

  1. 接收publisher发送的消息

  2. 将消息按照规则路由到与之绑定的队列

  3. 不能缓存消息,路由失败,消息丢失

  4. FanoutExchange的会将消息路由到每个绑定的队列

声明队列,交换机,绑定关系的Bean是什么?

  1. Queue

  2. FanoutExchange

  3. Binding

发布,订阅模型-Direct

发布订阅-DirectExchange

Direct Exchange会将接收到的消息根据规则路由指定的Queue,因此称为路由模式(routes)。

案例:利用SpringAMQP演示DirectExchange的使用

实现思路如下:

实现思路如下:

  1. 利用@RabbitListener声明Exchange,Queue,RoutingKey

    1. 在consumer服务中,编写两个消费者方法,分别监听direct.queue1和direct.queue2

    2. 并利用@RabbitListener声明Exchange,Queue,RoutingKey

  2. 在consumer服务中,编写两个消费则方法,分别监听direct.queue1和direct.queue2

    @RabbitListener(bindings = @QueueBinding(//队列value = @Queue(name = "direct.queue1"),//交换机exchange = @Exchange(name = "itcast.direct",type = ExchangeTypes.DIRECT),//邦定机置key = {"red","blue"}
    ))
    public void listenDirectQueue1(String msg){System.out.println("消费者接收到direct.queue1的消息:{"+msg+"}");
    }@RabbitListener(bindings = @QueueBinding(//队列value = @Queue(name = "direct.queue2"),//交换机exchange = @Exchange(name = "itcast.direct",type = ExchangeTypes.DIRECT),//邦定机置key = {"red","yellow"}
    ))
    public void listenDirectQueue2(String msg){System.out.println("消费者接收到direct.queue2的消息:{"+msg+"}");
    }

  3. 在publisher中编写测试方法,向itcast.direct发送消息

    @Test
    public void testSendDirectExchange(){//交换机名称String exchangeName = "itcast.direct";//消息String message = "hello,blue one!";//发送消息,参数分别是:交换机名称,RoutingKey("red"),消息rabbitTemplate.convertAndSend(exchangeName, "red", message);
    }

总结

描述下Direct交换机与Fanout交换机的差异?

  1. Fanout交换机将消息路由给每一个与之绑定的队列

  2. Direct交换机根据RoutingKey判断路由给哪个队列

  3. 如果多个队列具有相同的RoutingKey,则与Fanout功能类似

基于@RabbitListener注解声明队列和交换机有哪些常见的注解?

  1. @Queue

  2. @Exchange

发布,订阅模型-Topic

发布订阅-TopicExchange

TopicExchange与DirectExchange类似,区别在于routingKey必须是多个单纯的列表,并且以 . 分割。

例如:

china.news:代表有中国新闻消息;

china.weather:代表中国的天气消息;

japan.news:代表日本新闻;

japan.weather:代表日本的天气消息;

案例:利用SpringAMQP演示TopicExchange的使用

实现思路如下:

  1. 利用@RabbitListener声明Exchange,Queue,RoutingKey

  2. 在consumer服务中,编写两个消费则方法,分别监听topic.queue1和topic.queue2

    @RabbitListener(bindings = @QueueBinding(value = @Queue(name = "topic.queue1"),exchange = @Exchange(name = "itcast.topic",type = ExchangeTypes.TOPIC),key = "china.#"
    ))
    public void listenTopicQueue1(String msg){System.out.println("消费者接收到topic.queue1的消息:{"+msg+"}");
    }@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "topic.queue2"),exchange = @Exchange(name = "itcast.topic",type = ExchangeTypes.TOPIC),key = "#.news"
    ))
    public void listenTopicQueue2(String msg){System.out.println("消费者接收到topic.queue2的消息:{"+msg+"}");
    }

  3. 在publisher中编写测试方法,向itcast.topic发送消息

    @Test
    public void testSendTopicExchange(){//交换机名称String exchangeName = "itcast.topic";//消息String message = "中国的新闻!";//发送消息,参数分别是:交换机名称,RoutingKey,消息rabbitTemplate.convertAndSend(exchangeName, "china.news", message);
    }

总结

描述下Direct交换机与Topic交换机的差异?

自己总结

消息转换器

测试发送Object类型消息

说明:在SpringAMQP的发送方法中,接收消息的类型是Object,也就是说我们可以发送任意对象类型的消息,SpringAMQP会帮我们序列化为字节后发送。(也就是是对象会序列化为字节)

修改序列化(推荐JSON序列化)

发送消息
  1. 我们在publisher服务引入依赖

    <!--rabbitmq使用json序列化-->
    <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId>
    </dependency>

  2. 我们在publisher服务声明MessageConverter:

    @Bean
    public MessageConverter messageConverter(){return new Jackson2JsonMessageConverter();
    }

  3. 发送消息

    @Test
    public void testSendObjectQueue(){Map<String,Object> msg = new HashMap<>();msg.put("name","留言");msg.put("age",21);rabbitTemplate.convertAndSend("object.queue",msg);
    }

接送消息
  1. 我们在consumer服务引入Jackson依赖:

    <!--rabbitmq使用json序列化-->
    <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId>
    </dependency>

  2. 我们在consumer服务定义MessageConverter:

    @Bean
    public MessageConverter messageConverter(){return new Jackson2JsonMessageConverter();
    }

  3. 然后定义一个消费者,监听object.queue队列并消费信息:

    @RabbitListener(queues = "object.queue")
    public void listenObjectQueue(Map<String,Object> msg){System.out.println("消费者接收到object.queue的消息:{"+msg+"}");
    }

总结

SpringAMQP中消息的序列化和反序列化是怎么实现的?

  1. 利用MessageConverter实现的,默认是JDK的序列化

  2. 注意发送方与接收方必须使用相同的MessageConverter

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

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

相关文章

基于springboot+vue的旅游管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

基于YOLOv5的驾驶员疲劳驾驶行为​​​​​​​检测系统

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文主要内容:详细介绍了疲劳驾驶行为检测整个过程&#xff0c;从数据集到训练模型到结果可视化分析。 博主简介 AI小怪兽&#xff0c;YOLO骨灰级玩家&#xff0c;1&#xff09;YOLOv5、v7、v8优化创新&#xff0c;轻松涨点和模型轻量…

Spring事务注解@Transactional的流程和源码分析

Spring事务简介 Spring事务有两种方式&#xff1a; 编程式事务&#xff1a;编程式事务通常使用编程式事务管理API实现&#xff0c;比如Spring提供的PlatformTransactionManager接口&#xff0c;使用它操控事务。声明式事务&#xff1a;注解式事务使用AOP&#xff08;面向切面…

通过Dockerfile创建镜像

通过Dockerfile创建镜像 Docker 提供了一种更便捷的方式&#xff0c;叫作 Dockerfile docker build命令用于根据给定的Dockerfile构建Docker镜像。 docker build语法&#xff1a; # docker build [OPTIONS] <PATH | URL | -> 1. 常用选项说明--build-arg&#xff0c;设置…

Java学习笔记------内部类

类的五大成员 属性、方法、构造方法、代码块、内部类 内部类 格式&#xff1a; public class Outer{//外部类 public class Inner{//内部类 } } public class Test{//外部其他类 public static void main(String[] args) } inner类表示的事物是Outer类的一部分&#xf…

【计算机考研】考408,还是不考408性价比高?

首先综合考虑&#xff0c;如果其他科目并不是很优秀&#xff0c;需要我们花一定的时间去复习&#xff0c;408的性价比就不高&#xff0c;各个科目的时间互相挤压&#xff0c;如果备考时间不充裕&#xff0c;考虑其他专业课也未尝不可。 复习408本来就是费力不讨好的事情 不同…

公司项目总结合分享经验

珠海督办 1.批量导入 导入excel表单给接口&#xff0c;接口返回前端想要的数据 list是代表数据的数量&#xff0c;titleMap是代表数据中会有那些字段 listl里面的字段&#xff1a; value是代表要显示的值&#xff0c;success为true代表excel表格的内容填写是正确的&#…

前端布局方式及其优缺点

前端布局方式多种多样&#xff0c;每种布局方式都有其特定的应用场景、特性和优缺点。以下是一些常见的前端布局方式及其特点和优缺点&#xff1a; 静态布局&#xff1a; 特性&#xff1a;元素的尺寸使用绝对单位&#xff08;如px&#xff09;进行定义&#xff0c;不会随浏览器…

1.5 简述转置卷积的主要思想以及应用场景

1.5 简述转置卷积的主要思想以及应用场景 普通的卷积主要思想&#xff1a; 普通的卷积操作可以形式化为一个矩阵乘法运算&#xff0c;即yAx&#xff08;1-12&#xff09; 其中&#xff0c;x和y分别是卷积的输入和输出(展平成一维向量形式)&#xff0c;维度分别为d⁽i⁾和d⁽…

Linux:kubernetes(k8s)探针ReadinessProbe的使用(9)

本章yaml文件是根据之前文章迭代修改过来的 先将之前的pod删除&#xff0c;然后使用下面这个yaml进行生成pod apiVersion: v1 # api文档版本 kind: Pod # 资源对象类型 metadata: # pod相关的元数据&#xff0c;用于描述pod的数据name: nginx-po # pod名称labels: # pod的标…

第三百八十八回

文章目录 概念介绍使用方法示例代码 我们在上一章回中介绍了DateRangePickerDialog Widget相关的内容,本章回中将介绍Radio Widget.闲话休提&#xff0c;让我们一起Talk Flutter吧。 概念介绍 我们在这里说的Radio Widget是指单选按钮&#xff0c;没有选中时是圆形边框&#x…

Vue+SpringBoot打造超市账单管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统设计3.1 总体设计3.2 前端设计3.3 后端设计在这里插入图片描述 四、系统展示五、核心代码5.1 查询供应商5.2 查询商品5.3 新增超市账单5.4 编辑超市账单5.5 查询超市账单 六、免责说明 一、摘要 1.1 项目介绍 基于…

王道机试C++第 3 章 排序与查找:排序问题 Day28(含二分查找)

查找 查找是另一类必须掌握的基础算法&#xff0c;它不仅会在机试中直接考查&#xff0c;而且是其他某些算法的基础。之所以将查找和排序放在一起讲&#xff0c;是因为二者有较强的联系。排序的重要意义之一便是帮助人们更加方便地进行查找。如果不对数据进行排序&#xff0c;…

【uni-app小程序开发】实现一个背景色渐变的滑动条slider

最近做的一个用uni-app+vue2开发的微信小程序项目中要实现一个滑动进度控制条,如下图所示: 1. 滑动条需要渐变背景色 2. 滑块的背景色需要与当前位置滑动条的背景色一致(动态改变) 碰到这样的需求,我当然先是看看官方提供的slider组件和uView里的u-slider组件能不能满足…

Javaweb之Web后端开发总结的详细解析

4. Web后端开发总结 到此基于SpringBoot进行web后端开发的相关知识我们已经学习完毕了。下面我们一起针对这段web课程做一个总结。 我们来回顾一下关于web后端开发&#xff0c;我们都学习了哪些内容&#xff0c;以及每一块知识&#xff0c;具体是属于哪个框架的。 web后端开…

nyist_acm 个人积分赛1(部分题解会补充)

Mirrored String II 看到题解说是马拉车算法&#xff0c;我赛时并没想到&#xff08;好吧其实我是比赛完才知道有马拉车这个算法&#xff09; 因为字符串的长度只有1000&#xff0c;直接暴力跑其实就可以了&#xff0c;但是要注意的是&#xff1b;回文串有俩种形式&#xff0c…

1. Gin框架入门

文章目录 一、Gin框架介绍二、RESTful API三、Gin渲染1. HTML渲染2. 自定义模板函数3. 静态文件处理4. 使用模板继承5. 补充文件路径处理6. JSON渲染7. XML渲染8. YMAL渲染9. protobuf渲染 四、Gin获取各种方式传递过来的参数1、获取querystring参数2、获取form参数3、获取path…

Vue3实现页面跳转功能

目标&#xff1a; 首页&#xff1a; 点击About后&#xff1a; 第一步&#xff1a;安装 Vue Router和创建你先 npm install vue-router4第二步&#xff1a;在router.js中设置路由 import { createRouter, createWebHistory } from vue-router; import Home from ./views/Home…

如何写一份简单的产品说明书,教程奉上

如果你是一位新晋产品经理&#xff0c;或者正在研发新产品&#xff0c;并且心中惴惴不安因为未知的产品说明书制作环节&#xff0c;那么今天你就来对地方了。本篇文章将教你如何创建一份简单明了的产品说明书。让我们开始吧&#xff01; 首先&#xff0c;明确产品说明书的目标。…

达梦数据库基础操作(二):表空间操作

达梦数据库基础操作(二)&#xff1a;表空间操作 1. 表空间操作 1.1 达梦表空间介绍 表空间的概念&#xff1a; 每个DM 数据库都是由一个或者多个表空间组成&#xff0c;表空间是一个逻辑的存储容器&#xff0c;它位于逻辑结构的顶层&#xff0c;用于存储数据库中的所有数据&am…