2014-09-03 50 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