V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
victorwu34
V2EX  ›  Java

UUID 在数据库中存为二进制的好处

  •  2
     
  •   victorwu34 · 2018-07-01 13:40:36 +08:00 · 6114 次点击
    这是一个创建于 2370 天前的主题,其中的信息可能已经有所发展或是发生改变。

    项目用的数据库是 mysql,把字段 UUID 定义成 type binary,length 16,这样是怎么理解呢?在 debug 时候相当麻烦,这个 uuid 字段都是 join 时候用,所以用眼睛去找 join 两边的对应行很麻烦,测试时候数据量小的时候可以看哪个二进制长得像。

    1. 二进制因为性能吗,二进制的快?
    2. 还是唯一性?(这个没理解,团队人说的)
    3. 还是封装性好?因为 uuid 本来就不是给人读的。
    15 条回复    2018-07-01 23:01:05 +08:00
    whileFalse
        1
    whileFalse  
       2018-07-01 13:52:00 +08:00
    1 + 3
    FrailLove
        2
    FrailLove  
       2018-07-01 14:21:36 +08:00
    占内存会比 char 少
    zjp
        3
    zjp  
       2018-07-01 14:22:14 +08:00 via Android
    UUID 的唯一性和存储格式有什么关系…
    victorwu34
        4
    victorwu34  
    OP
       2018-07-01 14:36:43 +08:00
    @FrailLove 是 mysql 运行时的内存吗
    victorwu34
        5
    victorwu34  
    OP
       2018-07-01 14:36:57 +08:00
    @whileFalse 什么意思
    victorwu34
        6
    victorwu34  
    OP
       2018-07-01 14:37:46 +08:00
    @zjp 不知道啊
    binux
        7
    binux  
       2018-07-01 14:41:43 +08:00
    你转一下不就行了
    iwtbauh
        8
    iwtbauh  
       2018-07-01 14:41:56 +08:00 via Android   ❤️ 7
    这里使用 binary 是合理,但原因不是性能。
    性能上,节省的微乎其微,这是一个过度优化的陷阱
    位密度上,文本仍然使用了 8bit 中的 7bit

    使用文本而不是用 binary 的情况通常是:
    1. 扩展问题,二进制格式一旦确定了,就没法再增加长度,如果一个数据字段只能存放 16bit,那么如果要扩展它是非常非常痛苦的,但是对于文本格式直接写就可以了。
    2. 字节序问题,二进制数使程序必须考虑大端序和小端序机器的问题,尤其是需要在不同的机器上通信时。如果不考虑的话程序将无法在网络上协同工作,并且是非常脆弱的(考虑程序有一天需要放到另一个不同字节序机器上运行)。
    3. 透明性,二进制数据破坏透明性,使调试变得困难,需要编写专用工具处理(文本格式一般可以直接用一个编辑器)。

    但是在这个 uuid 的例子中,1,2,3 都不成立,uuid 长度固定不变,字节序问题也不需要考虑,透明性也可以算作不用考虑。

    因此使用文本的好处就不是很明显了。

    另外结束前多说一点:
    有些极端情况,如大位图、音视频这些情况,特点是特大批量数据,这个时候二进制的位密度和性能优势就体现出来了。
    doubleflower
        10
    doubleflower  
       2018-07-01 17:46:49 +08:00
    @iwtbauh UUID 上用文本可不是使用了 8bit 中的 7bit,浪费掉一半的内存呢
    特别是用在主键上时浪费巨大
    gabon
        11
    gabon  
       2018-07-01 18:27:10 +08:00 via Android
    高性能 MySQL 书里有提到这个问题
    victorwu34
        12
    victorwu34  
    OP
       2018-07-01 22:00:33 +08:00
    @gabon 里面这么说的,If you do store UUID values, you should remove the dashes or, even better, convert the
    UUID values to 16-byte numbers with UNHEX() and store them in a BINARY(16) column.
    You can retrieve the values in hexadecimal format with the HEX() function
    victorwu34
        13
    victorwu34  
    OP
       2018-07-01 22:11:08 +08:00
    @iwtbauh 不同字节序机器什么时候需要考虑?调试困难编写专用工具是什么样的工具?
    honeycomb
        14
    honeycomb  
       2018-07-01 22:38:40 +08:00 via Android
    @victorwu34

    使用 bin 的时候 UUID 字段占 16 字节,使用 char 时(用 string 表达的 hex )应该是 32 字节( UTF8 里 ASCII 字符是双字节)。

    mongodb 的主 id 也只用了 12 字节
    iwtbauh
        15
    iwtbauh  
       2018-07-01 23:01:05 +08:00 via Android
    @victorwu34
    字节序:字节序问题经常出现在 int 类型等类型的机器表示,CPU 通常只能处理一种字节序,考虑这种情况,在大端 CPU 上的一个程序有一个 int 变量,程序如果将这个内存中的 int 按照原有字节序直接存在某个地方,然后另一个小端 CPU 上运行的程序读取这个二进制值并赋值给 int 变量。这两个 int 值几乎不可能相同!因此程序必须能够理解字节序并且自己处理字节序转换问题。例如,在网络编程中,规定字节序为大端字节序,因此在小端机器上的网络应用程序必须自己将值(例如端口号)转换为大端字节序发送,接收数据包还要自己转换为小端序。而文本是没有字节序的。(某些编码有,如 UCS-2 有,但其实上,常用编码如 ASCII,UTF-8 等没有)

    专用工具:假设你要存放一些配置数据,如果是二进制 blob,你很难直接查看 /修改数据,必须为这种 blob 格式编写专用工具,但是文本就可以很轻易的看到,如果要修改的话,只需要一个文本编辑器(存放在文件)或者一行 sql (数据库)。考虑 HTTP 协议。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3097 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 13:42 · PVG 21:42 · LAX 05:42 · JFK 08:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.