PostgreSQL: разница между текстом и varchar (различается символ)

377

Какая разница между типами данных text и character varying (varchar)?

Согласно документации

Если переменная символов используется без спецификатора длины, тип принимает строки любого размера. Последнее является расширением PostgreSQL.

и

Кроме того, PostgreSQL предоставляет тип текста, в котором хранятся строки любой длины. Хотя текст типа не входит в стандарт SQL, у него также есть несколько других систем управления базами данных SQL.

И какая разница?

Теги:
string
types
text
varchar

5 ответов

474
Лучший ответ

Нет никакой разницы, под капотом это все varlena (массив переменной длины).

Проверьте эту статью от Depesz: http://www.depesz.com/index.php/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text/

Несколько основных моментов:

Подводя итог:

  • char (n) - занимает слишком много места при работе со значениями, короче n, и может приводить к тонким ошибкам из-за добавления трейлинг пробелы, плюс проблематично изменить предел
  • varchar (n) - проблематично изменить лимит в живой среде
  • varchar - точно так же, как текст
  • текст - для меня победитель - over (n) типов данных, потому что ему не хватает своих проблем, и над varchar - потому что он имеет различное имя

В статье подробно описывается тестирование, показывающее, что производительность вставок и выборок для всех 4 типов данных аналогична. Он также подробно рассматривает альтернативные способы ограничения длины при необходимости. Ограничения на основе функций или домены обеспечивают преимущество мгновенного увеличения ограничения длины, и на основе того, что уменьшение ограничения длины строки происходит редко, depesz делает вывод, что один из них обычно является лучшим выбором для ограничения длины.

  • 54
    @axiopisty Отличная статья. Вы можете просто сказать: «Не могли бы вы взять некоторые выдержки на случай, если статья когда-нибудь выйдет из строя?» Я попытался кратко изложить содержание / выводы статьи. Я надеюсь, что этого достаточно, чтобы ослабить ваши опасения.
  • 32
    @axiopisty, собственно говоря, первоначальный ответ гласил: « под капотом все это варлена », что, безусловно, является полезной информацией, которая отличает этот ответ от ответа только по ссылке.
Показать ещё 6 комментариев
85

Как " Типы символов" в документации указывает, varchar(n), char(n) и text все хранятся одинаково путь. Единственное различие - дополнительные циклы, необходимые для проверки длины, если она задана, и дополнительное пространство и время, необходимые для заполнения для char(n).

Однако, когда вам нужно только сохранить один символ, есть небольшое преимущество в производительности для использования специального типа "char" (сохранить двойные кавычки - они являются частью имени типа). Вы получаете более быстрый доступ к полю, и для хранения длины нет накладных расходов.

Я просто сделал таблицу из 1 000 000 случайных "char", выбранных из нижнего регистра. Запрос на получение частотного распределения (select count(*), field ... group by field) занимает около 650 миллисекунд, против примерно 760 по тем же данным, используя поле text.

  • 16
    технически кавычки не являются частью имени типа. они нужны, чтобы отличать его от ключевого слова char.
  • 24
    Технически вы правы @Jasen ... Что, конечно, лучший вид
Показать ещё 1 комментарий
19

ОБНОВЛЕНИЕ БЕНЗАРМЕНТОВ НА 2016 ГОД (pg9.5 +)

И используя тесты "чистого SQL" (без каких-либо внешних script)

  • используйте любой string_generator с UTF8

  • Основные этапы:

    2,1. ВСТАВИТЬ

    2,2. SELECT сравнение и подсчет


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;

... И используйте EXPLAIN ANALYZE. Мои результаты: в среднем все равно.

  • 0
    Значит не имеет значения, чем я сделал все свои столбцы varchar вместо текста? Я не указал длину, хотя некоторые из них только 4 - 5 символов и, конечно, не 255.
  • 1
    @ Да, это не имеет значения
Показать ещё 3 комментария
18

В руководстве по PostgreSQL

Между этими тремя типами нет разницы в производительности, кроме увеличения пространства для хранения при использовании пустого запаса и нескольких дополнительных циклов процессора для проверки длины при хранении в столбце с ограничением длины. Хотя характер (n) имеет преимущества производительности в некоторых других системах баз данных, в PostgreSQL такого преимущества нет; на самом деле символ (n) обычно является самым медленным из трех из-за его дополнительных затрат на хранение. В большинстве случаев вместо этого следует использовать текст или символ.

Обычно я использую текст

Ссылки: http://www.postgresql.org/docs/current/static/datatype-character.html

4

Немного OT: если вы используете Rails, стандартное форматирование веб-страниц может отличаться. Для форм ввода данных text окна прокручиваются, но теги character varying (Rails string) являются однострочными. Показывать представления до тех пор, пока это необходимо.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню