В чем разница между типом данных text
и типами данных character varing
(varchar
)?
Согласно документации
Если символьная переменная используется без спецификатора длины, тип принимает строки любого размера. Последний тип является расширением PostgreSQL.
и
Кроме того, PostgreSQL предоставляет тип text, который хранит строки любой длины. Хотя тип text не входит в стандарт SQL, в некоторых других системах управления базами данных SQL он тоже есть.
Так в чем же разница?
Разницы нет, под капотом все varlena
(массив переменной длины).
Посмотрите эту статью от Depesz: http://www.depesz.com/index.php/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text/.
Пара основных моментов:
Подводя итог:
- char(n) - занимает слишком много места при работе со значениями короче
n
(разбивает их наn
), и может привести к тонким ошибкам из-за добавления пробелов в конце строки. пробелы, плюс проблематично изменить предел- varchar(n) - проблематично изменить лимит в живой среде (требуется эксклюзивная блокировка при изменении таблицы)
- varchar - так же, как и текст
- text - для меня победитель - над (n) типами данных, потому что у него нет их проблем, и над varchar - потому что у него есть отличительное имя
В статье проводится подробное тестирование, показывающее, что производительность вставок и селектов для всех 4 типов данных одинакова. В ней также подробно рассматриваются альтернативные способы ограничения длины, когда это необходимо. Ограничения на основе функций или доменов дают преимущество мгновенного увеличения ограничения длины, и на основании того, что уменьшение ограничения длины строки встречается редко, Депеш делает вывод, что один из них обычно является лучшим выбором для ограничения длины.
Как указано в документации "Типы символов", varchar(n)
, char(n)
и text
хранятся одинаково. Единственное различие заключается в дополнительных циклах, необходимых для проверки длины, если она задана, а также в дополнительном пространстве и времени, требуемых для char(n)
, если требуется заполнение.
Однако, когда вам нужно хранить только один символ, есть небольшое преимущество в производительности при использовании специального типа "char"
(сохраните двойные кавычки - они являются частью имени типа). Вы получаете более быстрый доступ к полю, и нет накладных расходов на хранение длины.
Я только что создал таблицу из 1,000,000 случайных "символов"-, выбранных из алфавита со строчными буквами. Запрос для получения частотного распределения (
select count(*), field ... group by field) занимает около 650 миллисекунд, против около 760 на тех же данных с использованием поля
text`.
И с помощью "в чистом SQL" и показатели (без какого-либо внешнего скрипта)
использовать любые string_generator с utf8
основные критерии:
2.1. Вставить
2.2. Выбрать сравнение и подсчет
CREATE FUNCTION string_generator(int DEFAULT 20,int DEFAULT 10) RETURNS text AS $f$
SELECT array_to_string( array_agg(
substring(md5(random()::text),1,$1)||chr( 9824 + (random()*10)::int )
), ' ' ) as s
FROM generate_series(1, $2) i(x);
$f$ LANGUAGE SQL IMMUTABLE;
Подготовить конкретные испытания (примеры)
DROP TABLE IF EXISTS test;
-- CREATE TABLE test ( f varchar(500));
-- CREATE TABLE test ( f text);
CREATE TABLE test ( f text CHECK(char_length(f)<=500) );
Выполнить базовую проверку:
INSERT INTO test
SELECT string_generator(20+(random()*(i%11))::int)
FROM generate_series(1, 99000) t(i);
И другие тесты,
CREATE INDEX q on test (f);
SELECT count(*) FROM (
SELECT substring(f,1,1) || f FROM test WHERE f<'a0' ORDER BY 1 LIMIT 80000
) t;
... И использовать объясните анализа
.
Обновлен снова 2018 (pg10)
маленькая правка, чтобы добавить 2018's результаты и укрепить рекомендации.
Результаты ## в 2016 и 2018 годах Мои результаты, после среднего, во многих машинах и много испытаний: все же<БР/> (статистически менее Тхам стандартное отклонение).
Используйте "текст" тип данных, <БР/>не старого типа varchar(х)
потому что иногда это не стандартный, например, в функции createположений
типа varchar(х)**≠**
типа varchar(г)`.
экспресс-ограничения (с тем же типа varchar
производительность!) с проверить
пункт создать таблицу
<БР/>например, проверить(char_length(х)<=10)
. <БР>с незначительной потерей производительности в вставка/обновление вы можете также контролировать диапазоны и структуры строки <БР/>например, проверить(char_length(х)>5 и char_length(х)<=20 и X, как 'Привет%')
В руководстве по PostgreSQL
Разницы в производительности между этими тремя типами нет, если не считать увеличения пространства для хранения при использовании типа с пустой подложкой и нескольких дополнительных тактов процессора для проверки длины при хранении в столбце с ограничением длины. Хотя character(n) имеет преимущества в производительности в некоторых других системах баз данных, в PostgreSQL такого преимущества нет; на самом деле character(n) обычно самый медленный из трех типов из-за дополнительных затрат на хранение. В большинстве ситуаций вместо него следует использовать варьирование текста или символов.
Я обычно использую текст
Ссылки: http://www.postgresql.org/docs/current/static/datatype-character.html
На мой взгляд, `типа varchar(Н) она'ы собственного достоинства. Да, все они используют один и тот же базовый тип и все такое. Но, следует отметить, что индексы в PostgreSQL имеет своим предельным размером 2712 байт в ряду.
ТЛ;ДР:
Если вы используете текст
тип без ограничения и индексы на эти колонки, то очень возможно, что вы достигли этого предела для некоторых столбцов и получаете сообщение об ошибке при попытке вставить данные, но с помощью типа varchar(н)
, вы можете предотвратить его.
Больше деталей: проблема здесь заключается в том, что PostgreSQL не'т дать каких-либо исключений при создании индексов для текст
или типа типа varchar(Н)
где N
- это больше, чем 2712. Однако, это даст ошибку при записи со сжатым размером больше, чем 2712 пытался быть вставлен. Это означает, что вы можете вставить 100.000 символ строки, которая состоит из повторяющихся символов легко, потому что он будет сжиматься намного ниже 2712 но вы не можете быть в состоянии, чтобы вставить строку с 4000 символов, так как сжатый размер больше 2712 байт. Используя типа varchar(Н)
где N
- это не слишком много больше, чем 2712, вы'Снова в безопасности от этих ошибок.
Text и varchar имеют различные неявные преобразования типов. Самое большое влияние, что я'вэ заметил обрабатывает конечные пробелы. Например ...
select ' '::char = ' '::varchar, ' '::char = ' '::text, ' '::varchar = ' '::text
возвращает значение true, false или true, а не
правда, правда, правда, как вы могли бы ожидать.
Несколько ВЗ: если вы're через рельсы, стандартные форматирования веб-страниц могут быть разными. Для поля ввода формы данных текст
прокруткой, но разные символы(рельсы
строка`) ящики в одну линию. Показать как долго, как это необходимо.
разные символы(Н)
, типа varchar(Н)
- (Как же). значение будет усечено до n символов без ошибки.
<БР><БР>
символ(Н)
, голец(Н)
- (Как же). фиксированной длины и колодки с заготовками до конца длины.
<БР><БР>
текст
- неограниченная длина.
<БР><БР>
Пример:<БР>
Table test:
a character(7)
b varchar(7)
insert "ok " to a
insert "ok " to b
Мы получим результаты:
a | (a)char_length | b | (b)char_length
----------+----------------+-------+----------------
"ok "| 7 | "ok" | 2