首页 文章

GORM UUID太长了

提问于
浏览
2

目前我正在使用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 回答

  • 1

    我认为问题出在模型 User 的定义中 . 要将GUID保存为16字节二进制文件,需要将 UserID 列定义为 []byte 而不是uuid.UUID .

    type User struct {
        //other fields ..
        UserID    []byte
    
        //other fields ...
    }
    
    func (u *User) BeforeCreate(scope *gorm.Scope) (err error) {
        if u.UserID == nil {
            uuid, err := uuid.NewV4().MarshalBinary()
            scope.SetColumn("user_id", uuid)
        }
        return nil
    }
    

    如果将字段定义为 uuid.UUIDgorm "misinterpreted"字段为字符串,然后将该字符串作为二进制文件插入数据库 . 例如,以下UUID,

    uuid: 16ac369b-e57f-471b-96f6-1068ead0bf98
    //16-bytes equivalent
    bytes: [22 172 54 155 229 127 71 27 150 246 16 104 234 208 191 152]
    

    将作为UUID的ASCII码插入数据库

    0x31 0x36 0x61 0x63 0x33 0x36 0x39 0x62 0x2D 0x65 ...
    ('1' '6'  'a'  'c'  '3'  '6'  '9'  'b'  '-'  'e'  ...)
    

    这是36个字节的长度,因此你得到 Error 1406: ...

相关问题