|
|
|
Varchar vs Text
|
|||
|---|---|---|---|
|
#18+
Нарвался недавно на такую неприятную штуку. Есть такой элементарный запрос: Код: sql 1. Код: sql 1. 2. 3. 4. 5. Очевидно не хватало индекса. Добавил, план не изменился. Чуть-чуть поменял запрос: Код: sql 1. План: Код: sql 1. 2. 3. 4. 5. Тип seriesNumber - char(20). План правильный при cast'е к чему угодно, кроме text. "PostgreSQL 9.4.5, compiled by Visual C++ build 1800, 64-bit" Собственно 2 вопроса: 1) Что такого волшебного в text? 2) И если вместо text использовать varchar какие могут быть подводные камни? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.02.2016, 10:37 |
|
||
|
Varchar vs Text
|
|||
|---|---|---|---|
|
#18+
а я всегда varchar использую.... и как то побаиваюсь использовать text, а то вдруг подводный камень вылезет ))) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2016, 16:50 |
|
||
|
Varchar vs Text
|
|||
|---|---|---|---|
|
#18+
Nitro_Junkie, В данном случае вам скорее всего скажут: “а зачем вы константу к типу явно приводите? Оставьте как есть” Но вопрос интересный, потому спросил в списке, отпишусь как ответят. Если глянуть на то, как типы приводятся, то и `text`, и `varchar` "двоично совместимы" с типом `bpchar`: Код: sql 1. 2. 3. 4. 5. 6. 7. При этом `varchar` работает "как хочется". Возможно связано с тем, что и `varchar`, и `bpchar` принимают ограничители длины, в отличии от `text`а. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.02.2016, 18:50 |
|
||
|
Varchar vs Text
|
|||
|---|---|---|---|
|
#18+
Nitro_Junkie, Не используйте char(n) типы, вы там еще много граблей с ними соберете совершенно неожиданных. Да и смысла в них ровно ноль. -- Maxim Boguk www.postgresql-consulting.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.02.2016, 02:39 |
|
||
|
Varchar vs Text
|
|||
|---|---|---|---|
|
#18+
Nitro_Junkie, http://www.postgresql.org/message-id/flat/CAGnEbohnFkRWrW1rAiZhobGhabwUNGBJxFwGMAVDGzQfpp5bDw@mail.gmail.com]Вот тут обсуждение. И нужен раздел 10.2 документации , с которым будем работать, часть`Operator Type Resolution` (первая сверху). Я смоделировал ситуацию так: Код: sql 1. 2. 3. 4. 5. 6. Рассматриваем такой запрос: Код: sql 1. Выражение имеет форму <left_arg> <op> <right_arg>, в нашем случае <op> = `=`. В документации (пункт первый) сказано, что если оператор не был задан явно ( раздел 4.2.5 ), то рассматриваются все видимые операторы с таким именем (возможно, вы создали оператор равенства в своей схеме? — он таже будетрассматриваться). Далее начинается проверка типов. Ищется оператор, который полностью соответствует типу данных аргументов. Если такой есть — используется. Если один из аргументов имеет тип `unknown`, то считается что он равен типу второго аргумента — ищется оператор и используется. Интересное начинается, если типы аргументов отличаются и нет соответствующего оператора сравнения (это как раз наш случай). Postgres должен привести оба аргумента к одному типу. Надо выбрать один из типов, `text` или `bpchar` (blank-padded char). Посмотрите на результат запроса и скажите, к какому типу Postgres будет приводить: Код: sql 1. Изменение типа колонки (по сути — вызов функции) делает использование индекса невозможным. Это отвечает на ваш вопрос #1 — тип `text` является предпочтительным и как только он появляется, то все аргументы (при необходимости) будут приведены к нему. Касаемо типов категории `S` — они (почти все) хранятся одинаково, и обрабатываются одним движком: Код: sql 1. Но у них должны быть различия на уровне SQL: - text — универсальный - varchar — тот же `text`, только может иметь ограничение длины - bpchar — тот же `varchar`, только должен дополнятся пробелами до указанной длины. Тип `char`стоит отдельно, его надо рассматривать как просто 8-битный символ, который храниться "как есть" (typlen=1, typstorage=p). Полагаю, это историческая часть системы и правильно работать с UTF8 в этом типе невозможно. Не стоит путать тип данных Postgres'а `char` с типом данных SQL'а `char`! — когда вы создаёте колонку типа `char` в SQL'е, то Postgres использует `bpchar`. TL;DR — В результате получается: - используя явное преобразование к `text`, которое не соответствует типу колонки, вы склоняете Postgres к тем последствиям, что вы и описали (ССЗБ); - лучше оставлять константы без явного преобразования (в тех местах, где это допустимо) — база сама привёдет `unknown` к типу второго аргумента оператора - т.к. SQL-тип `char` использует Postgres-тип `bpchar`, обрабатываемый одинаково с `text`-ом, то предпочтительней использовать `text`. Мало ли какие ещё сюопризы откопаете в связи с тем, что результат "должен" дополнятся пробелами (в кавычках, т.к. везде ли он дополняется?) - если нужно ограничить длину `text` колонки — пользуйтесь CHECK constraint или сделайте свой DOMAIN. Как-то так. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.02.2016, 12:30 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=39176843&tid=1997409]: |
0ms |
get settings: |
9ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
59ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
63ms |
get tp. blocked users: |
2ms |
| others: | 224ms |
| total: | 393ms |

| 0 / 0 |
