Для 1a и 2: я проголосовал бы за новый класс DOMCrawler класса Symfony ( DomCrawler ). Этот класс позволяет запросы, похожие на CSS Selectors. Взгляните на эту презентацию для реальных примеров: news-of-the-symfony2-world .
Компонент предназначен для автономной работы и может использоваться без Symfony.
Единственным недостатком является то, что он будет работать только с PHP 5.3 или новее.
Нет никакой разницы, под капотом это все varlena
( массив переменной длины ).
Проверьте эту статью от Depesz: http: // www .depesz.com / index.php / 2010/03/02 / charx-vs-varcharx-vs-varchar-vs-text /
Пара основных моментов:
< blockquote>Чтобы суммировать все это:
n
(накладывает их на n
) и может приводят к тонким ошибкам из-за добавления конечных пробелов, плюс проблематично изменить предел В статье подробно описывается тестирование, показывающее, что производительность вставок и выборок для всех 4 типов данных аналогична. Он также подробно рассматривает альтернативные способы ограничения длины при необходимости. Ограничения на основе функций или домены обеспечивают преимущество мгновенного увеличения ограничения длины, и на основании того, что уменьшение ограничения длины строки редок, depesz делает вывод, что один из них обычно является лучшим выбором для ограничения длины.
В руководстве по PostgreSQL
Не существует разницы в производительности между этими тремя типами, кроме увеличенного пространства для хранения при использовании пустого типа и нескольких дополнительных циклов ЦП для проверки длины при хранении в столбец с ограничениями длины. Хотя характер (n) имеет преимущества производительности в некоторых других системах баз данных, в PostgreSQL такого преимущества нет; на самом деле символ (n) обычно является самым медленным из трех из-за его дополнительных затрат на хранение. В большинстве случаев вместо этого следует использовать текст или символ. blockquote>Я обычно использую текст
Ссылки: http://www.postgresql.org/docs/current/static/datatype-character.html
текст и varchar имеют разные неявные преобразования типов. Самое большое влияние, которое я заметил, - обработка конечных пробелов. Например ...
select ' '::char = ' '::varchar, ' '::char = ' '::text, ' '::varchar = ' '::text
возвращает true, false, true
, а не true, true, true
, как вы могли ожидать.
Немного OT: если вы используете Rails, стандартное форматирование веб-страниц может отличаться. Для полей ввода данных text
поля прокручиваются, но character varying
(Rails string
) являются однострочными. Показывать представления до тех пор, пока это необходимо.
Поскольку « Типы символов » в документации указаны, varchar(n)
, char(n)
и text
сохраняются одинаково. Единственное различие - дополнительные циклы, необходимые для проверки длины, если она задана, и дополнительное пространство и время, необходимые для заполнения для char(n)
.
Однако, когда вам нужно только сохранить один символ, есть небольшое преимущество в производительности для использования специального типа "char"
(сохранить двойные кавычки - они являются частью имени типа). Вы получаете более быстрый доступ к полю, и нет накладных расходов для хранения длины.
Я только что сделал таблицу из 1 000 000 случайных "char"
, выбранных из нижнего регистра. Запрос на получение частотного распределения (select count(*), field ... group by field
) занимает около 650 миллисекунд, против примерно 760 по тем же данным, используя поле text
.
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
И используя тесты «чистого SQL» (без какого-либо внешнего скрипта)
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 года и укрепить рекомендации.
Мои результаты после средних значений на многих машинах и во многих тестах: все равно (статистически меньше стандартного отклонения).
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%')
По-моему, у 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, вы можете избежать этих ошибок.