我应该花时间将列类型从 CHAR(36) 更改为 UUID 吗?

Fra*_*eil 14 postgresql

我的数据库中已经有几百万行了。我在设计模式时不知道 PostgreSQL UUID 数据类型。

其中一个表有 1600 万行(每个分片大约有 350 万到 400 万条记录),每天增长大约 50 万条记录。如果需要,我仍然可以将生产系统关闭几个小时。一两周内我不会有这种奢侈。

我的问题是,这样做是否值得?我想知道 JOIN 性能、磁盘空间使用(完整的 gzip 转储是 1.25 GiB),以及这种性质的事情。

表架构是:

# \d twitter_interactions
                Table "public.twitter_interactions"
         Column          |            Type             | Modifiers 
-------------------------+-----------------------------+-----------
 interaction_id          | character(36)               | not null
 status_text             | character varying(1024)     | not null
 screen_name             | character varying(40)       | not null
 twitter_user_id         | bigint                      | 
 replying_to_screen_name | character varying(40)       | 
 source                  | character varying(240)      | not null
 tweet_id                | bigint                      | not null
 created_at              | timestamp without time zone | not null
Indexes:
    "twitter_interactions_pkey" PRIMARY KEY, btree (interaction_id)
    "twitter_interactions_tweet_id_key" UNIQUE, btree (tweet_id)
    "index_twitter_interactions_on_created_at" btree (created_at)
    "index_twitter_interactions_on_screen_name" btree (screen_name)
Triggers:
    insert_twitter_interactions_trigger BEFORE INSERT ON twitter_interactions FOR EACH ROW EXECUTE PROCEDURE twitter_interactions_insert_trigger()
Number of child tables: 9 (Use \d+ to list them.)
Run Code Online (Sandbox Code Playgroud)

Pet*_*aut 13

我会考虑更改为 UUID 类型。 char(36)占用 40 个字节,uuid占用 16个字节,因此每行将节省 24 个字节,这相当于每天 12 MB,一年后节省 4 GB。加上索引。根据您拥有的硬件,这并不多,但可能是。如果你有更多这样的改进机会,它就会加起来。

此外,我在您的架构中没有看到任何约束,以确保它interaction_id实际上采用正确的格式。使用正确的类型也会给你。

但是,如果您喜欢这样,那么使用它bigint会节省更多并具有更好的性能。您的应用程序不太可能太大以致bigint于 ID 列不起作用。

  • @FrançoisBeausoleil,为节点 ID 保留 N 位等于使用序列中的每个第 N 个数字(因此易于实现)。此外,您可能会考虑使用复合键。 (3认同)

bil*_*nkc 6

我不是任何想像力的 postgres 人,但根据我从 SQL Server 中了解到的信息,数据页上可以容纳的行越多,性能就越好(从磁盘读取数据通常是最昂贵的操作)。因此,从 36 ish 1字节宽的字段到 16 字节GUID似乎可以直接节省成本。发生的读取越少,返回结果的速度就越快。当然,所有这些都假设 GUID/UUID 满足表的业务需求。如果 UUID 满足它,那么bigint 会吗?这将进一步减少每行 8 个字节的存储成本。

编辑1

对于Postgres 中的字符数据,它们有额外的存储成本。127 字节以下的短字符串有 1 字节的开销,而任何更长的字符串都有 4 字节,这就是第二个响应者为 36 字节字段提出 40 字节成本的原因。但是还有一个字符串压缩选项,所以它可能不会花费全部 40。我不知道最终成本是多少,但基本原理仍然存在:超过 16 字节的任何内容都会增加存储成本,需要更长的时间来读取并消耗更多内存。

短字符串(最多 126 个字节)的存储要求是 1 个字节加上实际字符串,其中包括字符情况下的空格填充。较长的字符串有 4 个字节的开销,而不是 1 个。系统会自动压缩长字符串,因此对磁盘的物理要求可能会更少。