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 случайных
"char"выбирается из строчного алфавита. Запрос для получения частотного распределения (select count(*), field ... group by field) занимает около 650 миллисекунд, против около 760 на тех же данных с помощью
обновление бенчмарков на 2016 год (pg9.5+)
и использование" чистых 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,)||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