我的数据库中已经有几百万行了。我在设计模式时不知道 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 列不起作用。
我不是任何想像力的 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 个。系统会自动压缩长字符串,因此对磁盘的物理要求可能会更少。