GO语言学习(17)Gorm的数据库操作

目录

🏆前言

1.Gorm的简介

2.GORM连接数据库 

2.1 配置DSN 

Mysql,TiDB,MariaDB

PostgreSQL

SQL Server

 SQLite

2.2 gorm.Open连接数据库

3.数据库连接池的配置  

4.使用GORM对数据库进行操作(重点) 

4.1 创建数据表

4.2 CRUD操作 

GORM利用原生SQL执行

🏆前言

        通过上一篇Go语言学习(16)Gin后端框架的学习,了解了基本的Go语言如何使用Gin进行前后端数据的传输,本文将进一步学习后端,了解如何使用Gorm与Mysql数据库进行数据交互,实现基本的增删改查功能。

1.Gorm的简介

        GORM 是 Go 语言中最流行的 ORM(对象关系映射)库之一,支持主流数据库(MySQL、PostgreSQL、SQLite、SQL Server 等),提供简洁的 API 和强大的功能。其具有以下基本特点:

  • 简洁易用:通过定义结构体来映射数据库表,简化数据操作。
  • 功能全面:支持CRUD、事务、预加载、关联关系、自动迁移等常见功能。
  • 扩展性强:内置钩子函数、插件机制以及对多种数据库(MySQL、PostgreSQL、SQLite、SQL Server等)的支持。
  • 性能优秀:经过大量优化,能够在高并发场景下保持稳定性能。 

        当然Go语言当中的ORM库不止Gorm一个,以下是一些其它Go当中的ORM库的比较,可根据自身需求,进行选择学习:

技术栈性能易用性功能适用场景
Gorm优秀,适合高并发场景非常友好,API简洁明了,文档齐全功能全面,支持多种数据库,扩展性强适合各种规模的项目,尤其是需要高性能和复杂数据库操作的场景
Xorm性能优异,经过大量优化API简洁,支持链式调用支持基本的CRUD操作,查询构建器灵活适合中小型项目,特别是对性能要求较高的场景
Beego ORM性能中等与Beego框架无缝集成,使用方便功能全面,但非Beego项目中配置复杂适合使用Beego框架的Web开发项目
Go-PG针对PostgreSQL优化,性能良好API设计符合PostgreSQL习惯,但学习成本较高充分利用PostgreSQL特性,支持高级查询和事务管理适用于PostgreSQL数据库的项目
upper.io/db性能中等模块化设计,易于扩展和定制,但配置复杂支持多种数据库,模块化设计适用于需要支持多种数据库的复杂项目

🍅 GORM的官方文档连接👉:GORM官方文档 

2.GORM连接数据库 

       首先我们需要使用以下命令,安装GORM与Mysql驱动引入到本地项目当中:

go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql

        使用GORM连接数据库,大体可以分为两个步骤:

  1. 🌸配置DSN(Data Source Name,数据源名称)
  2. 🌸使用gorm.Open连接数据库

2.1 配置DSN 

         DSN(Data Source Name) 是一种用于连接数据库的字符串,它包含了连接到数据库所需的所有信息,如数据库类型、主机地址、端口号、用户名、密码、数据库名称等。DSN通常用于数据库驱动程序中,以简化数据库连接的配置。不同的数据库连接中DSN的配置也不相同。

  • Mysql,TiDB,MariaDB

dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"//填上参数后的例子
//username = root
//password = 123456
//host     = localhost
//port     = 3306
//Dbname   = gorm
root:123456@tcp(localhost:3306)/gorm?charset=utf8&parseTime=True&loc=Local

 🌹各参数含义:

  1. user:数据库用户名。
  2. password:数据库密码。
  3. 127.0.0.1:数据库服务器的IP地址。
  4. 3306:数据库服务监听的端口号。
  5. dbname:要连接的数据库名称。
  6. charset=utf8mb4:字符集设置。
  7. parseTime=True:启用时间解析。
  8. loc=Local:时区设置。

        由于TiDB,MariaDB与MySQL在功能上几乎完全兼容,因此可以按照MySQL的DSN格式来连接:,但需要注意TiDB的默认端口号为4000,而不是3306。

  • PostgreSQL

dsn := "host=localhost user=gorm dbname=gorm password=gorm port=5432 sslmode=disable"

🌹各参数含义:

  1. host:数据库服务器的主机名或IP地址。
  2. user:数据库用户名。
  3. dbname:要连接的数据库名称。
  4. password:数据库密码。
  5. port:数据库服务监听的端口号。
  6. sslmode:SSL模式,如disable、require等 
  • SQL Server

dsn := "sqlserver://username:password@localhost:1433?database=your_db"

 🌹各参数含义:

  1. username:数据库用户名。
  2. password:数据库密码。
  3. localhost:数据库服务器的主机名或IP地址。
  4. 1433:数据库服务监听的端
  5. your_db:要连接的数据库名称。
  •  SQLite

dsn := "gorm.db"

SQLite的DSN通常是一个文件路径,表示数据库文件的位置。

2.2 gorm.Open连接数据库

        配置好DSN之后,便可以使用open函数连接数据库,下面以Mysq连接为例子。

db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})if err != nil {panic("failed to connect database")}

         使用mysql.open读取dsn进行数据库连接,&gorm.Config{} 用于配置 GORM 的全局行为(可选参数),例如:Logger: 自定义日志输出;SkipDefaultTransaction: 禁用默认事务;NamingStrategy: 表名和列名命名策略,此处使用空结构体 {} 表示使用默认配置。返回的db是一个 *gorm.DB 对象,代表数据库连接池,后续所有数据库操作都基于此对象。其余数据库连接也是同理。

此外GORM 允许通过 DriverName 选项自定义 MySQL 驱动,例如: 

import (_ "example.com/my_mysql_driver""gorm.io/driver/mysql""gorm.io/gorm"
)db, err := gorm.Open(mysql.New(mysql.Config{DriverName: "my_mysql_driver",DSN: "gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True&loc=Local", // data source name, 详情参考:https://github.com/go-sql-driver/mysql#dsn-data-source-name
}), &gorm.Config{})

3.数据库连接池的配置  

        数据库连接池就像餐厅里的一群“备用服务员”。这些服务员已经站在厨房门口,随时准备接单。当顾客来点菜时,直接从这群备用服务员中挑一个,用完后服务员会回到原位,继续等待下一位顾客。这样就避免了每次都要重新找服务员(建立连接)的麻烦,效率更高。然而连接池的设置并不能过大或者或小。

连接池设置过大的影响:

  1. 资源浪费:设置过大的连接池可能导致过多的数据库连接被创建,占用过多的系统资源(如内存和CPU),从而导致资源浪费。
  2. 性能下降:过多的连接可能导致数据库服务器负载过高,影响整体应用程序性能,甚至可能导致系统崩溃。
  3. 资源碎片化:过多的连接可能导致系统资源碎片化,降低系统的稳定性和响应速度。

连接池设置过小的影响:

  1. 连接不足:设置过小的连接池可能导致在高并发情况下请求无法及时获取数据库连接,从而影响并发性能和响应速度。
  2. 频繁创建和销毁连接:连接池过小会导致频繁地创建和销毁连接,增加了系统的开销。
  3. 请求等待:在高并发情况下,请求可能会等待空闲连接,导致延迟增加,用户体验下降

在GORM中,我们可以参照以下示例,对连接池进行有关配置。 

dsn := "root:123456@tcp(127.0.0.1:3306)/golang?charset=utf8mb4&parseTime=True&loc=Local"
db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})sqlDB, err := db.DB()
if err != nil {panic("failed to get database connection")
}// 设置最大打开的连接数
sqlDB.SetMaxOpenConns(10)
// 设置最大空闲连接数
sqlDB.SetMaxIdleConns(5)
// 设置连接的最大存活时间
sqlDB.SetConnMaxLifetime(time.Hour)

下面解释一下上述代码最后三行代码的配置分别代表什么,有什么作用。

// 设置最大打开的连接数
sqlDB.SetMaxOpenConns(10)

🌈通俗解释
想象你开了一家餐厅,最多只能同时雇佣10个服务员。无论有多少顾客来,你最多只能同时派10个服务员去服务。这个数字就是“最大打开的连接数”。

☀️技术解释
最大打开的连接数是指数据库连接池中同时可以打开的数据库连接的最大数量。如果设置为10,那么最多只能有10个连接同时处于“打开”状态,用于执行数据库操作。如果所有连接都被占用,新的请求需要等待,直到有连接被释放。

// 设置最大空闲连接数
sqlDB.SetMaxIdleConns(5)

🌈通俗解释:
继续用餐厅的例子,假设你有10个服务员,但并不是所有服务员都一直有活干。有些服务员可能暂时没事做(空闲)。你希望最多有5个服务员可以“待命”,随时准备接单。这个数字就是“最大空闲连接数”。
☀️技术解释:
最大空闲连接数是指连接池中允许存在的空闲连接的最大数量。空闲连接是指当前没有被使用的连接。如果空闲连接数超过这个值,多余的连接会被关闭,以节省资源。

// 设置连接的最大存活时间
sqlDB.SetConnMaxLifetime(time.Hour)

🌈通俗解释
假设你规定每个服务员最多只能连续工作1小时,之后必须休息或换人。这个时间限制就是“连接最大存活时间”。

☀️技术解释
连接最大存活时间是指一个数据库连接在连接池中可以存在的最长时间。如果一个连接已经存在了超过这个时间,它会被自动关闭,并从连接池中移除。这样可以确保连接不会因为长时间使用而出现性能问题或资源泄漏。

4.使用GORM对数据库进行操作(重点) 

        首先,如果对结构体以及标签(Tag)不熟悉的uu,还请移步到结构体标签与反射机制,GORM对数据库的基本操作与结构体类型数据非常相关。对结构体不熟悉的话,可能下面的代码会看不懂QAQ。

4.1 创建数据表

        假设我们现在需要构建一个 Students 表,那么我们得先创建一个Students的结构体类型数据,这一步我们称为 定义操作模型 。如下:

type Students struct {StudentID uint   `gorm:"primaryKey;autoIncrement"`Name      string `gorm:"size:50;not null"`Major     string `gorm:"size:100"`Gender    string `gorm:"type:enum('男', '女');not null"`Phone     string `gorm:"size:11;not null"`
}

        这里结构体使用 gorm 标签,以下是关于 gorm 标签常用的标签字段表:

标签说明示例
primaryKey标记字段为主键gorm:"primaryKey"
autoIncrement主键自增(仅支持整数类型)gorm:"primaryKey;autoIncrement"
column自定义数据库列名gorm:"column:user_name"
type指定数据库字段类型gorm:"type:varchar(100)"
size设置字段长度(如字符串类型)gorm:"size:255"
default设置字段默认值gorm:"default:'anonymous'"
not null字段不可为空gorm:"not null"
unique唯一约束(值不可重复)gorm:"unique"
uniqueIndex创建唯一索引(可指定索引名)gorm:"uniqueIndex:idx_email"
index创建普通索引gorm:"index"
check自定义检查约束gorm:"check:age > 18"
autoCreateTime记录创建时间(time.Time 类型)gorm:"autoCreateTime"
autoUpdateTime记录更新时间(time.Time 类型)gorm:"autoUpdateTime"
foreignKey定义外键字段gorm:"foreignKey:UserID"
references定义关联的主键字段gorm:"references:ID"
many2many定义多对多关联的中间表gorm:"many2many:user_groups;"
polymorphic多态关联(用于多模型共享关联)gorm:"polymorphic:Owner"

         接着连接数据库之后,使用 db.AutoMigrate() 启用自动迁移模式,此时如果Students表不存在,则会依据上述定义的结构体,自动创建一个Students表,如果表已存在但是表的结构与结构体的结构不一样,则会自动更新数据表的结构与结构体保持一致。 

	// 连接到Mysql数据库dsn := "root:123456@tcp(127.0.0.1:3306)/golang?charset=utf8mb4&parseTime=True&loc=Local"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})//自动迁移模式(如果表不存在,会自动创建)db.AutoMigrate(&Students{})

我们可以使用 Navicat 或者 sql语句 直接查看创建的数据表:

这里补充一下,GORM的结构体字段到数据库字段的转化是采取 Snake Case 风格转换:

  • 结构体的名称必须首字母大写 ,并和数据库表名称对应。
  • 结构体中的字段名称首字母必须大写,并和数据库表中的字段一一对应
  • Snake Case命名风格,就是各个单词之间用下划线(_)分隔,例如: CreateTime的Snake Case风格命名为create_time。
  • 在创建数据表过程中,默认情况表名是结构体名称的复数形式。如果我们的结构体名称定义成 User,表示这个模型默认操作的是 users 表。

4.2 CRUD操作 

下面以User表作为示例:

type User struct {ID    uint   `gorm:"primaryKey"` // 主键Name  string `gorm:"size:100"`    // 字符串长度限制Age   intEmail string `gorm:"unique"`     // 唯一约束
}

1.新增数据:

// 单条插入
user := User{Name: "Alice", Age: 25, Email: "alice@example.com"}
result := db.Create(&user) // 插入数据
if result.Error != nil {panic("插入失败: " + result.Error.Error())
}
fmt.Println("插入成功,ID:", user.ID) // 自动填充主键// 批量插入
users := []User{{Name: "Bob", Age: 30, Email: "bob@example.com"},{Name: "Charlie", Age: 28, Email: "charlie@example.com"},
}
db.Create(&users)

2.查询数据

// 查询单条(按主键)
var user User
db.First(&user, 1) // 查询 ID=1 的记录
fmt.Println(user.Name)// 条件查询
db.Where("age > ?", 20).First(&user)   // 第一条符合条件的记录
db.Where("name LIKE ?", "%Ali%").Find(&user)// 查询多条
var users []User
db.Where("age BETWEEN ? AND ?", 20, 30).Find(&users)// 选择特定字段
db.Select("name", "age").Find(&users)// 排序和分页
db.Order("age desc").Limit(10).Offset(0).Find(&users)

3.更新数据

// 更新单个字段
db.Model(&user).Update("age", 26) // 将 user 的 age 更新为 26// 更新多个字段
db.Model(&user).Updates(User{Name: "Alice Smith", Age: 27})// 条件更新(更新所有符合条件的记录)
db.Where("age < ?", 18).Updates(User{Name: "未成年"})// 注意:Updates 默认忽略零值(如 Age:0),需用 Select 强制更新
db.Model(&user).Select("Age").Updates(User{Age: 0})

4.删除数据

// 删除单条记录(软删除,需模型包含 DeletedAt 字段)
db.Delete(&user) // 实际执行 UPDATE 设置 deleted_at 时间// 硬删除(物理删除)
db.Unscoped().Delete(&user) // 直接从数据库删除// 条件删除
db.Where("email LIKE ?", "%example.com").Delete(&User{})
  • 软删除:并不会真正从数据库中移除数据,而是通过添加一个标记字段(如is_deleted或deleted_at)来表示数据是否被“删除”。查询时,通常会过滤掉这些被标记为已删除的数据。
  • 硬删除:硬删除会直接从数据库中移除数据,这些数据一旦删除,就无法恢复(除非有备份)

GORM利用原生SQL执行

        以上的CRUD操作都是基于GORM的封装函数实现,如果习惯了写 sql 的uu,也可以使用 db.Exec()以及db.Raw()来执行sql语句,具体使用可参考下面的示例代码

完整实例:

package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)type User struct {ID    uintName  stringAge   intEmail string
}func main() {dsn := "root:123456@tcp(127.0.0.1:3306)/test_db?charset=utf8mb4&parseTime=True&loc=Local"db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})if err != nil {panic("数据库连接失败")}// 插入db.Exec("INSERT INTO users (name, age, email) VALUES (?, ?, ?)", "李四", 28, "lisi@example.com")// 查询var user Userdb.Raw("SELECT * FROM users WHERE name = ?", "李四").Scan(&user)fmt.Printf("查询结果: %+v\n", user)// 更新db.Exec("UPDATE users SET age = ? WHERE name = ?", 30, "李四")// 删除db.Exec("DELETE FROM users WHERE name = ?", "李四")
}

        至此17篇,我们终于学完了Go的后端开发的最为基础的内容。

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

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

相关文章

【JavaEE】网络原理详解

1.❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; Hello, Hello~ 亲爱的朋友们&#x1f44b;&#x1f44b;&#xff0c;这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章&#xff0c;请别吝啬你的点赞❤️❤️和收藏&#x1f4d6;&#x1f4d6;。如果你对我的…

第十五届蓝桥杯单片机省赛程序设计试题

同时也是积分赛——测量NE555输出脉冲频率 第十五届 蓝桥杯 单片机设计与开发项目 省赛1 第二部分 程序设计试题&#xff08;85 分&#xff09; &#xff08;大学组&#xff09; 一 基本要求 1、使用大赛组委会统一提供的四梯单片机竞赛实训平台&#xff0c;完成本试题程序…

JavaScript智能对话机器人——企业知识库自动化

引言 内部知识管理常面临信息分散、查找困难的问题。本文将使用Node.js和虎跃办公的智能对话API&#xff0c;构建企业级知识问答机器人&#xff0c;支持自然语言查询和自动学习。 核心技术 自然语言处理&#xff08;NLP&#xff09;意图识别机器学习模型微调REST API集成 代…

元宇宙浪潮下,前端开发如何“乘风破浪”?

一、元宇宙对前端开发的新要求 元宇宙的兴起&#xff0c;为前端开发领域带来了全新的挑战与机遇。元宇宙作为一个高度集成、多维互动的虚拟世界&#xff0c;要求前端开发不仅具备传统网页开发的能力&#xff0c;还需要掌握虚拟现实&#xff08;VR&#xff09;、增强现实&#…

Spring Boot 3.4.3 基于 Caffeine 实现本地缓存

在现代企业级应用中,缓存是提升系统性能和响应速度的关键技术。通过减少数据库查询或复杂计算的频率,缓存可以显著优化用户体验。Spring Boot 3.4.3 提供了强大的缓存抽象支持,而 Caffeine 作为一款高性能的本地缓存库,因其优异的吞吐量和灵活的配置,成为许多开发者的首选…

QT Quick(C++)跨平台应用程序项目实战教程 6 — 弹出框

目录 1. Popup组件介绍 2. 使用 上一章内容完成了音乐播放器程序的基本界面框架设计。本小节完成一个简单的功能。单击该播放器顶部菜单栏的“关于”按钮&#xff0c;弹出该程序的相关版本信息。我们将使用Qt Quick的Popup组件来实现。 1. Popup组件介绍 Qt 中的 Popup 组件…

DuckDB系列教程:如何分析Parquet文件

Parquet 是一种强大的、基于列的存储格式&#xff0c;适用于实现更快捷和更高效的数据分析。您可以使用 DuckDB 这种内存型分析数据库来处理 Parquet 文件并运行查询以对其进行分析。 在这篇文章中&#xff0c;我们将逐步介绍如何使用 DuckDB 对存储在 Parquet 文件中的餐厅订单…

异步框架使用loguru和contextvars实现日志按Id输出

需求阐述 工作中使用fastStream模块消费kafka事件的时候&#xff0c;遇到以下问题。1. 由于main.py模块要用到许多其他模块 &#xff0c;main模块&#xff0c;和其他模块都有日志输出。2. 要实现异步消费事件&#xff0c;但是又不希望日志打印的很乱。3. 想着在每次消费事件的…

【HTTPS协议】

文章目录 一、HTTPS二、HTTPS协议五种加密方案1.只使用对称加密2.只使用非对称加密3.双方都使用非对称加密4.对称加密非对称加密中间人攻击理解数字签名CA机构和证书 5. 对称加密非对称加密证书认证中间人篡改证书&#xff1f;中间人调包整个证书&#xff1f; 常见问题总结 一、…

算法设计学习8

实验目的及要求&#xff1a; 通过深入学习树&#xff08;Tree&#xff09;和二叉树&#xff08;Binary Tree&#xff09;这两种重要的数据结构&#xff0c;掌握它们的基本概念、性质和操作&#xff0c;提高对树形结构的理解和应用能力。通过本实验&#xff0c;学生将深化对树和…

P17_ResNeXt-50

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、模型结构 ResNeXt-50由多个残差块&#xff08;Residual Block&#xff09;组成&#xff0c;每个残差块包含三个卷积层。以下是模型的主要结构&#xff1…

【YOLO系列(V5-V12)通用数据集-剪刀石头布手势检测数据集】

YOLO格式的剪刀石头布手势检测数据集&#xff0c;适用于YOLOv5-v11所有版本&#xff0c;可以用于本科毕设、发paper、做课设等等&#xff0c;有需要的在这里获取&#xff1a; 【YOLO系列&#xff08;V5-V12&#xff09;通用数据集-剪刀石头布手势检测数据集】 数据集专栏地址&a…

基于连接池与重试机制的高效TDengine写入方案

摘要 在时序数据库应用场景中,如何构建稳定高效的写入机制是核心挑战。本文基于提供的Python代码实现,解析一种结合连接池管理、智能重试策略和事务控制的TDengine写入方案,并分析其技术优势与优化方向。 一、代码 from dbutils.pooled_db import PooledDB import timede…

抖音热点视频识别与分片处理机制解析

抖音作为日活数亿的短视频平台,其热点视频识别和分片处理机制是支撑高并发访问的核心技术。以下是抖音热点视频识别与分片的实现方案: 热点视频识别机制 1. 实时行为监控系统 用户行为聚合:监控点赞、评论、分享、完播率等指标的异常增长曲线内容特征分析:通过AI识别视频…

基于RDK X3的“校史通“机器人:SLAM导航+智能交互,让校史馆活起来!

视频标题&#xff1a; 【校史馆の新晋顶流】RDK X3机器人&#xff1a;导览员看了直呼内卷 视频文案&#xff1a; 跑得贼稳团队用RDK X3整了个大活——给校史馆造了个"社牛"机器人&#xff01; 基于RDK X3开发板实现智能导航与语音交互SLAM技术让机器人自主避障不…

Metal学习笔记十三:阴影

在本章中&#xff0c;您将了解阴影。阴影表示表面上没有光。当另一个表面或对象使对象与光线相遮挡时&#xff0c;您会看到对象上的阴影。在项目中添加阴影可使您的场景看起来更逼真&#xff0c;并提供深度感。 阴影贴图 阴影贴图是包含场景阴影信息的纹理。当光线照射到物体…

Matplotlib:数据可视化的艺术与科学

引言&#xff1a;让数据开口说话 在数据分析与机器学习领域&#xff0c;可视化是理解数据的重要桥梁。Matplotlib 作为 Python 最流行的绘图库&#xff0c;提供了从简单折线图到复杂 3D 图表的完整解决方案。本文将通过实际案例&#xff0c;带您从基础绘图到高级定制全面掌握 …

Python数据可视化-第4章-图表样式的美化

环境 开发工具 VSCode库的版本 numpy1.26.4 matplotlib3.10.1 ipympl0.9.7教材 本书为《Python数据可视化》一书的配套内容&#xff0c;本章为第4章 图表样式的美化 本章主要介绍了图表样式的美化&#xff0c;包括图表样式概述、使用颜色、选择线型、添加数据标记、设置字体…

嵌入式海思Hi3861连接华为物联网平台操作方法

1.1 实验目的 快速演示 1、认识轻量级HarmonyOS——LiteOS-M 2、初步掌握华为云物联网平台的使用 3、快速驱动海思Hi3861 WIFI芯片,连接互联网并登录物联网平台

如何在Redis容量限制下保持热点数据

如何在Redis容量限制下保持热点数据 当数据库有100万条数据但Redis只能保存10万条时,需要智能的策略来确保Redis中存储的都是最常访问的热点数据。以下是几种有效的解决方案: 一、内存淘汰策略 Redis提供了多种内存淘汰机制,当内存不足时会自动删除部分数据: 策略命令/配…