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

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

По данным документация

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

и

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

Так в чем же разница?

8 ответов


нет никакой разницы, под капотом все 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-так же, как текст
  • текст – для меня победитель – над (n) типами данных, потому что ему не хватает их проблем, и над varchar – потому что у него отличное имя

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


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

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

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


обновление бенчмарков на 2016 год (pg9.5+)

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

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

  2. основные задачи:

    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,)||chr( 9824 + (random()*10)::int )
  ), ' ' ) as s
  FROM generate_series(1, ) 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.

обновлено снова 2018 (pg10)

мало редактировать, чтобы добавить результаты 2018 и укрепить рекомендации.


результаты в 2016 и 2018 годах

мои результаты, после среднего, во многих машинах и много испытаний: все же
(статистически меньше стандарта tham отклонение.)

рекомендация

  • использовать text тип,
    не varchar(x) потому что иногда это не стандарт, например, в CREATE FUNCTION п. varchar(x)varchar(y).

  • экспресс-лимиты (с varchar производительность!) с CHECK п. в CREATE TABLE
    например CHECK(char_length(x)<=10).
    с незначительной потерей производительности в INSERT / UPDATE вы также можете управлять диапазонами и строкой структура
    например CHECK(char_length(x)>5 AND char_length(x)<=20 AND x LIKE 'Hello%')


на PostgreSQL руководство

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

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

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


text и varchar имеют разные неявные преобразования типов. Самое большое влияние, которое я заметил, - это обработка конечных пространств. Например...

select ' '::char = ' '::varchar, ' '::char = ' '::text, ' '::varchar = ' '::text

возвращает true, false, true, а не true, true, true как и следовало ожидать.


по-моему,varchar(n) имеет свои преимущества. Да, все они используют один и тот же базовый тип и все такое. Но, следует отметить, что индексы в PostgreSQL имеют свой предел размера 2712 байт в строке.

TL; DR: Если вы используете text тип без ограничений и имеют индексы на этих столбцах, очень возможно, что вы нажмете этот предел для некоторых из ваших столбцов и получите ошибку при попытке вставить данные, но с используя varchar(n), вы можете предотвратить его.

подробнее: проблема здесь в том, что PostgreSQL не дает никаких исключений при создании индексов для text тип или varchar(n) здесь n больше 2712. Однако это приведет к ошибке при попытке вставить запись со сжатым размером больше 2712. Это означает, что вы можете легко вставить 100.000 символов строки, состоящей из повторяющихся символов, потому что она будет сжата намного ниже 2712 но вы не сможете вставить некоторую строку с 4000 символами, потому что сжатый размер больше 2712 байт. Используя varchar(n) здесь n не слишком много больше, чем 2712, вы в безопасности от этих ошибок.


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


character varying(n), varchar(n) - (как же). значение будет усечено до n символов без ошибки.

character(n), char(n) - (как же). фикчированн-длина и пусковая площадка с пробелами до конца длины.

text - неограниченной длины.

пример:

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