2017-05-08 300 views
2

目前我使用GO-格姆我所有的數據庫查詢(主要是CRUD)的,我有一些問題,將生成的UUID到MySQL數據庫列。GORM UUID太長

的柱是BINARY(16)如在多個博客的建議,使用github.com/satori/go.uuid包Golang生成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如下:當我從格姆得到的錯誤:

(Error 1406: Data too long for column 'user_id' at row 1)

我也有fmt.Println(UUID)看到的結果,他們也如下(obviosuly的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並將它們轉換爲二進制以插入類似的結果。

+0

也許愚蠢的問題,但爲什麼你使用'user_id'二進制?爲什麼你使用類似https://en.wikipedia.org/wiki/Universally_unique_identifier的內容? – pregmatch

+0

我可以在這裏http://stackoverflow.com/questions/15130321/is-there-a-method-to-generate-a-uuid-with-go-language看到,真的很容易產生。 – pregmatch

+0

我總是使用它,但我最好的猜測都依賴於數據庫。我可以看到你有'id',然後'user_id',爲什麼你有'user_id'呢? – pregmatch

回答

2

我認爲這個問題是在模型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「誤解」的字段作爲字符串,然後插入串入數據庫二進制文件。例如,下面的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其是

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

其在長度36字節的ASCII碼,因而你得到Error 1406: ...