搭建私有仓库Nexus的流程以及npm包的开发和发布

news2024/12/28 23:58:13

搭建私有仓库 Nexus 的流程(Ubuntu)以及 npm 包的开发和发布

本文档是关于在 Ubuntu 上面搭建 Nexus,以及制作 npm 包并发布到 Nexus 的流程说明。

关于 Ubuntu

Ubuntu 是一个基于 Linux 的操作系统,通常会用在服务器或者嵌入式设备。当然也有桌面端版本(Ubuntu Desktop),带界面的,用于个人 PC 使用。如果你的电脑操作系统是 Ubuntu(或者其他 Linux 操作系统),你可以直接在电脑上进行该文档的流程。如果是 Windows 或者 Mac,建议使用虚拟机软件(VirtualBox, VM Ware等, 当然使用 Windows 操作系统部署 Nexus 也是可以的,但是一般人不会这样干,毕竟谁的服务器用 Windows)。

安装 Ubuntu 虚拟机

安装 Ubuntu 虚拟机的流程很简单,这里以 VirtualBox 为例,直接去官网下载安装包并安装,然后直接安装。然后再去Ubuntu官网下载 Ubuntu镜像,然后再 VirtualBox 里面建一个虚拟机实例,运行并安装系统即可。这里就不具体阐述步骤了。

关于 Nexus

因为我看公司运维给到我们的制品仓库使用的是 Nexus,因此我这边也是去大概了解了下。这是我查到的一些介绍:

这是由Sonatype公司开发的一款强大的仓库管理器,用于组织内部的依赖关系和工件(如Maven、npm、NuGet、Docker等)存储。
它简化了软件开发中的依赖管理,提供了组件的存储、版本控制、以及安全分发等功能,是持续集成和持续部署(CI/CD)流程中常用的工具。

Nexus 开源版具有以下优点:

  • 占用内存小(28 M 左右)
  • 具有基于 ExtJs 得操作界面,用户体验较好
  • 使用基于 Restlet 的完全 REST API
  • 支持代理仓库、宿主仓库和仓库组
  • 基于文件系统,不需要依赖数据库
  • 支持仓库管理
  • 支持构件搜索
  • 支持在界面上上传构件

下载安装包

直接去官网下载安装包,这里注意选择版本,因为我们使用 Ubuntu 安装,因此选择第三个。
在这里插入图片描述

安装 Java 运行环境

Nexus需要Java环境来运行,需要我们的系统中安装了 Java 运行环境 JDK,可以通过以下命令安装 OpenJDK

sudo apt install openjdk-8-jdk-headless

按照提示安装完成后使用 version 命令验证安装是否成功

java -version

注意这里的命令是一个 - 而不是两个,安装成功的话会看到:

tribiani@tribiani-VirtualBox:/web$ java -version
openjdk version "1.8.0_402"
OpenJDK Runtime Environment (build 1.8.0_402-8u402-ga-2ubuntu1~20.04-b06)
OpenJDK 64-Bit Server VM (build 25.402-b06, mixed mode)
tribiani@tribiani-VirtualBox:/web$

安装 Nexus

解压安装包

将我们之前下载的 Nexus 安装包解压到我们希望的安装的目录,例如我安装在 /web/servers/

sudo tar -xvzf nexus-3.43.0-01-unix.tar.gz -C /web/servers/

设置 Nexus 用户和权限

sudo useradd -r -d /web/servers/nexus-3.43.0-01/ -s /bin/false nexus
sudo chown -R nexus:nexus /web/servers/nexus-3.43.0-1/

这里需要注意这里的路径是你自己自定义的安装路径。

配置 Nexus 服务

创建Systemd服务文件,方便管理 Nexus

sudo nano /etc/systemd/systemd/system/nexus.service

当然如果你习惯使用 vim 的话也可以使用 vim 来编辑。
注:这里可能会遇到没有权限创建文件或者编辑文件的问题,大家自行百度解决办法。实在不行先用 touch 命令创建这个文件,再使用 vim 命令编辑。

创建这个文件后写入以下配置:

[Unit]
Description=Nexus Repository Manager
After=network.target

[Service]
User=nexus
Group=nexus
ExecStart=/web/servers/nexus-3.68.0-04/bin/nexus start
ExecStop=/web/servers/nexus-3.68.0-04/bin/nexus stop
Restart=always
RestartSec=10

[Install]

注意:这里的路径是你自己自定义的安装路径。
编辑后保存并退出编辑,然后分别执行以下命令来配置和启动 Nexus

sudo systemctl daemon-reload
sudo systemctl enable nexus
sudo systemctl start nexus

遇到的坑

上面操作完成后就可以访问 http://localhost:8081 来看一下是否启动完成了。 这里如果不出意外,Nexus 是无法正常启动的,实际上是报错了,但是 start 命令不会输出报错日志,这里我们就可以进入安装目录并使用 status 命令查看 Nexus的状态:

cd /web/servers/nexus-3.68.0-04/bin/
./nexus status

如果正常运行着会看到:

nexus is running

否则就代表没有启动成功,前面说了使用 start 命令没有日志输出,因此我们可以使用 run 命令来启动(run 命令只是在当前终端启动,终端关闭服务也会关闭):
这里可能会输出日志告诉我们 java 在读取某些文件报没权限了,因此我们需要给这些文件配置访问权限,我的做法比较暴力,直接给出问题的根目录递归给到所有的权限:

sudo chmod -R 777 xxxxx

完成后再执行 run 命令,应该是可以正常启动了(测试用 run,真正运行用 start)。访问http://localhost:8081应该就可以看到对应的界面了。

登录以及配置权限

启动完成后就可以通过 web 界面访问,点击登录输入用户名和密码登录,Nexus 会默认创建用户名为 admin的用户,随便输入一个密码,界面会提示你默认的密码在哪里,然后按照提示在对应的文件里面去找到即可,建议登录后更改密码。

配置权限

admin用户是默认的超级管理员用户,我们可以在设置界面创建用户:
在这里插入图片描述

创建用户后可以给用户分配权限角色等。
踩坑记录:
本以为我创建了用户给了对应的角色和权限就可以发布包了,但是一直被一个报错困扰:
在这里插入图片描述

整了半天才知道需要配置这块儿(最开始问运维运维也没弄好,因此我才开始本地搭建 Nexus 的):
在这里插入图片描述
弄好了后发包终于成功了。访问 web 界面也能正常看到该包了:

在这里插入图片描述

使用命令行登录也是正常的了:
在这里插入图片描述

注:这里可能会出现用户名和密码都正确但是登录还是失败的情况,使用以下命令

npm config ls

找到 User config from xxxxx/.npmrc 这个路径对应的文件,删除文件内容再登录即可(具体原因未知)。

创建 npm 仓库

Nexus默认没有创建 npm 仓库,因此我们第一步需要先创建 npm 仓库:
在这里插入图片描述

至此,Nexus 的安装就完成了。接下来介绍怎么封装自己的工具库或者组件库并且发布到npm仓库。

自己封装 vue3+ts 组件库并且发布到 NPM

创建项目

pnpm create vite

如果我们将文档和组件库放到一个项目中,我们还可以引入 vitepress:

pnpm add -D vitepress
pnpm vitepress init

按照提示完成即可。这里关于 vitepress 有关的就不多讲了。因为我们目前是有用它搭建的文档的,因此这里不需要(但是从技术的角度讲,这些都是可以整合到这一个项目的)。

配置 package.json

按照提示创建好项目,然后再 package.json 中进行如下配置:

{
  "name": "@gl/main",
  "private": false,
  "version": "0.0.01",
  "type": "module",
  "repository": {},
  "types": "dist/lib/main.d.ts",
  "module": "dist/main.es.js",
  "files": ["dist"],
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc && vite build",
    "pub": "vue-tsc && vite build && npm publish",
    "preview": "vite preview",
    "docs:dev": "vitepress dev docs",
    "docs:build": "vitepress build docs",
    "docs:preview": "vitepress preview docs"
  },
  "dependencies": {
    "ant-design-vue": "^4.2.1",
    "vue": "^3.4.21"
  },
  "devDependencies": {
    "@types/node": "^20.12.10",
    "@vitejs/plugin-vue": "^5.0.4",
    "sass": "^1.77.1",
    "typescript": "^5.2.2",
    "vite": "^5.2.0",
    "vite-plugin-dts": "^3.9.1",
    "vitepress": "^1.1.4",
    "vue-tsc": "^2.0.6"
  }
}

配置解读:

属性配置
name包名称string
private是否私有boolean
types声明文件路径path
module模块path
files包含的文件路径dirs

如果我们是自己发布一些开源的包到开源的仓库,我们通常还会配置 author,keywords,homepage 等字段

配置 vite.config.ts

配置路径别名

为了方便开发的时候引入模块,优化开发体验,我们可以配置路径别名
// vite.config.ts

  resolve: {
    alias: {
      "@lib":resolve(__dirname, "./lib"),
      "@":resolve(__dirname, "./src"),
      "@libComponents":resolve(__dirname, "./lib/components"),
      "@components":resolve(__dirname, "./src/components"),
    }
  },

配置别名后 tsconfig.json 也需要做对应的配置:
// tsconfig.json

"compilerOptions": {
    .................
    "paths": {
      "@lib/*": ["lib/*"],
      "@/*":["./src/*"],
      "@libComponents/*":["./lib/components/*"],
      "@components/*":["./src/components/*"]
    }
  },
配置库模式

这里需要配置库模式

 build: {
    lib: {
      // vite默认会打es和umd两种包,但是我们web开发只需要es模块的内容
       formats:['es'],
      // Could also be a dictionary or array of multiple entry points
      entry: resolve(__dirname, 'lib/main.ts'),
      name: 'MyLib',
      // the proper extensions will be added
      // fileName: 'my-lib',
      fileName(format, entryName) {
        return `${entryName}.${format}.js`
      },
    },
    rollupOptions: {
      // 确保外部化处理那些你不想打包进库的依赖
      external: ["vue", 'ant-design-vue'],
      output: {
        // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
        globals: {
          vue: 'Vue',
        },
      },
    },

注:建议将 external 里面包含的依赖,在安装的时候就安装到 packages.json 里面的 peerDependencies。

使用 vite-plugin-dts 生成对应的声明文件
import dts from "vite-plugin-dts";
export default defineConfig({
  ///
  plugins: [vue(), dts()],
  ///
});
编写组件

我们简单的封装一个自己的组件和对应的一些方法,我的做法是直接在项目的根目录下面创建 lib 目录,然后创建以下文件和目录:

|-lib
|----components
|----|----HButton.vue
|----|----HClone.vue
|----|----index.ts
|----|----main.css
|----tools
|----|----deepClone.ts
|----|----index.ts
|----|----shallowClone.ts
|----main.ts

我们可以在 HButton 组件里面简单的写一下组件:

<script lang="ts" setup>
  import { CSSProperties, computed } from "vue";

  const props = defineProps<{ backgroundColor?: string; color?: string }>();

  const styleObj = computed<CSSProperties>(() => {
    return {
      backgroundColor: props.backgroundColor || "#3f51b5",
      color: props.color,
    };
  });
</script>

<template>
  <button class="h-button" :style="styleObj">
    <slot>this is default button</slot>
  </button>
</template>

<style lang="css" scoped></style>

以及编写 css 文件

.h-button {
  border-radius: 8px;
  border: 1px solid transparent;
  padding: 0.6em 1.2em;
  font-size: 1em;
  font-weight: 500;
  font-family: inherit;
  background-color: #1a1a1a;
  cursor: pointer;
  transition: border-color 0.25s;
}

然后在 index.ts 里面暴露出去

import "./main.css";
export { default as HButton } from "./HButton.vue";
export { default as HClone } from "./HCloneTest.vue";
打包和发布

使用命令直接打包,然后打包的文件会存放在 dist 目录,由于我们已经在 package.json 里面配置了 files 属性只想了 dist 目录,因此我么只需要使用 npm login 登陆到 npm 然后使用 npm publish 命令直接发布包到 npm 即可。
建议我们以这种 @gl/xxx 格式命名我们的仓库,方便后面如果我们有其他的 npm 包发布到仓库的话,我们在配置.npmrc不用重复配置:

@gl:registry=http://192.168.8.149:8081/repository/npm-release/

问题记录

组件国际化

我们的项目是需要国际化双语支持的,假如我们封装的组件有内置的文字,那么也是需要国际化的,但是我们在项目中每个调用组件的地方都去设置国际化的配置显然不合理,因此借用 ant-design-vue的设计,我们可以在我们的组件库暴露一个 ConfigProvider 组件,组件的内容如下:

<template>
  <slot />
</template>

<script setup lang="ts">
  import { ConfigProviderProps, Languages } from "@lib/models";
  import { BASE_PROVIDER_INJECTION_KEY } from "@lib/models/constants";
  import { provide } from "vue";
  const props = withDefaults(defineProps<ConfigProviderProps>(), {
    locale: Languages.EN,
  });

  // export const BASE_PROVIDER_INJECTION_KEY = Symbol() as InjectionKey<ConfigProviderProps>;

  provide(BASE_PROVIDER_INJECTION_KEY, props);
</script>

<style lang="scss" scoped></style>

这是 ConfigProviderProps的定义:

export interface ConfigProviderProps {
  locale: Languages;
}

然后我们封装的组件就可以通过 inject 获取到对应的语言配置,这里我们还可以进一步封装 hook

/
export const BASE_PROVIDER_INJECTION_KEY =
  Symbol() as InjectionKey<ConfigProviderProps>;

/
import { BASE_PROVIDER_INJECTION_KEY } from "@lib/models/constants";
import { inject } from "vue";
import zh from "@lib/locale/zh";
import en from "@lib/locale/en";
import { ConfigProviderProps, Languages } from "@lib/models";

const localeMap = new Map([
  [Languages.EN, en],
  [Languages.ZH, zh],
]);

export default function useGlobalConfigInject() {
  const config = inject<ConfigProviderProps>(BASE_PROVIDER_INJECTION_KEY);

  const t = (key: keyof typeof zh) => {
    return localeMap.get(config.locale)[key];
  };

  return { config, t };
}

这个 hook 会帮我们返回所有的全局配置以及一个翻译函数 t,我们在封装组件的时候就可以使用这个 t 方法去做国际化:

<!--
 * @Description: 公共的抽屉组件
 * @Author: shufei.han
 * @LastEditors: shufei.han
 * @Date: 2024-04-11 09:38:44
 * @LastEditTime: 2024-05-11 10:08:52
-->
<template>
  <Drawer> ................................... </Drawer>
</template>

<script setup lang="ts">
  import useGlobalConfigInject from '@lib/hooks/useGlobalConfig';
  // const { t } = i18n.global
  const {t} = useGlobalConfigInject()
  ...................................
  // 底部按钮有关的配置
  const footerBtnConfig = computed(() => {
     return {
        ok: { show: props.showOkButton, text: props.okText || t('confirm') },
          cancel: { show: props.showCancelButton, text: props.cancelText || t('cancel') 		},
      }
  })
  ...................................
</script>

ConfigProvider 组件作为我们组件库的根组件,使用我们组件库的时候,如果需要配置国际化就需要再根组件(App.vue)里面使用该组件(类似于 ant-design-vue)。传入 locale 这个属性即可:

<script setup lang="ts">
  import { RouterView } from "vue-router";
  import { Languages } from "@gl/main";
  import { ref } from "vue";

  const locale = ref(Languages.EN);

  const changeLocale = () => {
    if (locale.value === Languages.EN) {
      locale.value = Languages.ZH;
      return;
    }
    locale.value = Languages.EN;
  };
</script>

<template>
  <ConfigProvider :locale="locale">
    <RouterView />
  </ConfigProvider>
</template>
怎么从一个 TS 文件到处其他的 TS 文件
export * from "./tools";
export * from "./components";
export * from "./deepClone";
export { default as shallowClone } from "./shallowClone";
怎么从一个 TS 文件导出多个 vue 组件
export { default as HButton } from "./HButton.vue";
export { default as HClone } from "./HCloneTest.vue";
将公共样式写在 vue 组件里面导致其他项目引入该组件的时候样式不生效

因为我们如果直接在 vue 组件的 style 标签里面写的样式,这些 css 代码是会被 vue 打包的,最终会变成类名假属性的选择器,因此不生效,解决方案就是用单独的 css 文件去写,然后其他项目在用的时候直接引入这个 css 文件即可。

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

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

相关文章

Git团队协作机制

Git 团队协作机制 1.团队内协作 小故事&#xff1a;岳不群手里有华山剑法但是不完整&#xff0c;需要弟子令狐冲进行完善&#xff0c;岳不群将华山剑法推送&#xff08;push&#xff09;到代码托管中心&#xff0c;这样岳不群就有属于自己的远程库&#xff0c;令狐冲从远程库…

(文章复现)基于变异粒子群算法的主动配电网故障恢复策略

参考文献&#xff1a; [1]徐岩,张荟,孙易洲.基于变异粒子群算法的主动配电网故障恢复策略[J].电力自动化设备,2021,41(12):45-53.DOI:10.16081/j.epae.202108030. 1.基本原理 为提高主动配电网故障恢复的快速性和可靠性&#xff0c;提出一种基于变异粒子群算法的恢复策略。光…

六级翻译笔记

理解加表达 除了专有名词不能自己理解翻译&#xff0c;其它都可以 时态一般唯一 题目里出现有翻译为 客观存在&#xff1a; there be 单词结尾加er和ee的区别&#xff1a;er是主动&#xff0c;ee是被动 中文句子没有被动&#xff0c;也可以英文翻译为被动 中文的状语可以不是…

3月笔记本电脑行业线上市场销售数据分析

笔记本电脑市场在过去几年中经历了起伏&#xff0c;但总体上呈现出稳定增长的态势。特别是随着远程办公、在线学习等需求的增加&#xff0c;以及消费者对于便携性、高性能等方面的追求&#xff0c;笔记本电脑市场得到了进一步的发展。 据鲸参谋数据统计&#xff0c;线上平台&a…

在Tiled中制作动画瓦片图

什么是瓦片图&#xff1f;瓦片图是指用图块把游戏场景评出来 工具安装链接&#xff1a;Tiled | Flexible level editor 资源下载教程 资源下载&#xff1a;Mystic Woods - 16x16 Pixel Art Asset Pack by Game Endeavor 解压后得到一些资源 新建图块集合 Tiled的安装就不介绍…

2024最新从0部署Django项目(nginx+uwsgi+mysql)

云服务器 我这里用的是腾讯云免费试用的2H4Gcentos服务器&#xff08;后升级为2H8G&#xff0c;保险一点提高内存&#xff09; 因为网上很多关于django部属的教程都是宝塔啊&#xff0c;python版本控制器啊这种的&#xff0c;我也误打误撞安装了宝塔面板&#xff0c;但这里我…

AR人像滤镜SDK解决方案,专业调色,打造个性化风格

视觉内容已成为企业传达品牌价值和吸引用户眼球的重要载体&#xff0c;为满足企业对于高质量、多样化视觉内容的迫切需求&#xff0c;美摄科技凭借先进的AR技术和深厚的图像处理经验&#xff0c;推出了业界领先的AR人像滤镜SDK解决方案。 一、一站式解决方案&#xff0c;覆盖多…

C++语法|智能指针的实现及智能指针的浅拷贝问题、auto_ptr、scoped_ptr、unique_ptr、shared_ptr和weak_ptr详细解读

文章目录 1.自己实现智能指针智能指针引起的浅拷贝问题尝试定义自己的拷贝构造函数解决浅拷贝 2.不带引用计数的智能指针auto_ptrscoped_ptrunique_ptr&#xff08;推荐&#xff09; 3.带引用计数的智能指针模拟实现引用计数shared_ptr和weak_ptr循环引用&#xff08;交叉引用&…

Maven 的仓库、周期和插件

优质博文&#xff1a;IT-BLOG-CN 一、Maven 仓库 在Maven的世界中&#xff0c;任何一个依赖、插件或者项目构建的输出&#xff0c;都可以称为构建。Maven在某个统一的位置存储所有项目的共享的构建&#xff0c;这个统一的位置&#xff0c;我们就称之为仓库。任何的构建都有唯一…

信息系统架构模型_2.面向服务架构(SOA)模式

前面讲的客户机/服务器模式&#xff0c;无论多少层的C/S软件结构&#xff0c;对外来讲&#xff0c;都只是一个单结点应用&#xff08;无论它由多个不同层的“服务”相互配合来完成其功能&#xff09;&#xff0c;具体表现为一个门户网站、一个应用系统等。而多个单点应用相互通…

蓝桥杯单片机之模块代码《多样点灯方式》

过往历程 历程1&#xff1a;秒表 历程2&#xff1a;按键显示时钟 历程3&#xff1a;列矩阵按键显示时钟 历程4&#xff1a;行矩阵按键显示时钟 历程5&#xff1a;新DS1302 历程6&#xff1a;小数点精确后两位ds18b20 历程7&#xff1a;35定时器测量频率 历程8&#xff…

docker部署minio和业务服务因变更minio密码导致访问不到图片的问题

问题起因 业务application和minio都是docker部署。按部署规则minio的环境变量中设置了MINIO_ROOT_USER和MINIO_ROOT_PASSWORD。这样就可以用这套用户名密码登录minio了。而我的application中是通过api访问minio获取资源URL&#xff0c;提供给前端的。所以在application的环境变…

SVN 合并到 Git 时有文件大于 100 M 被限制 Push

如果有文件大小大于 100M&#xff0c;GitHub 是会被限制推送到仓库中的&#xff0c;大概率情况会显示下面的错误&#xff1a; remote: Resolving deltas: 100% (3601/3601), done. remote: error: Trace: aea1f450da6f2ef7bfce457c715d0fbb9b0f6d428fdca80233aff34b601ff59b re…

【知识碎片】2024_05_11

本篇记录了两个代码&#xff0c;【图片整理】是一个数组排序题&#xff0c;【寻找数组的中心下标】看起来很适合用双指针&#xff0c;但是细节多&#xff0c;最后还是没通过全部用例&#xff0c;看了题解写出来的。 C语言部分是两个知道错了之后恍然大悟的选择题。 每日代码 图…

iOS Xcode Debug View Hierarchy 查看视图层级结构

前言 我们难免会遇到接手别人项目的情况&#xff0c;让你去改他遗留的问题&#xff0c;想想都头大&#xff0c;&#x1f602;可是也不得不面对。作为开发者只要让我们找到出问题的代码文件&#xff0c;我们就总有办法去解决它&#xff0c;那么如何快速定位问题对应的代码文件呢…

原创未发表!24年新算法SBOA优化TVFEMD实现分解+四种熵值+频谱图+参数变化图+相关系数图!

声明&#xff1a;文章是从本人公众号中复制而来&#xff0c;因此&#xff0c;想最新最快了解各类智能优化算法及其改进的朋友&#xff0c;可关注我的公众号&#xff1a;强盛机器学习&#xff0c;不定期会有很多免费代码分享~ 目录 数据介绍 优化流程 创新点 使用TVFEMD的创…

哪里有高清视频素材库?哪里有视频素材免费提供?

随着数字媒体和内容创作的不断演进&#xff0c;高效且创意的视频素材变得日益重要。以下列举的视频素材网站&#xff0c;无论是国内还是国际&#xff0c;都能为您的项目提供宝贵的资源。 1. 蛙学府 不断扩展其视频库&#xff0c;提供从经典剪辑到现代影视制作所需的素材。除了…

01、什么是ip、协议、端口号知道吗?计算机网络通信的组成是什么?

声明&#xff1a;本教程不收取任何费用&#xff0c;欢迎转载&#xff0c;尊重作者劳动成果&#xff0c;不得用于商业用途&#xff0c;侵权必究&#xff01;&#xff01;&#xff01; 目录 前言 计算机网络 网络ip地址 网络协议 网络端口号 前言 最近有个项目要用到相关文章…

【回溯 网格 状态压缩】52. N 皇后 II

本文涉及知识点 回溯 网格 状态压缩 LeetCode52. N 皇后 II n 皇后问题 研究的是如何将 n 个皇后放置在 n n 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回 n 皇后问题 不同的解决方案的数量。 示例 1&#xff1a; 输入&#x…

Mysql数据库的基础学习

为什么使用数据库&#xff1f; 1.持久化&#xff1a;将数据保存到可掉电式存储设备中以供使用。 数据库相关概念&#xff1a; DB:数据库&#xff08;Databass&#xff09;即存储数据的仓库&#xff0c;本质是一个文件系统&#xff0c;保存了一系列有组织的数据DBMS:数据库管…