我有一个名为" 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)个字符,这是唯一的问题。
答案 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;
varchar
与text
基本相同,并且允许使用长度说明符:varchar(n)
。我通常只使用text
。如果我需要限制长度,我使用CHECK
约束。 Here's one example, why.
每当您可以使用简单的integer
(或enum
)时,在各个方面都会更小更快。对于enum
,请考虑@Pavel's answer。
至于:
因为每次执行
inner join
(...)都很昂贵
嗯,它的成本很低,但它通常比冗余保存状态的文本表示更便宜,而不是主表中更便宜的整数。有些人在理解database normalization的概念时会传播这种谣言。 enum
类型在这里是一种妥协 - 对于相对静态的值集。