解压到
E:\Soft\go\bin\go1.5.1.windows-amd64
设置环境变量
GOROOT=E:\Soft\go\bin\go1.4.2.windows-amd64\go GOPATH=E:\Soft\go\gopath PATH+=%GOROOT%\bin PATH+=%GOPATH%\bin
life's a struggle.
2015-10-14
2015-10-13
流程分析
- 外部接口
1 | s := rpc.NewServer() // 定义一个rpc server |
参考
2015-10-13
要点
编码解码是相对于
json
字符串(utf-8
编码的slice)来讲的编码=>将
go
数据类型值转换为json
字符串解码=>将
json
字符串转换为go
中数据类型值
常用API
Marshal(v interface{}) ([]byte, error)
编码
Unmarshal(data []byte, v interface{}) error
解码
NewDecoder(r io.Reader) *Decoder
(dec *Decoder) Decode(v interface{}) error
从实现了
io.Reader
接口中的对象读取json
字符串来解码
参考
2015-10-10
要点
对目标列使用,
- 输出列名可读性更强
对表名使用
简写表名
同名表关联
在select的目标输出列中(
select_expr
)别名可以在
GROUP BY
,ORDER BY
,HAVING
中使用标准SQl不允许在
WHERE
中使用因为
WHERE
是执行的,而SELECT
目标列是基于WHERE
结果的,
所以WHERE
中不能使用还没产生的别名!
AS
可以省略select id userid from user; select a.id from user a;
参考
2015-10-10
表名采用小写下划线
如auth_user
列名采用小写下划线
如is_superuser
关于id
主键
表名_id
(优先采用)输出目标列时,不用alias,对前端人员来说,附带一个表名,会使数据库可读性更强
select user_id from user
在多表查询,关联条件时,比较清晰
select order.user_id, name, order_id from user, order where order.user_id = user.user_id
id
若需要引用某个表的
id
列,该列名还需要附带表名select user_id from order;
输出目标列时,每个都需要alias,非常麻烦!
select user.id as user_id, order.id as order_id from user, order where user.id = order.user_id
参考:
2015-10-09
要点
decimal
是使用字符存储数字的,所以不存在精度丢失问题decimal(M, N)
M说明存储数位长度(包括小数部分, 又叫精度, precision),取值范围1~65
N说明小数位数(scale, 标度),取值范围0~30,必须不大于M
参考
2015-09-30
数据库
业务逻辑实现难易程度,拓展性等跟表结构设计相关
API优雅跟SQL语句的熟练,精妙程度相关
不要为了一点性能或存储空间而增加程序或逻辑的复杂度
如用
int
来存储小数, 存储和读取都需要转换,还需要知道精度,增加复杂度,得不偿失
语言设计
- 定义重要类型的别名,如
typedef uint32_t uid_t
2015-09-30
update
当需要部分更新时,不要使用多表关联更新
因为可能部分关联失败,导致需要更新的数据没有更新
1
update product a, order b set ... where a.product_id = b.product_id
2015-09-28
备份恢复指定表
mysqldump -uwallace -pwallace stock_app t_banner_100 >stock_app.t_banner_100
mysql -uroot -pxianji -hsz003-db -P3309 stock_app <stock_app.t_banner_100
2015-09-25
要点
go
官方没有直接提供数据库驱动,而是定义了一些标准接口(database/sql
)第三方驱动通过包初始化函数
init()
调用sql.Register(name string, driver driver.Driver)
完成注册
重要类型
driver.Conn
Conn是一个数据库连接的接口定义,他定义了一系列方法,这个Conn只能应用在一个goroutine里面,不能使用在多个goroutine里面
1 | type Conn interface { |
Prepare函数返回与当前连接相关的执行Sql语句的准备状态,可以进行查询、删除等操作。
Close函数关闭当前的连接,执行释放连接拥有的资源等清理工作.
Begin函数返回一个代表事务处理的Tx,通过它你可以进行查询,更新等操作,或者对事务进行回滚、递交。
driver.Stmt
Stmt是一种准备好的状态,和Conn相关联,而且只能应用于一个goroutine中,不能应用于多个goroutine
1 | type Stmt interface { |
Close函数关闭当前的链接状态,但是如果当前正在执行query,query还是有效返回rows数据
NumInput函数返回当前预留参数的个数,当返回>=0时数据库驱动就会智能检查调用者的参数。当数据库驱动包不知道预留参数的时候,返回-1
Exec函数执行Prepare准备好的sql,传入参数执行update/insert等操作,返回Result数据
Query函数执行Prepare准备好的sql,传入需要的参数执行select操作,返回Rows结果集
driver.Tx
事务处理一般就两个过程,递交或者回滚
1 | type Tx interface { |
driver.Execer
这是一个Conn可选择实现的接口
1 | type Execer interface { |
如果这个接口没有定义,那么在调用DB.Exec,就会首先调用Prepare返回Stmt,然后执行Stmt的Exec,然后关闭Stmt。
driver.Result
这个是执行Update/Insert等操作返回的结果接口定义
1 | type Result interface { |
LastInsertId函数返回由数据库执行插入操作得到的自增ID号。
RowsAffected函数返回query操作影响的数据条目数。
driver.Rows
Rows是执行查询返回的结果集接口定义
1 | type Rows interface { |
Columns函数返回查询数据库表的字段信息,这个返回的slice和sql查询的字段一一对应,而不是返回整个表的所有字段。
Close函数用来关闭Rows迭代器。
Next函数用来返回下一条数据,把数据赋值给dest。dest里面的元素必须是driver.Value的值除了string,返回的数据里面所有的string都必须要转换成[]byte。如果最后没数据了,Next函数最后返回io.EOF。
driver.RowsAffected
RowsAffected其实就是一个int64的别名,但是他实现了Result接口,用来底层实现Result的表示方式
1 | type RowsAffected int64 |
driver.Value
Value其实就是一个空接口,他可以容纳任何的数据
1 | type Value interface{} |
drive的Value是驱动必须能够操作的Value,Value要么是nil,要么是下面的任意一种
1 | int64 |
driver.ValueConverter
ValueConverter接口定义了如何把一个普通的值转化成driver.Value的接口
1 | type ValueConverter interface { |
在开发的数据库驱动包里面实现这个接口的函数在很多地方会使用到,这个ValueConverter有很多好处:
- 转化driver.value到数据库表相应的字段,例如int64的数据如何转化成数据库表uint16字段
- 把数据库查询结果转化成driver.Value值
- 在scan函数里面如何把driver.Value值转化成用户定义的值
driver.Valuer
Valuer接口定义了返回一个driver.Value的方式
1 | type Valuer interface { |
很多类型都实现了这个Value方法,用来自身与driver.Value的转化。
使用相关
sql.Stmt
sql.DB.Prepare
返回的语句操作
1 | (s *Stmt) Exec(args ...interface{}) (Result, error) // 带参数执行prepare语句(insert, update...) |
sql.Row
QueryRow返回
,结合scan
用来获取单行查询结果