(var)char作为性能列的类型?

时间:2014-04-08 15:55:53

标签: performance postgresql types normalization postgresql-9.2

我有一个名为" status"在PostgreSQL中。首先它曾经是" status_id"类型为integer。这些值保存在客户端上,因此服务器上有 no 表名为status,我保留这些状态,然后使用第一个表inner join

我曾经从客户端发送状态的ID(他们在客户端上有名字)。但是,在某些时候我理解我最好让服务器保持这些状态。不是在单独的表中,而是在第一个表中,我想让它们成为字符串。因此,初始表将具有类型为字符串status的{​​{1}}列,以便更具体。我读过它不会那么慢。

总的来说,这是一个好主意吗?我想这是因为每次执行varchar(以及我在单独的表中保持状态)都是昂贵的以及从客户端发送ID。

1)我唯一担心的是inner join列应该是status类型,而不是char。它应该使我认为更有效。是这样吗?

2)如果第一种情况是正确的,那么我不确定我是否能够使用完全相同数量的字符来命名所有状态,例如,5个字符。其中一些可能更长,一些更短。我该如何解决这个问题?

更新

这不是非国籍化,因为我在谈论一张单人桌。没有,也从来没有第二个名为Statuses的表,其中包含字段(id,status_name)。

我想传达的是我可以将char(n)用于status_name并在其上添加索引。然后它应该足够快。但是,可能或不可能将所有状态命名为特定(n)个字符,这是唯一的问题。

2 个答案:

答案 0 :(得分:1)

我不这么认为使用char或varchar而不是整数是个好主意。很难想象它会比整数PK慢多少,但这种设计会更慢 - 当你加入更大的表时,影响会更加糟糕。如果可以,请改用ENUM类型。

http://www.postgresql.org/docs/9.2/static/datatype-enum.html

CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');

CREATE TABLE person (
    name text,
    current_mood mood
);
INSERT INTO person VALUES ('Moe', 'happy');
SELECT * FROM person WHERE current_mood = 'happy';
 name | current_mood 
------+--------------
 Moe  | happy
(1 row)

PostgreSQL varchar和char类型非常相似。内部实现是相同的 - 由于空格的增加,char可以(它是悖论)稍慢一点。

答案 1 :(得分:1)

我更进一步。 从不使用过时的数据类型char(n),除非您知道必须(出于兼容性或一些罕见的异国情况)。在现代数据库中,这种类型完全没用。填充带有空白字符的字符串是无稽之谈,如果来执行此操作,则可以使用rpad()以更便宜的方式进行数据检索。

SELECT rpad('short', 10) AS char_10_string;

varchartext基本相同,并且允许使用长度说明符:varchar(n)。我通常只使用text。如果我需要限制长度,我使用CHECK约束。 Here's one example, why.

每当您可以使用简单的integer(或enum)时,在各个方面都会更小更快。对于enum,请考虑@Pavel's answer

至于:

  

因为每次执行inner join(...)都很昂贵

嗯,它的成本很低,但它通常比冗余保存状态的文本表示更便宜,而不是主表中更便宜的整数。有些人在理解database normalization的概念时会传播这种谣言。 enum类型在这里是一种妥协 - 对于相对静态的值集。