create table user_info
(
email_hash CHAR(64) NOT NULL,
token CHAR(32) NOT NULL,
timestamp INT NOT NULL,
attentions VARCHAR(10000),
PRIMARY KEY (email_hash),
INDEX (token)
) DEFAULT CHARSET = ascii;
而关于这个长度上限为 10000 的字符串 attentions 的核心解析如下:
func charToInt(c int) int {
if c <= '9' {
return c - int('0')
} else {
return c - int('a') + 10
}
}
func hexToIntSlice(str string) []int {
rtn := make([]int, len(str)/8)
res := int(0)
for i, r := range str {
res = res + charToInt(int(r))<<(4*(7-(i%8)))
if (i+1)%8 == 0 {
rtn[i/8] = res
res = 0
}
}
return rtn
}
func intSliceToHex(array []int) string {
var rtn string
for _, n := range array {
rtn += fmt.Sprintf("%08x", n)
}
return rtn
}
潜在风险
如果我没理解错的话,这个设定有以下问题:
在没有必要用 VARCHAR 的场合使用它,对数据库空间利用率不高;
在查询、添加关注时,都需要对 attentions 字符串进行遍历与解析,效率不高;
当前树洞已经有近四千条,不出几日即可达到万规模,而这个设定下最多仅能容纳 1250 条,且用的是栈式结构,如果数据库用的是 mysql 的 ANSI 模式,将会在第 1251 个关注时由于记录截断而出现关注失败的情况。
涉及代码
从
init_db.sql
可以看到user_info
的attentions
字段的的定义如下:而关于这个长度上限为 10000 的字符串 attentions 的核心解析如下:
潜在风险
如果我没理解错的话,这个设定有以下问题:
建议