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

2018-07-01 13:40:36 +08:00
 victorwu34

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

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

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

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

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

另外结束前多说一点:
有些极端情况,如大位图、音视频这些情况,特点是特大批量数据,这个时候二进制的位密度和性能优势就体现出来了。
CDuXZMAPgHp1q9ew
2018-07-01 14:50:39 +08:00
doubleflower
2018-07-01 17:46:49 +08:00
@iwtbauh UUID 上用文本可不是使用了 8bit 中的 7bit,浪费掉一半的内存呢
特别是用在主键上时浪费巨大
gabon
2018-07-01 18:27:10 +08:00
高性能 MySQL 书里有提到这个问题
victorwu34
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
2018-07-01 22:11:08 +08:00
@iwtbauh 不同字节序机器什么时候需要考虑?调试困难编写专用工具是什么样的工具?
honeycomb
2018-07-01 22:38:40 +08:00
@victorwu34

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

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

专用工具:假设你要存放一些配置数据,如果是二进制 blob,你很难直接查看 /修改数据,必须为这种 blob 格式编写专用工具,但是文本就可以很轻易的看到,如果要修改的话,只需要一个文本编辑器(存放在文件)或者一行 sql (数据库)。考虑 HTTP 协议。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/467224

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX