簡體   English   中英

Postgres SQL中的字符串字段長度

[英]String field length in Postgres SQL

我在SQL數據庫中提交了一個字符串,表示一個URL。 有些網址很短,有些很長。 我真的不知道waht是我可能遇到的最長的URL,所以為了安全起見,我會采用一個很大的值,比如256或512。

當我定義最大字符串長度時(例如使用SQLAlchemy):

url_field = Column(String(256))

這是否占用每行的空間(存儲),即使實際的字符串更短?

我假設這與實現細節有關。 我正在使用postgreSQL,但我也對sqlite,mysql感興趣。

在PostgreSQL中, character(n)基本上只是varchar ,輸入/輸出上有空格填充。 它很笨拙,應該避免。 它使用與varchartext字段相同的存儲空間,並將其填充到最大長度(見下文)。 char(n)是一個歷史性的疣,應該避免 - 至少在PostgreSQL中它沒有任何優勢,並且有一些奇怪的怪癖,比如left(...)

varchar(n)varchartext都使用相同的存儲 - 你提供的字符串的長度沒有填充。 它只使用字符實際需要的存儲空間,而不管長度限制。 此外,如果字符串為null,PostgreSQL根本不存儲它的值(甚至不是長度頭),它只是在記錄的空位圖中設置空位。

合格的varchar(n)與非限定的varchar基本相同,並且length(colname) < ncheck約束。

盡管其他一些評論/答案都在說, char(n)varcharvarchar(n)text都是TOASTable類型。 它們都可以存儲在線外和/或壓縮。 要控制存儲,請使用ALTER TABLE ... ALTER COLUMN ... SET STORAGE

如果您不知道所需的最大長度,只需使用text或unqualified varchar 沒有空間罰款。

有關更多詳細信息,請參閱有關字符數據類型的文檔 ,以及有關如何存儲它們的一些內容,請參閱特別是TOAST的 數據庫物理存儲

演示:

CREATE TABLE somechars(c10 char(10), vc10 varchar(10), vc varchar, t text);
insert into somechars(c10) values ('  abcdef ');
insert into somechars(vc10) values ('  abcdef ');
insert into somechars(vc) values ('  abcdef ');
insert into somechars(t) values ('  abcdef ');

為每個col輸出此查詢:

SELECT 'c10', pg_column_size(c10), octet_length(c10), length(c10) 
from somechars where c10 is not null;

是:

 ?column? | pg_column_size | octet_length | length 
 c10      |             11 |           10 |      8
 vc10     |             10 |            9 |      9
 vc       |             10 |            9 |      9
 t        |             10 |            9 |      9

pg_column_size是字段中數據的磁盤大小。 octet_length是沒有標題的未壓縮大小。 length是“邏輯”字符串長度。

正如您所看到的, char字段是填充的。 雖然輸入是9個字符而不是8個字符,但是它也浪費了空間,它也給出了length非常令人驚訝的結果。那是因為Pg無法區分你自己放置的前導空格和它添加的前導空格之間的區別填充。

所以,不要使用char(n)

順便說一句,如果我正在設計數據庫,我從不使用varchar(n)char(n) 我只是使用text類型並添加適當的check約束,如果有值的應用程序要求。 我認為varchar(n)在標准中有點像疣,但我認為它對於具有磁盤布局的DB很有用,其中大小限制可能會影響存儲。

postgreSQL,sqllite和mysql都應用sql標准來存儲varchar和chars。 這是基本的:

SQL定義了兩種主要字符類型:字符變化(n)和字符(n),其中n是正整數。 這兩種類型都可以存儲長度最多為n個字符的字符串。 嘗試將較長的字符串存儲到這些類型的列中將導致錯誤,除非多余的字符都是空格,在這種情況下,字符串將被截斷為最大長度。 (這個有點奇怪的異常是SQL標准所要求的。)如果要存儲的字符串比聲明的長度短,則字符類型的值將被空格填充; 類型字符變量的值將只存儲較短的字符串。

如果顯式地將值轉換為字符變量(n)或字符(n),則超長值將被截斷為n個字符而不會引發錯誤。 (這也是SQL標准所要求的。)

符號varchar(n)和char(n)分別是字符變化(n)和字符(n)的別名。 沒有長度說明符的字符等同於字符(1)。 如果在沒有長度說明符的情況下使用字符變化,則該類型接受任何大小的字符串。 后者是PostgreSQL擴展。

參考:

通常,數據庫存儲引擎可以做很多你不期望的事情。 但基本上,有兩種文本字段,它們提示內部會發生什么。

char和varchar。 Char將為您提供固定的字段列,並且根據sql會話中的選項,您可能會收到空格填充的字符串。 Varchar用於最大長度的文本字段。

Varchar字段可以存儲為塊外部的指針,以便塊在查詢上保持可預測的大小 - 但這是一個實現細節,可能因db而異。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM