Наскільки великі ці зображення, і скільки ви очікуєте мати? Хоча я здебільшого погоджуюся з @sp_BlitzErik , я думаю, що є певні сценарії, коли це нормально робити, і тому це допоможе мати чіткішу картину того, що насправді тут запитують.
Деякі варіанти врахування, які полегшують більшість негативних аспектів, на які вказував Ерік, є:
Обидва ці варіанти розроблені як посередництво між збереженням BLOB або повністю в SQL Server, або повністю зовні (за винятком рядкового кола для збереження шляху). Вони дозволяють BLOB, щоб вони були частиною моделі даних та брали участь в Операціях, не витрачаючи при цьому місця в буферному пулі (тобто пам'яті). Дані BLOB все ще включаються в резервні копії, що дозволяє їм займати більше місця та займати більше часу для резервного копіювання тавідновити. Однак мені важко сприймати це як справжній негатив, враховуючи, що якщо воно є частиною програми, тоді його потрібно якось створити резервну копію, а лише стовпець з рядком, що містить шлях, повністю відключений і дозволяє файлам BLOBs отримувати видалено без вказівки на це в БД (тобто недійсні вказівники / відсутні файли). Це також дозволяє файли "видаляти" всередині БД, але все ще існують у файловій системі, яку в кінцевому підсумку потрібно буде очистити (тобто головний біль). Але якщо файли ВЕЛИЧЕЗНІ, то, можливо, найкраще залишити повністю поза SQL Server, крім стовпця шляху.
Це допомагає у питанні "всередині або зовні", але не стосується питання однієї таблиці проти кількох таблиць. Я можу сказати, що поза цим конкретним питанням, безумовно, є вагомі випадки поділу таблиць на групи стовпців на основі моделей використання. Часто, коли в них є 50 або більше стовпців, є такі, до яких часто звертаються, а інші - ні. Деякі колонки записуються часто, а деякі в основному читаються. Відокремлення часто доступних та нечасто доступних стовпців до кількох таблиць із співвідношенням 1: 1 досить часто вигідно, тому що чому витрачати простір у буферному пулі на дані, які ви, мабуть, не використовуєте (подібно до того, як зберігати великі зображення в звичайнихVARBINARY(MAX)
стовпці - це проблема)? Ви також збільшуєте продуктивність стовпців, що часто отримують доступ, зменшуючи розмір рядків і, отже, поміщаючи більше рядків на сторінку даних, роблячи читання (фізичні та логічні) більш ефективними. Звичайно, ви також вводите деяку неефективність, потребуючи дублювання ПК, і тепер іноді вам потрібно з'єднати дві таблиці, що також ускладнює (навіть якщо трохи) деякі запити.
Отже, ви можете скористатися кількома підходами, і що найкраще залежить від вашого оточення та того, що ви намагаєтеся виконати.
У мене було враження, що SQL Server зберігає лише вказівник на деяку виділену структуру даних BLOB у таблиці
Не так просто. Тут ви можете знайти добру інформацію. Який розмір покажчика LOB для типів (MAX) типу Varchar, Varbinary, Etc? , але основи:
TEXT
, NTEXT
та IMAGE
типи даних (за замовчуванням): 16-байтний покажчик
VARCHAR(MAX)
, NVARCHAR(MAX)
, VARBINARY(MAX)
(За замовчуванням):
- Якщо дані можуть вміститися в рядку, то вони будуть розміщені там
- Якщо дані менше ок. 40 000 байтів (пов’язана публікація в блозі показує 40 000 як верхня межа, але моє тестування показало дещо вищу величину) І якщо в рядку буде місце для цієї структури, то буде між 1 і 5 прямими посиланнями на сторінки LOB, починаючи з 24 байти за перше посилання на перші 8000 байт, і збільшиться на 12 байт за кожне додаткове посилання для кожного додаткового набору 8000 байт, максимум до 72 байт.
- Якщо дані перевищують прибл. 40 000 байт АБО не вистачає місця для зберігання відповідної кількості прямих посилань (наприклад, лише 40 байтів, що залишилися в рядку, а значення 20 000 байт потребує 3 посилання, що становить 24 байти для першого плюс 12 для двох додаткових посилань на 48 байт загальний необхідний простір у рядку), тоді буде просто 24-байтний вказівник на сторінку текстового дерева, яка містить посилання на сторінки LOB).