Также имейте в виду, что при сравнении индексов часто очень большая разница между CHAR и VARCHAR
Это применимо / все еще применяется к Postgres?
Я обнаружил, что в Oracle есть страницы, в которых утверждается, что CHARэто более или менее псевдоним, VARCHARи поэтому производительность индекса одинакова, но я не нашел ничего определенного в Postgres.
CHARи VARCHARреализованы точно так же в Postgres (и Oracle). Нет разницы в скорости при использовании этих типов данных.
Однако есть одно отличие, которое может повлиять на производительность: charстолбец всегда дополняется до определенной длины. Таким образом, если вы определяете столбец как char(100)и один как, varchar(100)но сохраняете только 10 символов в каждом, char(100)столбец использует 100 символов для каждого значения (10 сохраненных символов плюс 90 пробелов), тогда как в varcharстолбце хранится только 10 символов.
Сравнение 100 символов с 100 символами будет медленнее, чем сравнение 10 символов с 10 символами - хотя я сомневаюсь, что вы действительно можете измерить эту разницу в запросе SQL.
Если вы объявляете оба с длиной 10 символов и всегда сохраняете в них ровно 10 символов, то нет абсолютно никакой разницы (это верно для Oracle и Postgres)
Таким образом, единственное отличие - это заполнение, которое делается для charтипа данных.
Также имейте в виду, что при сравнении индексов часто очень большая разница между CHAR и VARCHAR
Приведенная выше цитата верна только в том случае, если (и только если) charстолбец определен слишком широко (т. Е. Вы тратите пространство из-за заполнения). Если длина charстолбца всегда используется полностью (поэтому заполнение не происходит), приведенная выше цитата неверна (по крайней мере, для Postgres и Oracle)
С моей точки зрения, charтип данных на самом деле не имеет никакого реального использования слова. Просто используйте varchar(или textв Postgres) и забудьте, что charсуществует.
Сравнение 100 символов с 100 символами будет медленнее, чем сравнение 10 символов с 10 символами - хотя я сомневаюсь, что вы действительно можете измерить эту разницу в запросе SQL. - В зависимости от того, что делает запрос в дополнение к сортировке, разница может быть огромной. Вот почему в Postgres 9.5 появилась новая функция «сокращенных ключей»: pgeoghegan.blogspot.de/2015/01/…
chirlu
6
Я согласен со всем, что говорит a_horse_with_no_name, и в целом согласен с комментарием Эрвина:
Нет, чарс уступает (и устарел). текст и varchar выполняют (почти) одно и то же.
Метаданные
За одним небольшим исключением, я использую только один раз char(), когда я хочу, чтобы метаданные сказали, что это ДОЛЖНО иметь x-символы. Хотя я знаю, что char()жалуется , только если входное значение превышает предел, я буду часто защищать от недогрузок в CHECKограничении. Например,
CREATETABLE foo (
x char(10)CHECK( length(x)=10));INSERTINTO foo VALUES(repeat('x',9));
Я делаю это по нескольким причинам,
char(x)иногда определяется загрузчиками схемы как столбец с фиксированной шириной. Это может иметь значение в языке, который оптимизирован для строк фиксированной ширины.
Он устанавливает соглашение, которое имеет смысл и легко исполняется. Я могу написать загрузчик схемы на языке, чтобы сгенерировать код из этого соглашения.
Нужен пример, где я могу это сделать,
Двухбуквенные сокращения состояний, хотя этот список можно перечислить, я обычно делаю это с помощью ENUM.
Обратите внимание, что некоторым людям может быть неудобно из-за несоответствия сообщений об ошибках по обе стороны предела, но меня это не беспокоит
test=#INSERTINTO foo VALUES(repeat('x',9));
ERROR: new rowfor relation "foo" violates checkconstraint"foo_x_check"
DETAIL: Failing rowcontains(xxxxxxxxx ).
test=#INSERTINTO foo VALUES(repeat('x',11));
ERROR: value too long for type character(10)
Контраст с varchar
Кроме того, я думаю, что вышеупомянутое предложение действительно хорошо согласуется с соглашением о почти всегда использованииtext . Вы varchar(n)тоже спрашиваете об этом . Я никогда не использую это . По крайней мере, я не могу вспомнить последний раз, когда я использовал varchar(n).
Если спецификация имеет статическую ширину поля , которое я доверяю, я использую char(n),
В противном случае я использую textчто эффективно varchar(без ограничений)
Если бы я нашел спецификацию, которая имела бы текстовые клавиши переменной длины, которые были бы значимыми и которые я доверял, чтобы иметь постоянную максимальную длину, я бы varchar(n)тоже использовал . Однако я не могу придумать ничего, что соответствует этим критериям.
sales_reporting_db=#createtable x (y char(2));CREATETABLE
sales_reporting_db=#insertinto x values('Y');INSERT01
sales_reporting_db=#select'*'|| y ||'*'from x;?column?----------*Y*
оракул
SQL>createtable x ( y char(2));Table created.
SQL>insertinto x values('Y');1row created.
SQL>select'*'|| y ||'*'from x;'*'|----*Y *
Я согласен со всем, что говорит a_horse_with_no_name, и в целом согласен с комментарием Эрвина:
Метаданные
За одним небольшим исключением, я использую только один раз
char()
, когда я хочу, чтобы метаданные сказали, что это ДОЛЖНО иметь x-символы. Хотя я знаю, чтоchar()
жалуется , только если входное значение превышает предел, я буду часто защищать от недогрузок вCHECK
ограничении. Например,Я делаю это по нескольким причинам,
char(x)
иногда определяется загрузчиками схемы как столбец с фиксированной шириной. Это может иметь значение в языке, который оптимизирован для строк фиксированной ширины.Нужен пример, где я могу это сделать,
ENUM
.На ошибки
Обратите внимание, что некоторым людям может быть неудобно из-за несоответствия сообщений об ошибках по обе стороны предела, но меня это не беспокоит
Контраст с
varchar
Кроме того, я думаю, что вышеупомянутое предложение действительно хорошо согласуется с соглашением о почти всегда использовании
text
. Выvarchar(n)
тоже спрашиваете об этом . Я никогда не использую это . По крайней мере, я не могу вспомнить последний раз, когда я использовалvarchar(n)
.char(n)
,text
что эффективноvarchar
(без ограничений)Если бы я нашел спецификацию, которая имела бы текстовые клавиши переменной длины, которые были бы значимыми и которые я доверял, чтобы иметь постоянную максимальную длину, я бы
varchar(n)
тоже использовал . Однако я не могу придумать ничего, что соответствует этим критериям.Дополнительные замечания
char
здесь не следует путать с"char"
однобайтовым типом, который имеет солидную производительность и экономит место.Связанные вопросы и ответы:
источник
Postgresql
оракул
Postgresql не дополнял пробелами.
источник
SELECT pg_column_size(y) FROM x;
Я нашел это самое полезное и быстрое объяснение в 3 строки:
источник