Які поточні найкращі практики щодо розмірів варшарів у SQL Server?


12

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

Продуктивність
З мого дослідження, схожещо varchar (max) слід використовувати лише тоді, коли він вам справді потрібен; тобто, якщо стовпець повинен містити більше 8000 символів, одна з причин - відсутність індексації (хоча я взагалі трохи підозрілий в індексації на полях varchar. Хоча я досить новий в принципах БД, тому, можливо, це необгрунтовано ) та стиснення (більше турботи про зберігання). Насправді люди, як правило, рекомендують використовувати лише те, що потрібно, коли ви робите varchar (n) .... негативний розмір - це погано, оскільки запити повинні враховувати максимально можливий розмір. Але також було заявлено, що двигун буде використовувати половину зазначеного розміру як оцінку середнього фактичного розміру даних. Це означає, що з даних слід визначити, що таке середній розмір, подвоїти його і використовувати це як n. Для даних з дуже низькою, але ненульовою мінливістю, це передбачає до 2-х разів перевищення максимального розміру, що здається великим, але, можливо, це не так? Інформація буде вдячна.

Зберігання
Після прочитання про те, як працює зберігання між рядами та поза рядками, і маючи на увазі, що фактичне зберігання обмежене фактичними даними, мені насправді здається, що вибір n має мало або не має відношення до пам’яті (до того ж переконайтесь, що він достатньо великий, щоб усе вмістити). Навіть використання varchar (max) не повинно впливати на зберігання. Натомість метою може бути обмеження фактичного розміру кожного рядка даних до ~ 8000 байт, якщо це можливо. Це точне прочитання речей?

Контекст
Деякі дані наших клієнтів дещо коливаються, тому ми зазвичай робимо стовпчики трохи ширшими, ніж вони повинні бути, скажімо, на 15-20% більшими для цих стовпців. Мені було цікаво, чи є якісь інші особливі міркування; наприклад, хтось, з ким я працюю, сказав мені використовувати 2 ^ n - 1 розмір (я не знайшов доказів, що це річ, хоча ....)

Я говорю про початкове створення таблиці. Клієнт скаже нам, що збирається почати надсилати нам нову таблицю, і надішле зразкові дані (або просто перший набір даних про виробництво), які ми подивимось, і складе таблицю в нашому кінці для зберігання даних. Ми хочемо зробити таблицю з нашого боку для обробки майбутнього імпорту, а також того, що є в вибірці. Але певні ряди обов'язково витягнуться довше, тому ми прокладемо їх.

Питання - скільки і чи є технічні вказівки?


MongoDB використовує 2 ^ n розподілу диска для документа. SQL Server не використовує цю стратегію.
Майкл Грін

Відповіді:


19

Незалежно від конкретного типу даних, ви повинні мати можливість зберігати будь-які програми, які вимагають зберігати. Ви не можете вказати щось менше, ніж максимальний розмір того, що буде фактично збережено.

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

Щоправда, рядки змінної довжини та двійкові стовпці не мають значення для зберігання, що це типи даних фіксованої довжини (рядок / двійковий / числовий / дата / тощо) (хоча деякі з цих наслідків можуть бути скасовані через стиснення даних або використання SPARSEвизначення стовпця варіант). Однак, як ви зазначали, навіть якщо немає прямих наслідків для зберігання даних, все ж є наслідки для продуктивності завищення необхідної пам'яті для запитів.

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

Натомість метою може бути обмеження фактичного розміру кожного рядка даних до ~ 8000 байт, якщо це можливо.

Я не зовсім впевнений, що ви тут отримуєте. SQL Server фізично обмежить вас трохи більше 8000 байт. Використання типів LOB - VARCHAR(MAX), NVARCHAR(MAX), VARBINARY(MAX), XML, і засуджується TEXT, NTEXTі IMAGEтипи - дозволяють вихід за межі цього початкового обмеження розміру сторінки, але це тільки з - за розміщення покажчика (16 або більше байт, в залежності від типу, і в залежності від розмір значення, що зберігається поза рядками при використанні MAXтипів). Фактичний фізичний ліміт сторінки даних не змінився.

Ваша мета повинна полягати в тому, щоб використовувати найменший обсяг фізичного простору, щоб зберігати те, що додаток / бізнес потрібно зберігати, не порушуючи або обрізаючи, щоб неповне значення втрачало сенс або спричиняло проблеми нижче за течією. Якщо вам потрібно зберегти 12 000 символів, тоді використовуйте, VARCHAR(MAX)тому що саме це потрібно. Якщо ви зберігаєте номер телефону або поштовий / поштовий індекс, користуватися ним було б нерозумно VARCHAR(100)і безвідповідально VARCHAR(MAX).

деякі дані наших клієнтів дещо коливаються, тому ми зазвичай робимо стовпчики трохи ширшими, ніж вони повинні бути, скажімо, на 15-20% більшими для цих стовпців. Мені було цікаво, чи є якісь інші особливі міркування;

Чи не всі системи мають принаймні деякі дані, які коливаються? Будь-яка система, яка зберігає ім'я людини, може кваліфікуватися, правда? Існує досить велика дисперсія в довжині імен. А потім у вас є хтось, як Принц, йдуть і змінюють їх ім'я на символ, і тепер у вас є зовсім інша проблема, яка не є довжиною. Це просто так.

Але, щоб на мить зіграти захисника диявола: як може значення "15-20% більше, ніж потрібно" не бути фактично необхідним значенням Скажімо, йдеться про дискусію про додавання нового стовпця, а хтось пропонує 50 символів, тоді хтось ще каже: "ну, на 20% більше 60, так що давайте зробимо 60, бо хтось може мати 60". Якщо це правда, що у клієнта може бути 60, то 60 - це було і завжди було фактично необхідне значення, а 50 - весь час помилявся.

Звичайно, це допоможе, якби було вказано джерело даних, оскільки:

  1. якщо ви робите "URL" 1024, а комусь потрібно 1060, то це повинно бути 1060 (аналогічно, якщо ви робите URL-адресу VARCHARта отримуєте скарги на те, що вона псує символи Unicode, які тепер дозволені в доменних іменах, тоді це потрібно бути NVARCHAR), але
  2. якщо хто - то хоче додати 1000 символів в поле коментаря в 500 символів межі, то він все ще тільки потрібно , щоб бути 500. Люди можуть бути менш багатослівним в коментарях (величезний виклик для мене ;-), але ProductSKUкраще бути досить великий , щоб відповідати всім Облікових кодів замовника.

Я говорю про початкове створення таблиці. Клієнт скаже нам, що збирається почати надсилати нам нову таблицю, і надішле зразкові дані (або просто перший набір даних про виробництво), які ми подивимось і складемо таблицю в нашому кінці для зберігання даних. Ми хочемо зробити таблицю з нашого боку для обробки майбутнього імпорту, а також того, що є в вибірці. Але певні ряди обов'язково витягнуться довше, тому ми прокладемо їх. Питання - скільки і чи є технічні вказівки?

Ви робите тут багато припущень. Звичайно, деякі поля можуть збільшитися. Але знову ж таки, вони не можуть. Або дехто міг отримати менше. Деякі можуть змінитись від не-Unicode до того, щоб стати Unicode (як тільки вони зрозуміють, що світ стає меншим, і не можна припустити, що прізвища матимуть лише основні символи англійської мови ASCII / US). Або вони могли перестати надсилати поле. Або вони можуть додати одне або кілька полів у майбутньому. Будь-яке поєднання цього та іншого. То чому б зосереджуватися лише на VARCHARстовпцях? Що робити, якщо вони наразі надсилають INTзначення і через рік-два вони досягають максимального значення і починають надсилати BIGINT? Що робити, якщо вони мають поле "статус" зі значеннями 0 - 5. Ви просто збираєтесь припускатиINTякий "підкладений", як дозволяє для зростання, але, мабуть, повинен бути TINYINT?

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

Тож керівництво:

  1. Не витрачайте часу та енергії на спроби відповісти на непереборне запитання.
  2. Натомість зосередьтеся на тому, щоб отримати якомога більше інформації щодо фактичних даних вашого клієнта, і перейдіть до цього (тобто прийняття рішень, орієнтованих на дані ;-).

У вас уже є приклади даних, чудово. Але, не забувайте, що ви також маєте контактну інформацію свого клієнта: телефон та / або електронну пошту. Зверніться до них! Попросіть їх специфікацій даних (як і у вашій системі, дані, які зараз знаходяться в їхній системі, можуть мати максимальну довжину 35, але їх система визначила як VARCHAR(50), і їх система прийме до такої довжини, і в такому випадку ви повинні використовувати 50). І запитайте їх, чи планують вони змінювати найближчі перспективи та типи даних (тип та / або розмір).


1
Я погоджуюся з Соломоном, @ Aristotle2600 - однак, ви можете поглянути на мою відповідь на питання щодо відмінностей між a varchar(255)і a varchar(256)для деяких подальших міркувань
Макс Вернон,

Дякую, я мав враження, що це буде щось подібне, а "використовувати лише те, що потрібно" - це лише хороша практика управління ресурсами у всьому світі. Але деякі дані наших клієнтів дещо коливаються, тому ми зазвичай робимо стовпчики трохи ширшими, ніж вони повинні бути, скажімо, на 15-20% більшими для цих стовпців. Мені було цікаво, чи є якісь інші особливі міркування; Наприклад, хтось, з ким я працюю, сказав мені використовувати 2 ^ n - 1 розмір (я не знайшов жодних доказів, що це річ ....). Але це здається, що немає нічого іншого, як зберегти речі як можна менше.
aristotle2600

1
@ aristotle2600 Не знаю, як застосувати "2 ^ n - 1", але мені все одно доведеться запитати: чи навіть теоретично можливо зробити щось більше, ніж потрібно ? Невже 15-20% більший розмір не буде розміром, який він повинен бути, щоб не зламатися? ;-). Я впевнений, що це допоможе, якщо ви були більш чіткими в джерелі даних, тому що а) якщо ви робите "URL" 1024, а комусь потрібно 1060, то це повинно бути 1060, але б) якщо хтось хоче додати 1000 символів до 500-літрового коментованого поля, тоді все одно потрібно було лише 500. Люди можуть вводити менше коментарів, але SKU продукту краще бути достатньо великим.
Соломон Руцький

@ aristotle2600 Я просто додав сюди кілька ваших коментарів до питання, оскільки вони забезпечують гарний контекст. Я також додав речі до кінця своєї відповіді :)
Соломон Руцький

Дуже дякую за вашу відповідь! Так, імена та адреси коливаються. Що стосується постійно зростаючого парадоксу на 20%, я розумію, що ви маєте на увазі, але я говорю про початкове створення таблиці. Клієнт скаже нам, що збирається почати надсилати нам нову таблицю, і надішле зразкові дані (або просто перший набір даних про виробництво), які ми подивимось і складемо таблицю в нашому кінці для зберігання даних. Ми хочемо зробити таблицю з нашого боку для обробки майбутнього імпорту, а також того, що є в вибірці. Але певні ряди обов'язково витягнуться довше, тому ми закладаємо їх. Питання - скільки і чи є технічні вказівки?
aristotle2600
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.