【问题标题】:How can I store binary data in MySQL?如何在 MySQL 中存储二进制数据?
【发布时间】:2013-11-22 02:34:55
【问题描述】:

我正在使用来自 http://github.com/go-sql-driver/mysql 的 MySQL 驱动程序

我需要将 MySQL 中 IP 地址的二进制表示形式存储在 BINARY(4) 列中。

为此,我已经尝试过:

    startSlice := net.ParseIP(rangeStart).To4()
    var startBytes [4]byte
    copy(startSlice[:], startBytes[0:4])

    endSlice := net.ParseIP(rangeEnd).To4()
    var endBytes [4]byte
    copy(endSlice[:], endBytes[0:4])

    r, e := db.Exec("UPDATE AIPRangesBlocks SET BinRangeStart = ?, BinRangeEnd = ? WHERE IPGRID = ?", startBytes, endBytes, id)
    fmt.Println("result of update:", r)
    if e != nil {
        fmt.Println(e)
    }

请注意,我使用复制命令将 []byte 切片转换为 [4]byte 数组,但出现此错误:

sql: converting Exec argument #0's type: unsupported type [4]uint8, a array

如果我直接作为 net.ParseIP("some_ip").To4() 执行此操作,则会收到此错误:

sql: converting Exec argument #0's type: unsupported type net.IP, a slice

如何发送二进制数据?

如果我使用十六进制字符串,它将执行查询,但我在检索时没有得到正确的值。

我试过 hex.EncodeToString() 和 "0x" + hex.EncodeToString() 都没有正常工作。

这是一个例子:

66.182.64.0 becomes 42b64000

如果我在我的 MySQL 列中存储“42b64000”,我会返回:

52 50 98 54

如果我在我的 MySQL 列中存储“0x42b64000”,我会返回:

48 120 52 50

我该如何解决这个问题?

【问题讨论】:

    标签: mysql go


    【解决方案1】:

    如果您在我的 MySQL 列中存储“42b64000”,您会返回:

    52 50 98 54
    

    解码成 ASCII 这是你给它的字符串的开头,例如

    "42b6"
    

    这表明将 IP 地址切片作为字符串传递会起作用,例如

    startSlice := net.ParseIP(rangeStart).To4()
    endSlice := net.ParseIP(rangeEnd).To4()
    r, e := db.Exec("UPDATE AIPRangesBlocks SET BinRangeStart = ?, BinRangeEnd = ? WHERE IPGRID = ?", string(startSlice), string(endSlice), id)
    fmt.Println("result of update:", r)
    if e != nil {
        fmt.Println(e)
    }
    

    Go 中的字符串本质上是[]byte 的只读版本,您可以毫无问题地在它们之间进行转换(除了一些内存复制)。希望 MySQL 驱动程序中的引用可以处理字符串中的 NUL。

    【讨论】:

      【解决方案2】:

      您可以尝试将其存储为 uint32 与 encoding/binary: binary.LittleEndian.Uint32(net.ParseIP(rangeStart).To4())binary.LittleEndian.PutUint32(destinationSlice, colValue)。 如果LittleEndian 为您的其他应用程序提供了错误的结果,请改用BigEndian

      【讨论】:

        【解决方案3】:

        您可以将其转换为 HEX 字符串。

        这是我解决它的方法(适用于 IPv4 和 IPv6):

        1. 假设您的表是:

        创建表 ip_addr (ip VARBINARY(16));

        1. 按如下方式准备 INSERT 或 UPDATE 语句:

        stmt := db.Prepare("INSERT INTO ip_addr (ip) VALUES (UNHEX(?))")

        1. 在“Go”代码中:
         if ip.To4() != nil {
                        ip_hex = hex.EncodeToString(ip.To4())
         } else {
                        ip_hex = hex.EncodeToString(ip.To16())
         }
         stmt.Exec(ip_hex)
        

        【讨论】:

          猜你喜欢
          • 2010-11-09
          • 1970-01-01
          • 1970-01-01
          • 2017-06-23
          • 2021-06-13
          • 1970-01-01
          • 2010-10-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多