这是我参与「第三届青训营 -后端场」笔记创作活动的的第2篇笔记。
1、理解 Database/SQL
1.1、基本用法-Quick Start
database sql包只是实现一个统一的接口,不同的数据库与自己去实现它们自己的driver
//import mysql的driver,实现了怎么去连接数据库,解析数据库等等
import XXX/go-sql-driver/mysql
//利用driver + DSN(data source name)初始化DB连接
db, err := sql.Open("mysql",DSN)
//rows是一个游标?可以通过.Next()获取下一条数据
rows, err := db.Query(XXX,X)
//处理完返回的数据后,记得将rows.Close(),避免资源泄露
defer rows.Close()
//除了数据相关的错,都会通过这个err返回
if rows.Err() != nil {
}
1.2 、database sql包设计原理
- databse/sql 为应用程序提供标准的API操作接口,为下层驱动提供一些接口,内部实现一些对连接池的管理(一种池化技术,应对请求量特别大的情况,将一些昂贵的资源放到一个特定的池子里)
- database sql有利于支持各种各样的数据库,修改连接接口即可
- 对连接池管理
-
连接池配置:
- 取出连接池状态:
- 操作过程的伪实现:
- 取出连接池状态:
-
drivers实现的连接接口:
- 使用driver:
- 2017年go提出了一个新的接口,可以使用结构体:
- 使用:
- 使用:
- 2017年go提出了一个新的接口,可以使用结构体:
- 使用driver:
-
操作接口
- DB连接的几种连接:
- 直接连接/Conn:直接通过tcp链接访问数据库;
- 预编译/Stmt:执行同样的sql,后续仅根据reference id访问数据库,减少网络传输和sqwl解析时间;
- 事务/Tx
- 处理返回数据的几种方式:
- Exec / ExecContext -> Result:成功失败的信息
- Query / QueryContext ->Rows(Columns):以行的形式返回结果
- QueryRow / QueryRowContext ->Row(Rows 简化):只会读取一行数据
- DB连接的几种连接:
-
02GORM使用简介
2.1基本定义
GROM: 设计简介、功能强大、自由扩展的全功能ORM(Object Relational Mapping)
2.2 CRUD基本用法
-
2种方法是等价的,取值放到users中:
- 通过使用gorm,避免引入了driver,避免忘记rows.close(),err检查也简单更多了
-
基本用法--CRUD(create && update)
2.3 模型定义
- 举例,2种模型定义的方式等价:
2.3模型定义-惯例约定
2.4关联介绍
2.4 关联操作-CRUD
2.4 关联操作-Preload / Joins预加载
2.4 关联操作-级联删除
保障没有一些孤儿的数据
- 方法1:使用数据库约束自动删除
- 方法2:使用Select
03 GORM设计原理
- 在databse/sql包前封装了一层
3.1 SQL是怎么生成的
-
- 一条普通的查询sql,sql statement
-
- grom statement
-
chain method的内部实现:
-
Finisher method的内部实现:
-
为什么这么设计呢?
- 可以自定义Clause Builder(子句生成的sql)
- 方便使用同一套逻辑实现不同的数据库操作,举例:
- 方便使用同一套逻辑实现不同的数据库操作,举例:
- 方便扩展Clause(子句)
- 举例:
- grom可以通过自由选择子句的方式,生成不同的sql,因为不同的数据库支持的sql语句不一样,例如:
- 举例:
- 可以自定义Clause Builder(子句生成的sql)
3.2插件是怎么工作的
-
create callbacks:
- 使用db.Create()的时候,把插件系统内定义的所有create相关的注册的callbacks,均取出来调用
- 除此之外,插件还提供了自定义callbacks的功能:
-
为什么这么设计呢?
- 灵活定制,自由扩展
- 支持多租户:
- 支持多数据库、读写分离:
- 支持加解密、混沌工程
- 支持多租户:
- 灵活定制,自由扩展
3.3 ConnPool是什么
- 可以缓存以前的编译结果
- 全局模式,所有DB操作都会预编译并缓存(缓存不包含参数)
- 会话模式:后续会话的操作都会预编译并缓存
- 如何通过一行代码提升性能:
- mysql driver提供了一个参数interpolateParams(默认false: 执行、调用和关闭预编译sql),false可节省大量时间。
3.4 Dialector是什么
- 橙色部分(定义了怎么去连接数据库):
04 GORM最佳实践
4.1 数据序列化与SQL表达式-sql表达式更新创建
4.1 数据序列化与SQL表达式-sql表达式查询
4.1 数据序列化与SQL表达式-sql数据序列化
4.2 批量数据操作-批量创建/查询
- 避免一次性将所有数据放入内存
4.2 批量数据操作-批量更新
4.2 批量数据操作-批量数据加速操作
- 方法1:关闭默认事务
- 方法2:默认批量导入会调用Hooks方法,使用‘SkipHooks'跳过
- 方法3:使用Prepared Statement
- 混合使用
4.3代码复用、分库分表、Sharding-代码复用
-
代码复用:
-
分库分表:
-
Sharding:
4.4混沌工程 / 压测
- 插件:sqlchaos
- 压测:
4.5 Logger / Trace
4.6数据库迁移管理
4.7 Gen代码生成 / raw sql
4.7 Gen代码生成 / Gen