目前我正在使用GO-GORM进行所有数据库查询(主要是CRUD),并且在将生成的UUID插入MySQL数据库列时遇到了一些问题 .
该列是多个博客中建议的BINARY(16),UUID是使用Golang的github.com/satori/go.uuid包生成的 .
我正在使用GORM的BeforeCreate挂钩生成UUID,如果用户尚不存在,我使用的代码如下:
func (u *User) BeforeCreate(scope *gorm.Scope) (err error) {
if u.UserID == uuid.Nil {
uuid, err := uuid.NewV4().MarshalBinary()
scope.SetColumn("user_id", uuid)
}
}
我也用len来获得MarshalBinary输出的长度,它返回16 .
尝试将UUID插入MySQL时,我从GORM获得的错误如下:
(Error 1406: Data too long for column 'user_id' at row 1)
我还有fmt.Println(uuid)来查看结果,它们也如下所示(每次插入时都会生成UUID,因此会发生变化)
[93 132 59 55 102 96 72 35 137 185 34 21 195 88 213 127]
我的MYSQL架构如下:
CREATE TABLE users
(
id INT(10) unsigned PRIMARY KEY NOT NULL AUTO_INCREMENT,
created_at TIMESTAMP,
updated_at TIMESTAMP,
deleted_at TIMESTAMP,
user_id BINARY(16) NOT NULL,
username VARCHAR(255) NOT NULL,
password VARCHAR(255),
firstname VARCHAR(255),
lastname VARCHAR(255),
email VARCHAR(255),
address_id VARCHAR(255)
);
CREATE INDEX idx_users_deleted_at ON users (deleted_at);
CREATE UNIQUE INDEX username ON users (username);
CREATE UNIQUE INDEX user_id ON users (user_id);
我已经尝试了不同的方法和库来生成UUID并将它们转换为二进制以插入具有类似结果 .
1 回答
我认为问题出在模型
User
的定义中 . 要将GUID保存为16字节二进制文件,需要将UserID
列定义为[]byte
而不是uuid.UUID .如果将字段定义为
uuid.UUID
,gorm
"misinterpreted"字段为字符串,然后将该字符串作为二进制文件插入数据库 . 例如,以下UUID,将作为UUID的ASCII码插入数据库
这是36个字节的长度,因此你得到
Error 1406: ...