Coze源码分析-资源库-删除数据库-后端源码-领域服务/数据访问层

4. 领域服务层

数据库领域服务层架构

数据库领域服务层是Coze Studio中处理数据库业务逻辑的核心层,负责数据库资源的删除、管理和业务规则实现。该层采用领域驱动设计(DDD)模式,将业务逻辑与数据访问分离,确保代码的可维护性和可扩展性。

数据库领域服务接口定义

数据库领域服务接口定义了数据库管理的核心业务能力,包括数据库资源的完整生命周期管理。

go 复制代码
type DatabaseService interface {
	// 删除数据库
	DeleteDatabase(ctx context.Context, req *DeleteDatabaseRequest) error
	
	// 其他数据库管理方法
	CreateDatabase(ctx context.Context, req *CreateDatabaseRequest) (*CreateDatabaseResponse, error)
	GetDatabase(ctx context.Context, req *GetDatabaseRequest) (*GetDatabaseResponse, error)
	UpdateDatabase(ctx context.Context, req *UpdateDatabaseRequest) error
}

核心接口功能

  1. 数据库资源管理:创建、获取、更新、删除用户自定义的数据库资源
  2. 删除操作核心:DeleteDatabase方法是删除数据库的核心业务接口
  3. 事务管理:确保数据库删除操作的原子性和一致性
  4. 业务规则封装:封装数据库相关的业务逻辑和验证规则
  5. 数据完整性保障:确保数据库及其关联数据的完整删除
数据库领域服务实现

文件位置:backend/domain/memory/database/service/database_impl.go

数据库服务实现类包含了所有数据库相关业务逻辑的具体实现,负责处理数据库删除的核心业务逻辑,包括在线库和草稿库的同时删除。

go 复制代码
func (d databaseService) DeleteDatabase(ctx context.Context, req *DeleteDatabaseRequest) error {
	onlineInfo, err := d.onlineDAO.Get(ctx, req.ID)
	if err != nil {
		return fmt.Errorf("get online database info failed: %v", err)
	}

	draftInfo, err := d.draftDAO.Get(ctx, onlineInfo.GetDraftID())
	if err != nil {
		return fmt.Errorf("get draft database info failed: %v", err)
	}

	tx := query.Use(d.db).Begin()
	if tx.Error != nil {
		return fmt.Errorf("start transaction failed, %v", tx.Error)
	}

	defer func() {
		if r := recover(); r != nil {
			e := tx.Rollback()
			if e != nil {
				logs.CtxErrorf(ctx, "rollback failed, err=%v", e)
			}

			err = fmt.Errorf("catch panic: %v\nstack=%s", r, string(debug.Stack()))
			return
		}

		if err != nil {
			e := tx.Rollback()
			if e != nil {
				logs.CtxErrorf(ctx, "rollback failed, err=%v", e)
			}
		}
	}()

	err = d.draftDAO.DeleteWithTX(ctx, tx, draftInfo.ID)
	if err != nil {
		return fmt.Errorf("delete draft database info failed: %v", err)
	}

	err = d.onlineDAO.DeleteWithTX(ctx, tx, onlineInfo.ID)
	if err != nil {
		return fmt.Errorf("delete online database info failed: %v", err)
	}

	err = tx.Commit()
	if err != nil {
		return fmt.Errorf("commit transaction failed: %v", err)
	}

	// delete draft physical table
	if draftInfo.ActualTableName != "" {
		_, err = d.rdb.DropTable(ctx, &rdb.DropTableRequest{
			TableName: draftInfo.ActualTableName,
		})
		// 错误处理...
	}

	// delete online physical table
	if onlineInfo.ActualTableName != "" {
		_, err = d.rdb.DropTable(ctx, &rdb.DropTableRequest{
			TableName: onlineInfo.ActualTableName,
		})
		// 错误处理...
	}

	return nil
}

删除操作实现特点

  1. 事务保障:使用数据库事务确保删除操作的原子性和一致性
  2. 完整删除:同时删除在线库和草稿库的元数据和物理表
  3. 异常处理:完善的panic恢复和事务回滚机制
  4. 资源清理:删除数据库相关的物理表资源
  5. 错误包装:详细的错误信息,便于问题定位和调试

DeleteDatabase方法详解

  • 参数:接收DeleteDatabaseRequest结构体,包含数据库ID
  • 处理流程
    1. 获取在线数据库信息
    2. 获取对应草稿数据库信息
    3. 开启事务进行原子操作
    4. 删除草稿数据库信息
    5. 删除在线数据库信息
    6. 提交事务
    7. 删除物理表资源
  • 错误处理:每个步骤都有详细的错误捕获和包装
数据库实体定义

数据库实体定义了数据库资源的核心数据结构,包含了数据库的所有关键属性。

go 复制代码
type Database struct {
	ID             int64         // 数据库唯一标识
	AppID          int64         // 所属应用ID
	SpaceID        int64         // 所属空间ID,支持多租户隔离
	CreatorID      int64         // 创建者ID
	TableName      string        // 表名
	FieldList      []*FieldItem  // 字段列表
	ActualTableName string       // 实际物理表名
	DraftID        *int64        // 草稿ID
	RwMode         BotTableRWMode // 读写模式
	Status         BotTableStatus // 状态
	CreatedAt      int64         // 创建时间戳
	UpdatedAt      int64         // 更新时间戳
}

实体设计特点

  1. 基础信息:包含ID、应用ID、空间ID等基本属性
  2. 表结构定义:通过FieldList定义数据库表结构
  3. 多租户支持:SpaceID字段支持多租户和空间隔离
  4. 创建者管理:CreatorID字段支持数据库所有权管理
  5. 状态管理:Status字段支持数据库的生命周期管理
  6. 物理映射:ActualTableName字段记录实际物理表名
  7. 草稿关联:DraftID字段关联对应的草稿版本
  8. 读写控制:RwMode字段控制数据库的读写权限
  9. 时间追踪:CreatedAt和UpdatedAt支持时间追踪和审计

5. 数据访问层

5.1 仓储接口定义

数据库仓储接口

数据库仓储接口定义了数据库资源的持久化操作能力,包括数据库的增删改查等核心功能。

go 复制代码
type DatabaseRepository interface {
	// DeleteDatabase 删除数据库
	DeleteDatabase(ctx context.Context, id int64) error
	// GetDatabase 获取数据库信息
	GetDatabase(ctx context.Context, id int64) (*DatabaseInfo, error)
	// 其他CRUD方法...
}

删除方法特点

  • 事务删除:DeleteDatabase方法支持事务操作,确保数据一致性
  • 上下文支持:支持context.Context进行请求链路追踪
  • 错误处理:返回error类型,便于上层进行错误处理
  • ID定位:通过唯一id精确定位要删除的数据库资源

5.2 数据访问对象(DAO)

数据库删除的具体实现

数据库删除操作涉及在线库和草稿库的同步删除,需要通过事务确保数据一致性:

go 复制代码
func (d *databaseRepoImpl) DeleteDatabase(ctx context.Context, id int64) (err error) {
	onlineInfo, err := d.onlineDAO.Get(ctx, id)
	if err != nil {
		return fmt.Errorf("get online database info failed: %v", err)
	}

	draftInfo, err := d.draftDAO.Get(ctx, onlineInfo.GetDraftID())
	if err != nil {
		return fmt.Errorf("get draft database info failed: %v", err)
	}

	tx := query.Use(d.db).Begin()
	if tx.Error != nil {
		return fmt.Errorf("start transaction failed, %v", tx.Error)
	}

	defer func() {
		if r := recover(); r != nil {
			e := tx.Rollback()
			if e != nil {
				logs.CtxErrorf(ctx, "rollback failed, err=%v", e)
			}

			err = fmt.Errorf("catch panic: %v\nstack=%s", r, string(debug.Stack()))
			return
		}

		if err != nil {
			e := tx.Rollback()
			if e != nil {
				logs.CtxErrorf(ctx, "rollback failed, err=%v", e)
			}
		}
	}()

	err = d.draftDAO.DeleteWithTX(ctx, tx, draftInfo.ID)
	if err != nil {
		return fmt.Errorf("delete draft database info failed: %v", err)
	}

	err = d.onlineDAO.DeleteWithTX(ctx, tx, onlineInfo.ID)
	if err != nil {
		return fmt.Errorf("delete online database info failed: %v", err)
	}

	err = tx.Commit()
	if err != nil {
		return fmt.Errorf("commit transaction failed: %v", err)
	}

	// 删除物理表资源
	if draftInfo.ActualTableName != "" {
		_, err = d.rdb.DropTable(ctx, &rdb.DropTableRequest{
			TableName: draftInfo.ActualTableName,
		})
		// 错误处理...
	}

	if onlineInfo.ActualTableName != "" {
		_, err = d.rdb.DropTable(ctx, &rdb.DropTableRequest{
			TableName: onlineInfo.ActualTableName,
		})
		// 错误处理...
	}

	return nil
}

删除操作的关键特点

  1. 事务保证:使用数据库事务确保所有删除操作的原子性
  2. 完整删除:同时删除在线库和草稿库的元数据和物理表
  3. 异常处理:完善的panic恢复和事务回滚机制
  4. 资源清理:删除数据库相关的物理表资源
  5. 错误包装:详细的错误信息,便于问题定位和调试

删除涉及的数据表

  • bot_table_info:数据库元数据表
  • bot_table_info_draft:数据库草稿表
  • 物理表:实际存储数据的物理表
DatabaseDAO结构体

DatabaseDAO是数据库数据访问的具体实现,负责与数据库进行交互,处理数据库资源的持久化操作。

go 复制代码
package dal

import (
	"context"
	"fmt"

	"gorm.io/gorm"

	"github.com/coze-dev/coze-studio/backend/infra/contract/idgen"
)

type DatabaseDAO struct {
	db *gorm.DB
	idGen idgen.IDGenerator
}

func NewDatabaseDAO(db *gorm.DB, generator idgen.IDGenerator) *DatabaseDAO {
	return &DatabaseDAO{
		db: db,
		idGen: generator,
	}
}
数据库删除操作实现

删除数据库记录

go 复制代码
func (d *DatabaseDAO) DeleteWithTX(ctx context.Context, tx *gorm.DB, id int64) (err error) {
	result := tx.WithContext(ctx).Where("id = ?", id).Delete(&DatabaseInfo{})
	if result.Error != nil {
		return fmt.Errorf("delete database in transaction failed: %v", result.Error)
	}
	
	if result.RowsAffected == 0 {
		return fmt.Errorf("database not found with id: %d", id)
	}
	
	return nil
}

获取数据库信息

go 复制代码
func (d *DatabaseDAO) Get(ctx context.Context, id int64) (*DatabaseInfo, error) {
	var info DatabaseInfo
	result := d.db.WithContext(ctx).Where("id = ?", id).First(&info)
	if result.Error != nil {
		return nil, fmt.Errorf("get database failed: %v", result.Error)
	}
	return &info, nil
}
数据转换方法

数据库实体与数据模型转换

go 复制代码
func (d *DatabaseDAO) databaseInfoDO2PO(database *entity.DatabaseInfo) *model.DatabaseInfo {
	fieldListJSON, _ := json.Marshal(database.FieldList)
	return &model.DatabaseInfo{
		ID:             database.ID,
		AppID:          database.AppID,
		SpaceID:        database.SpaceID,
		CreatorID:      database.CreatorID,
		TableName:      database.TableName,
		FieldList:      string(fieldListJSON),
		ActualTableName: database.ActualTableName,
		DraftID:        database.DraftID,
		RwMode:         int32(database.RwMode),
		Status:         int32(database.Status),
	}
}

数据模型转实体

go 复制代码
type databaseInfoPO model.DatabaseInfo

func (d databaseInfoPO) ToDO() *entity.DatabaseInfo {
	var fieldList []*entity.FieldItem
	_ = json.Unmarshal([]byte(d.FieldList), &fieldList)
	
	database := &entity.DatabaseInfo{
		ID:             d.ID,
		AppID:          d.AppID,
		SpaceID:        d.SpaceID,
		CreatorID:      d.CreatorID,
		TableName:      d.TableName,
		FieldList:      fieldList,
		ActualTableName: d.ActualTableName,
		DraftID:        d.DraftID,
		RwMode:         entity.BotTableRWMode(d.RwMode),
		Status:         entity.BotTableStatus(d.Status),
		CreatedAt:      d.CreatedAt,
		UpdatedAt:      d.UpdatedAt,
	}
	return database
}

删除操作特点

  1. 事务删除:DeleteWithTX方法支持事务操作,确保数据一致性
  2. 精确定位:通过id精确定位要删除的数据库资源
  3. 结果验证:验证删除操作是否实际影响了数据行
  4. 物理删除:执行物理删除操作,从数据库中彻底移除记录
  5. 资源清理:同时清理物理表资源,避免资源泄漏

删除数据库的完整数据访问流程

在删除数据库的场景中,数据访问层的操作流程如下:

  1. 获取在线库信息:查询在线数据库的元数据信息
  2. 获取草稿库信息:根据在线库关联的DraftID查询草稿库信息
  3. 事务开始:开启数据库事务,确保删除操作的原子性
  4. 删除草稿库:在事务中删除草稿库记录
  5. 删除在线库:在事务中删除在线库记录
  6. 事务提交:所有删除操作成功后提交事务
  7. 删除物理表:提交事务后,删除相关的物理表资源
  8. 错误回滚:任何操作失败时回滚事务,保证数据一致性

这种设计确保了删除操作的安全性、可靠性和数据完整性。

数据访问层删除操作总结

删除数据库在数据访问层的实现具有以下特点:

  1. 事务保证:所有元数据删除操作在事务中执行,确保数据一致性
  2. 完整删除:同时删除在线库、草稿库和物理表资源
  3. 验证机制:验证删除操作是否成功,确保资源确实被删除
  4. 错误处理:完善的错误处理和事务回滚机制
  5. 资源清理:彻底清理相关资源,避免资源泄漏
  6. 性能优化:通过精确的WHERE条件,确保删除操作的高效执行

5.3 数据库数据模型

DatabaseInfo数据模型

数据库数据模型定义了数据库资源在数据库中的存储结构,使用GORM标签进行ORM映射。

go 复制代码
// DatabaseInfo 数据库信息模型
type DatabaseInfo struct {
	ID             int64  `gorm:"column:id;primaryKey;autoIncrement;comment:数据库ID" json:"id"`
	AppID          int64  `gorm:"column:app_id;not null;index:idx_appid;comment:应用ID" json:"app_id"`
	SpaceID        int64  `gorm:"column:space_id;not null;index:idx_spaceid;comment:空间ID" json:"space_id"`
	CreatorID      int64  `gorm:"column:creator_id;not null;index:idx_creatorid;comment:创建者ID" json:"creator_id"`
	TableName      string `gorm:"column:table_name;not null;type:varchar(100);comment:表名" json:"table_name"`
	FieldList      string `gorm:"column:field_list;type:text;comment:字段列表" json:"field_list"`
	ActualTableName string `gorm:"column:actual_table_name;type:varchar(255);comment:实际表名" json:"actual_table_name"`
	DraftID        *int64 `gorm:"column:draft_id;index:idx_draftid;comment:草稿ID" json:"draft_id"`
	RwMode         int32  `gorm:"column:rw_mode;default:0;comment:读写模式" json:"rw_mode"`
	Status         int32  `gorm:"column:status;default:0;comment:状态" json:"status"`
	CreatedAt      int64  `gorm:"column:created_at;not null;autoCreateTime;comment:创建时间" json:"created_at"`
	UpdatedAt      int64  `gorm:"column:updated_at;not null;autoUpdateTime;comment:更新时间" json:"updated_at"`
}

// TableName 指定表名
func (*DatabaseInfo) TableName() string {
	return "bot_table_info"
}

删除操作中的模型特点

  1. 主键定位:ID字段作为主键,是删除操作的核心定位字段,确保精确删除
  2. 索引优化:为AppID、SpaceID、CreatorID、DraftID字段建立索引,提高查询效率
  3. 关联字段:DraftID字段关联在线库和草稿库,支持级联删除
  4. 物理映射:ActualTableName字段记录实际物理表名,支持物理资源清理
  5. 类型约束:对字符串类型设置长度限制,确保数据完整性
  6. 默认值设置:为RwMode和Status字段设置默认值
  7. 时间戳自动管理:使用autoCreateTime和autoUpdateTime自动管理时间戳
  8. JSON序列化:通过json标签支持JSON序列化,便于API响应和日志记录

5.4 GORM生成的查询接口

GORM框架为数据库数据模型生成了丰富的查询接口,支持各种查询和操作场景。

go 复制代码
// 根据ID查询
func (d *DatabaseDAO) GetByID(ctx context.Context, id int64) (*DatabaseInfo, error) {
	var info DatabaseInfo
	result := d.db.WithContext(ctx).First(&info, "id = ?", id)
	if result.Error != nil {
		return nil, result.Error
	}
	return &info, nil
}

// 条件查询
func (d *DatabaseDAO) ListByCondition(ctx context.Context, condition map[string]interface{}, page, pageSize int) ([]*DatabaseInfo, error) {
	var infos []*DatabaseInfo
	query := d.db.WithContext(ctx)
	
	// 添加查询条件
	for key, value := range condition {
		query = query.Where(key, value)
	}
	
	// 分页查询
	result := query.Offset((page - 1) * pageSize).Limit(pageSize).Find(&infos)
	if result.Error != nil {
		return nil, result.Error
	}
	
	return infos, nil
}
复制代码
#### 查询接口定义
```go
type IWorkflowDraftDo interface {
	gen.SubQuery
	Debug() IWorkflowDraftDo
	WithContext(ctx context.Context) IWorkflowDraftDo
	WithResult(fc func(tx gen.Dao)) gen.ResultInfo
	ReplaceDB(db *gorm.DB)
	ReadDB() IWorkflowDraftDo
	WriteDB() IWorkflowDraftDo
	// 删除操作相关方法
	Delete(conds ...gen.Condition) (gen.ResultInfo, error)
	Where(conds ...gen.Condition) IWorkflowDraftDo
	......
}

删除操作相关接口特点

  1. Delete方法:提供类型安全的删除操作,支持条件删除
  2. Where条件:支持复杂的删除条件构建,确保精确删除
  3. 上下文支持:WithContext方法支持请求上下文传递
  4. 事务支持:支持在事务中执行删除操作,确保数据一致性
  5. 调试支持:Debug方法便于删除操作的SQL调试和优化
5.5 统一查询入口

文件位置:backend\domain\workflow\internal\dal\query\gen.go

该文件为删除工作流操作提供了统一的查询入口和事务支持,确保删除操作的一致性和可靠性。

核心代码:

go 复制代码
// Code generated by gorm.io/gen. DO NOT EDIT.

package query

import (
	"context"
	"database/sql"

	"gorm.io/gorm"

	"gorm.io/gen"

	"gorm.io/plugin/dbresolver"
)

var (
	Q            = new(Query)
	WorkflowDraft *workflowDraft
)

func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
	*Q = *Use(db, opts...)
	WorkflowDraft = &Q.WorkflowDraft
}

func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
	return &Query{
		db:          db,
		PluginDraft: newPluginDraft(db, opts...),
		ToolDraft:   newToolDraft(db, opts...),
	}
}

type Query struct {
	db *gorm.DB

	WorkflowDraft workflowDraft
}

func (q *Query) Available() bool { return q.db != nil }

func (q *Query) clone(db *gorm.DB) *Query {
	return &Query{
		db:          db,
		WorkflowDraft: q.WorkflowDraft.clone(db),
	}
}

func (q *Query) ReadDB() *Query {
	return q.ReplaceDB(q.db.Clauses(dbresolver.Read))
}

func (q *Query) WriteDB() *Query {
	return q.ReplaceDB(q.db.Clauses(dbresolver.Write))
}

func (q *Query) ReplaceDB(db *gorm.DB) *Query {
	return &Query{
		db:          db,
		WorkflowDraft: q.WorkflowDraft.replaceDB(db),
	}
}

type queryCtx struct {
	WorkflowDraft IWorkflowDraftDo
}

func (q *Query) WithContext(ctx context.Context) *queryCtx {
	return &queryCtx{
		WorkflowDraft: q.WorkflowDraft.WithContext(ctx),
	}
}

func (q *Query) Transaction(fc func(tx *Query) error, opts ...*sql.TxOptions) error {
	return q.db.Transaction(func(tx *gorm.DB) error { return fc(q.clone(tx)) }, opts...)
}

func (q *Query) Begin(opts ...*sql.TxOptions) *QueryTx {
	tx := q.db.Begin(opts...)
	return &QueryTx{Query: q.clone(tx), Error: tx.Error}
}

type QueryTx struct {
	*Query
	Error error
}

func (q *QueryTx) Commit() error {
	return q.db.Commit().Error
}

func (q *QueryTx) Rollback() error {
	return q.db.Rollback().Error
}

func (q *QueryTx) SavePoint(name string) error {
	return q.db.SavePoint(name).Error
}

func (q *QueryTx) RollbackTo(name string) error {
	return q.db.RollbackTo(name).Error
}

删除操作查询入口特点

  1. 全局查询对象:提供全局的WorkflowDraft查询对象,便于删除操作的统一管理
  2. 事务支持:Transaction方法支持在事务中执行删除操作,确保数据一致性
  3. 读写分离:ReadDB和WriteDB方法支持数据库读写分离,删除操作使用WriteDB
  4. 上下文传递:WithContext方法支持请求上下文在删除操作中的传递
  5. 数据库切换:ReplaceDB方法支持动态切换数据库连接,便于多环境部署
  6. 事务管理:Begin、Commit、Rollback等方法提供完整的事务管理能力

5.6 数据访问层删除操作架构总结

删除工作流在数据访问层的实现体现了现代Go应用的最佳实践:

技术特点

  1. 类型安全:使用GORM Gen生成类型安全的查询接口,避免SQL注入和类型错误
  2. 分层设计:Repository接口抽象数据访问,DAO实现具体的数据库操作
  3. 错误处理:统一的错误码包装机制,便于上层进行错误分类和处理
  4. 事务支持:完整的事务支持,确保删除操作的原子性
  5. 性能优化:精确的WHERE条件和索引利用,确保删除操作的高效执行

安全保障

  1. 权限验证:通过OwnerID字段确保只有工作流所有者可以删除自己的工作流
  2. 存在性检查:删除前验证工作流是否存在,避免无效删除
  3. 物理删除:彻底从数据库中移除记录,确保数据清理的完整性
  4. 审计追踪:完整的时间戳记录,支持删除操作的审计和追踪

删除操作流程

  1. 接口调用:上层通过Repository接口调用DeleteDraftWorkflow方法
  2. 事务开启:开启数据库事务确保操作的原子性
  3. 删除操作:删除工作流数据
  4. 事务提交:删除操作成功后提交事务
  5. 错误处理:任何步骤失败都会回滚事务并返回错误

这种设计确保了删除工作流操作的安全性、可靠性和高性能,为上层业务逻辑提供了坚实的数据访问基础。

数据模型与查询文件依赖关系
复制代码
数据库表结构 (schema.sql)(workflow_draft表)
    ↓    gen_orm_query.go
模型文件 (model/workflow_draft.gen.go) - 生成模型
    ↓
查询文件 (query/workflow_draft.gen.go) - 依赖对应模型
    ↓
统一入口 (query/gen.go) - 依赖所有查询文件

数据访问层架构总结

分层架构

复制代码
业务服务层 (Service)
       ↓
仓储接口层 (Repository Interface)
       ↓
数据访问层 (DAO Implementation)
       ↓
GORM查询层 (Generated Query)
       ↓
数据模型层 (Generated Model)
       ↓
数据库层 (MySQL)

删除工作流在数据访问层的完整流程

  1. 接口定义WorkflowRepository.DeleteDraftWorkflow(ctx, ID) 定义删除操作契约
  2. DAO实现WorkflowDraftDAO.DeleteWithTX(tx, ID) 实现具体删除逻辑
  3. 事务管理:使用事务确保工作流数据的一致性删除
  4. 删除操作:执行工作流数据的删除操作
  5. 错误处理:包装删除异常为统一错误码
  6. 结果返回:删除成功返回nil,失败返回包装后的错误

设计优势

  1. 接口抽象:通过Repository接口实现数据访问的抽象化
  2. 代码生成:使用GORM Gen自动生成类型安全的查询代码
  3. 错误处理:统一的错误包装和处理机制
  4. 事务支持:通过context传递支持数据库事务
  5. 删除安全:通过ID精确定位,避免误删除操作
  6. 性能优化:合理的索引设计和查询优化
  7. 可测试性:清晰的分层结构便于单元测试
  8. 可维护性:代码生成减少手工编写,降低维护成本
  9. 单一职责:每个DAO类专注于单一实体的数据访问操作

删除操作的技术特点

  • 物理删除:当前实现为物理删除,直接从数据库中移除记录
  • 事务操作:使用数据库事务确保工作流数据的一致性删除
  • 索引优化:基于主键ID的删除操作,具有最佳的查询性能
  • 错误分类:通过错误码区分不同类型的删除异常
  • 审计支持:可通过数据库日志追踪删除操作的执行情况
相关推荐
科技小花26 分钟前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸28 分钟前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain29 分钟前
linux个人心得22 (mysql)
数据库·mysql
阿里小阿希1 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神1 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员1 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java2 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
一个天蝎座 白勺 程序猿2 小时前
Apache IoTDB(15):IoTDB查询写回(INTO子句)深度解析——从语法到实战的ETL全链路指南
数据库·apache·etl·iotdb
不知名的老吴2 小时前
Redis的延迟瓶颈:TCP栈开销无法避免
数据库·redis·缓存
YOU OU2 小时前
三大范式和E-R图
数据库