大型电商分库分表缓存策略
go的哈希标准库
shardKey := 1115 // 按店铺搜索就是店铺id, 按什么分表就用什么的id或唯一标识的哈希值
dbMax := 10 // 库数量
tabMax := 100 // 每个库的表数量
// 水平拆分到第middleVal个表
middleVal := shardKey % (dbMax * tabMax)
// 第几个数据库中的
dbNo := middleVal / tabMax
// 第几个表
tabNo := middleVal % tabMax
str := "5lp3l5rx3mqg40l8pt1gb0yw0000g"
h := fnv.New32a()
h.Write([]byte(str))
t.Logf("%v", h.Sum32())
str, err := os.Executable()
filepath.Dir(str)
fileName := "/Users/zcw/crr/go/test/aa.txt"
fp, err := os.OpenFile(fileName, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0777) // 读写方式打开
/*
os.O_CREATE|os.O_APPEND
或者 os.O_CREATE|os.O_TRUNC|os.O_WRONLY
os.O_RDONLY // 只读
os.O_WRONLY // 只写
os.O_RDWR // 读写
os.O_APPEND // 追加(Append)
os.O_CREATE // 如果文件不存在则先创建
os.O_TRUNC // 文件打开时裁剪文件
os.O_EXCL // 和O_CREATE一起使用,文件不能存在
os.O_SYNC // 以同步I/O的方式打开
*/
if err != nil {
fmt.Println("文件打开失败")
return
}
// defer延迟调用
defer fp.Close() //关闭文件,释放资源。
// 写入文件(字符串) WriteString()
count, err2 := fp.WriteString("中\r\n文\r\n")
if err2 != nil {
fmt.Println("写入文件失败:", err2)
return
}
fmt.Println("写入字节数: ", count) // 一个汉字3个字节
// 写入文件(字符切片) Write()
slice := []byte{'h', 'e', 'l', 'l', 'o', '\r', '\n'}
count, err2 = fp.Write(slice)
fmt.Println("count1:", count)
count, err2 = fp.Write([]byte("中文信息xxx")) // 强制类型转换 string-->[]byte
fmt.Println("count2:", count)
// 写入文件 从指定光标位置写入 WriteAt()
//count2, _ := fp.Seek(0, io.SeekEnd) // 计算文件起始位置和末尾之间的字符数(文件大小)。
count, _ = fp.WriteAt([]byte("从指定光标位置开始写入"), 3) // 从指定光标位置开始写入
fmt.Println("count3:", count)
func TestReflect(t *testing.T) {
type A struct {
Name string
Age int
}
x1 := A{Name: "BJJ", Age: 112}
x2 := A{Name: "NMW", Age: 1112}
v1 := reflect.ValueOf(&x1).Elem() // 去指针化: 为了能够修改该变量的值需要传入他的指针, 并绕过指针
v2 := reflect.ValueOf(&x2).Elem()
t1 := v1.Type()
for i := 0; i < v1.NumField(); i++ {
f1 := v1.Field(i) // 迭代结构体中的各个域
f2 := v2.Field(i)
fmt.Printf("%v: %v %v = %v\n", i, t1.Field(i).Name, f1.Type().Name(), f1.Interface())
if v1.Field(i).CanSet() {
switch f1.Type().Name() {
case "string":
v1.Field(i).SetString(f2.Interface().(string))
case "int":
v1.Field(i).SetInt(int64(f2.Interface().(int)))
}
//v1.Field(i).SetPointer()
//v1.Field(i).SetFloat()
//v1.Field(i).SetBool()
//v1.Field(i).SetBytes()
//v1.Field(i).SetCap()
//v1.Field(i).SetLen()
//v1.Field(i).SetUint()
//v1.Field(i).SetComplex()
//v1.Field(i).SetMapIndex()
//v1.Field(i).CanSet()
}
fmt.Printf("%v: %v %v = %v\n", i, t1.Field(i).Name, f1.Type(), f1.Interface())
}
/*
0: Name string = BJJ
0: Name string = NMW
1: Age int = 112
1: Age int = 1112
*/
}
// 创建目录
err = os.MkdirAll(fullSaveDir, os.ModePerm)
if err != nil {
return
}
// 创建文件
osFile, _ := os.Create(fullSavePath)
defer osFile.Close()
f, _ := file.Open() // var file *multipart.FileHeader
// 写入内容
io.Copy(osFile, f)