Есть ли какая-либо возможность указать столбец как VARCHAR (N) над VARCHAR в postgres? [Дубликат]

Для 1a и 2: я проголосовал бы за новый класс DOMCrawler класса Symfony ( DomCrawler ). Этот класс позволяет запросы, похожие на CSS Selectors. Взгляните на эту презентацию для реальных примеров: news-of-the-symfony2-world .

Компонент предназначен для автономной работы и может использоваться без Symfony.

Единственным недостатком является то, что он будет работать только с PHP 5.3 или новее.

461
задан the Tin Man 10 December 2015 в 19:19
поделиться

8 ответов

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

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

Пара основных моментов:

< blockquote>

Чтобы суммировать все это:

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

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

542
ответ дан rogerdpack 24 August 2018 в 03:13
поделиться

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

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

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

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

24
ответ дан a_horse_with_no_name 24 August 2018 в 03:13
поделиться

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

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

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

7
ответ дан bpd 24 August 2018 в 03:13
поделиться

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

4
ответ дан Greg 24 August 2018 в 03:13
поделиться

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

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

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

97
ответ дан Jeffrey04 24 August 2018 в 03:13
поделиться

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
0
ответ дан ofir_aghai 24 August 2018 в 03:13
поделиться

ОБНОВЛЕНИЕ ПАНЕЛЕЙ ДЛЯ 2016 (pg9.5 +)

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

  1. использовать любой string_generator с UTF8
  2. основные этапы: 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.

UPDATED AGAIN 2018 (pg10)

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


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

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

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

  • Использовать тип данных 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%')
28
ответ дан Peter Krauss 24 August 2018 в 03:13
поделиться

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

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

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

6
ответ дан sotn 24 August 2018 в 03:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: