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



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



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




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




и




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




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

3001   8  

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 случайных "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 (рельсы 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

Comments

    Ничего не найдено.