Чи слід додати довільну межу довжини до стовпців VARCHAR?


35

Згідно документації в PostgreSQL , немає ніякої різниці в продуктивності між VARCHAR, VARCHAR(n)і TEXT.

Чи слід додати довільну межу довжини до стовпця імені чи адреси ?

Редагувати: Не обман:

Я знаю, що CHARтип є пережитком минулого, і мене цікавлять не тільки продуктивність, але й інші плюси та мінуси, як Ервін зазначив у своїй дивовижній відповіді.

Відповіді:


45

Відповідь - ні .
Не додайте модифікатор довжини, varcharякщо ви можете цього уникнути. Більшість випадків вам фактично не потрібно обмеження довжини. Просто використовуйте textдля всіх символьних даних. Зробіть це varchar(без модифікатора довжини), якщо вам потрібно залишатися сумісним з RDBMS, які не мають text.

Продуктивність майже те ж саме - textце трохи швидше , в рідкісних випадках , і ви збережете цикли для перевірки на довжину.

Якщо вам дійсно потрібно застосувати максимальну довжину, все ж використовуйте textта додайте для цього контрольне обмеження :

ALTER TABLE tbl ADD CONSTRAINT tbl_col_len CHECK (length(col) < 51);

Ви можете будь-коли змінити або скинути таке обмеження, не возившись з визначенням таблиці та всіма залежними об'єктами (подання, функції, зовнішні ключі, ...)

З модифікаторами довжини ви просто зіткнетеся з проблемами на кшталт цієї чи цієї чи цієї ...

PostgreSQL 9.1 представив нову функцію, щоб дещо полегшити біль. Я цитую тут примітки до випуску :

Дозволити ALTER TABLE ... SET DATA TYPEуникати переписувань таблиць у відповідних випадках (Ноа Міш, Роберт Хаас)

Наприклад, перетворення varcharстовпця в текст більше не потребує перезапису таблиці. Однак для збільшення обмеження довжини varcharстовпця все ж потрібно переписати таблицю.


Я думаю, що ця відповідь була б набагато кращою, якби вона була просто "ніколи не додавай довільних обмежень реальній базі даних ніколи". Я відчуваю, що багато відповідей потребують виправлень та додаткової інформації, але це абсолютно поза темою і могло б відвернути ваш висновок, з яким я повністю згоден.
Еван Керролл

Так, все на основі версій Postgres до 9.1 - 6 років тому. Наразі трохи запилено, але основна порада все-таки хороша.
Ервін Брандстеттер

Це гарна чи погана ідея додавати обмеження для перевірки для кожного текстового стовпчика з метою перевірки правильності та забезпечення того, що помилка у клієнта не використовує весь диск на базі даних, вставивши дуже великий текст?
Код

@Code: Це життєздатний варіант. Якщо у вас багато стовпців з однаковим обмеженням, врахуйте домени . Або varchar(n)зрештою, для простоти - якщо мінуси зазвичай не впливають на вас. (Обмеження не є довільним у вашому випадку, якщо ви хочете виконати фактичну максимальну довжину.)
Ервін Брандштеттер

12

Якщо ви бачите обмеження довжини як своєрідне обмеження для перевірки, щоб переконатися у валідації даних, тоді так, додайте. Насправді ви можете використовувати не визначення довжини, а справжнє обмеження перевірки, щоб швидше змінити межу.

Щоб змінити (збільшити) обмеження довжини, вам потрібно запустити лінійку, ALTER TABLEяка може зайняти довгий час (через можливе перезапис таблиці), під час якої необхідне ексклюзивне блокування таблиці.

Зміна (тобто скасування та повторне створення) обмеження перевірки - це дуже коротка операція і вимагає лише зчитування даних таблиці, вона не змінить жодних рядків. Тож це стане набагато швидшим (що, в свою чергу, означає, що ексклюзивний замок столу буде утримуватися набагато коротший час).

Під час роботи немає різниці між тим text, a, varcharабо varchar(5000)стовпцем.


з простої цікавості, чому ви вважаєте, чому ця перевірка довжини не може бути виконана на клієнтській програмі під час збору даних?
PirateApp

4
@PirateApp: тому що дуже часто буде більше однієї програми або якогось зовнішнього джерела даних (подумайте, щомісячний імпорт). І майже завжди база даних (і дані) живе довше, ніж одна програма.
a_horse_with_no_name

2

Питання полягає саме в тому, чи додавати довільну межу довжини до стовпців VARCHAR?

На це відповідь просто «ні». Немає нічого, що може виправдати додавання довільної межі, як ви б, у нижчі бази даних, які підтримують varchar(max)або використовують такі умови varchar(255). Однак якщо специфікація вирішує обмеження, я думаю, що відповідь стає набагато складнішим, особливо в сучасних версіях PostgreSQL. І для цього я б схилився ТАК .

На мою думку, межа є розумним вибором, якщо цього вимагає специфікація. Особливо для більш розумних навантажень. Якщо ні з якої іншої причини, то зберегти метадані.

З моєї відповіді тут, показник ефективності для CHAR проти VARCHAR (Postgres) , де я адресую значення метаданих.

Якби я знайшов специфікацію, яка мала текстові клавіші змінної довжини, які мали сенс і які я довіряла мати постійну максимальну довжину, я також використала б varchar. Однак я не можу придумати нічого, що відповідає цим критеріям.


1

Схоже, може бути певна різниця в продуктивності, якщо VARCHARїї регулярно використовують для зберігання дуже великих рядків, оскільки "довгі рядки стискаються системою автоматично", а "дуже довгі значення також зберігаються у фонових таблицях". Теоретично це означатиме, що великий обсяг запитів для дуже довгого рядкового поля буде повільнішим, ніж для поля короткого рядка. Ви, мабуть, ніколи не зіткнетеся з цією проблемою, оскільки імена та адреси не будуть дуже довгими.

Однак, залежно від того, як ви використовуєте ці рядки поза вашою базою даних, ви можете додати практичний ліміт, щоб запобігти зловживанню системою. Наприклад, якщо ви десь відображаєте ім’я та адресу у формі, можливо, ви не зможете відобразити цілий абзац тексту у полі "ім'я", тому було б доцільно обмежити стовпець імені чимось на зразок 500 символів.


1
AFAIK немає різниці в полях TOARSTING вархар та текстових полів.
dezso

VARCHAR- це чисто синтаксичний цукор для TEXTPostgres, різниця в обробці сховища нульова; зберігання таблиці на стиск та фон, яке ви згадуєте, здійснюється на основі фактичної довжини даних у стовпці, а не на метаданих стовпця. Стовпчики TEXT зберігаються внутрішньо як varlenaструктура С (це масив змінної довжини з першими 4 байтами, що зберігають довжину під час створення / оновлення), і саме ця структура оптимізована на основі її довжини.
коуберт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.