2014-09-03 53 views
1

有点理论上的问题。数据库优化 - 编码字段

只是想知道有没有一种方法来优化数据字段?

说一个给定的字段,你只有3个可能的字符串,但这些字符串由于某种原因很长(比如说50个字符),声明字段为character_varying(50)看起来像浪费了很多磁盘空间,因为数据本质上会适合在2位上。

我想你可以通过加入标签表来解决问题,但有没有另一种更正确的方法或数据库能够自动优化这种类型的列?

常见的数据库能够处理自己的那种优化吗? 有没有办法在数据库中声明这种结构(类似于R语言因子概念)? Postgresql域结构是否有助于优化?

某些背景:

在你认为这是一个愚蠢的问题之前。我一直在使用旧的遗留系统(90年代早期),其中一切都进行了大量编码以节省内存和性能(例如,性将被编码(1,2)而不是(男性,女性)以及许多不太明显的编码)。

现在我们正在将系统移动到更现代化的数据库(postgresql),希望我们能够使用可读的“纯文本”字段。

我并不是真的担心实际的表现。更多的是一个理论问题。

+0

作为一个理论问题,这实际上是关于列约束。可以使用普通的CHECK约束或用户定义的类型或DOMAIN。你也可以将这些域分割成单独的表格(甚至可以使用类似EAV的模型) – wildplasser 2014-09-03 10:09:41

回答

0

PostgreSQL的enums (enumerations)就是这个。

CREATE TYPE sex AS ENUM ('male', 'female', 'intersex', 'unspecified'); 

(是的,我正在做一个点在这里我举的例子,应用程序开发人员仍然迫使二元性别选择需要与线索棒,硬的冲击。同样的,那些谁混淆了“性”(生物)和“性别”(社会学)。)

枚举的主要限制是它们必须包含name,而不是任意长度的字符串,并且不能删除值,只能追加/插入它们。在所有标准PostgreSQL版本中,NAMEDATALEN设置为63字节。所以,你没有得到使用字符串:

regress=> CREATE TYPE long AS ENUM ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'); 
ERROR: invalid enum label "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 
DETAIL: Labels must be 63 characters or less. 

枚举在内部编码为int4值:

regress=> SELECT pg_column_size('female'::sex); 
pg_column_size 
---------------- 
       4 
(1 row) 

所以它实际上更紧凑来存储"char"

select pg_column_size('m'::"char"); 

如果您不介意丢失自我记录可靠性以及无法独立于值指定排序顺序。 "char"是1字节固定大小字符值的PostgreSQL扩展,并且必须始终使用引号将其与SQL标准character类型(可缩写为char)区分开来。

+0

非常感谢,正是我需要的。 – 2014-09-03 10:03:00

1

我想你要找的,你必须明确创建“枚举”数据类型,将数据保存为一个整数,但它转换为字符串在SELECT

例如

CREATE TYPE my_specific_text_field AS ENUM 
(
'string one with longish text', 
'second string with fairly long text', 
'third string' 
); 

CREATE TABLE test (
id serial not null primary key, 
myenum my_specific_text_field 
); 

INSERT INTO test (myenum) VALUES ('string one with longish text'); 

也就是说,枚举可能有些麻烦,如果您不熟悉它们,出口枚举可能会非常棘手,也相信他们的长度为63个字节的上限。

+1

谢谢你们,看起来正是我在找的东西。 – 2014-09-03 10:00:24