Дизайн бази даних SQL Server для "архівованих, але доступних" даних


12

У нас є ця велика база даних (> 1 ТБ), яку ми маємо намір "скоротити". База даних обертається навколо однієї основної сутності, назвемо її "Відвідати". Для обговорення скажімо, що це база даних для медичної практики.

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

База даних накопичила приблизно 12 років даних з 2000 року. Хтось запропонував нам тричі три роки зберігати дані у "живій" версії, а решта жити у базі даних "old_data". Дата ТОЛЬКО зберігається в таблиці "Відвідування", оскільки вона нормалізується. Таблиця відвідувань також містить ROWVERSIONстовпчик та BIGINTпсевдо-ідентичність (кластер). Скажімо, для всіх намірів і цілей, скажімо, що кластеризаційний ключ заповнений SEQUENCE (SQL Server 2012 Enterprise) - ми його назвемо cid.

Це visit.dateне завжди в тому ж порядку, що і клавіш кластеризації, наприклад, коли лікар відвідує розширені візити та повертається зі своїм "портфелем" даних, він об'єднується в основну таблицю. Також є кілька оновлень таблиці "візит", які призведуть до того, що ROWVERSIONстовпець не синхронізується як із стовпцями, так cidі зі dateстовпцями - простіше кажучи, з цього приводу не робиться ROWVERSIONі cidвідповідних ключів розділу.

Ділове правило для видалення даних із "прямого" є те, що кількість людей visit.dateповинна перевищувати 36 місяців, аvisit_payment запис про дітей повинен існувати. Крім того, база даних "old_data" не містить жодної базової таблиці, за винятком visit%.

Отже, ми закінчуємо:

Жива БД (щоденне використання) - Усі таблиці БД старих даних - старі дані для visit%таблиць

Пропозиція вимагає створення комбінованої БД, яка є оболонкою, що містить синоніми до ВСІХ базових таблиць Live DB(крім visit%), а також перегляди, які ОБ'ЄДНУЮТЬ ВСІ в visit%таблицях у двох базах даних.

Припускаючи , що одні і ті ж індекси , які створюються в Old-DataБД, будуть запити добре виконувати на UNION-ALL Переглядів ? Який типу шаблонів запитів може підніжку плану виконання для UNION-ALL Переглядів ?


3
Яка мотивація а) архівувати старі дані та б) зберігати їх доступними? Технічне обслуговування накладних витрат? Проблеми з роботою? Потрібно, щоб заархівовані дані були безперешкодно доступними для програми? З модифікацією додатку чи без нього?
Марк Сторі-Сміт

(a) Маючи основний db малим. Він реплікується на 3 інші envs - dev, pre-test, test. Також є тиражувані дзеркала та резервні копії, які підтримуються дорогим сховищем. (b) Оскільки нині поточні системи мають доступ до всіх даних, то це підтримує статус-кво. (c) Екземпляр програми може працювати проти "комбінованого" БД з усіма переглядами, але я підозрюю, що він може не працювати взагалі.
孔夫子

Просто для уточнення, заархівовані дані все ще читаються-записуються, правильно? Або це лише для читання?
Джон Сейгель

Старі дані будуть змінені на сторінки, які доступні лише для читання та на 100%. Екземпляр програми, яка підключається до комбінованих поглядів, може призвести до помилок, якщо хтось спробує щось нерозумно на старих даних - нас це не хвилює.
孔夫子

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

Відповіді:


4

Для зручності припустімо, що пряму базу даних називають LiveDbі базу даних AchiveArchiveDb

  • Додайте перегляд UNION ALL для LiveDbвказівки на таблиці в ArchiveDbбазі даних за допомогою синоніма (Не потрібно робити комбінований db із синонімами)
  • "Розділити" на visit.dateта денормалізувати цей стовпець visit_paymentsтеж, якщо його там ще немає (це покращує спільне розташування приєднання)
  • Заархівуйте лише дві великі таблиці, якщо це можливо (зменшує ймовірність спрацьовування оптимізатора). Зберігайте перегляд UNION ALL та інші таблиці, LiveDbщоб усі приєднання до менших таблиць зберігалися на локальному рівні
  • Додати СНЕСК на столах в обох LiveDbі ArchiveDb що описує діапазон , visit.dateщо містяться в таблиці. Це допомагає оптимізатору усунути таблицю архіву як із пошуків, так і сканів, що містять стовпець visit.data. Вам доведеться періодично оновлювати це обмеження.
  • У поданні UNION ALL додайте критерії WHERE, які фільтруються visit.data. Це додатково до натяку, який ви вже надали у обмеженні чека. Це максимально збільшує шанс натискання фільтрів вниз
  • Якщо у вас є EE, розділіть таблицю в базі даних архіву (Але НЕ в реальній базі даних). Якщо ви хочете по-справжньому фантазувати, використовуйте резервне копіювання / відновлення архівів баз даних на рівні файлових груп, щоб заощадити на час резервного копіювання.
  • Розгляньте можливість перевести AchiveDbв простий режим відновлення, якщо його ще немає. Вам, швидше за все, не знадобляться резервні копії журналу транзакційArchiveDb
  • Використовуйте INSERT ... WITH (TABLOCK) SELECT ... WITH (ROWLOCK) для примусового мінімуму входу в пункт призначення при переміщенні даних між LiveDbіArchiveDb

Все вищесказане не гарантує, що оптимізатор усуне архівні таблиці від пошуків і сканувань, але це робить більш імовірним.

Коли усунення не відбувається. Це ефект, який ви можете бачити (цей список може бути неповним). Для пошукових запитів ви отримаєте додатковий пошук за кожним запитом (це збільшує IOPS). Для сканувань результати можуть бути згубними для продуктивності, оскільки ви можете закінчити сканування і архіву, і живих таблиць. Ось типові способи подолання оптимізатора:

  • Якщо ви visit%об'єднаєте таблиці разом і не включаєте visit.dataкритерії об'єднання (саме тому ви хочете денормалізувати). Через це ви можете змінити деякі запити
  • Якщо ви отримаєте хеш-з'єднання між visit.dataта іншою таблицею (наприклад, параметр дати), ви не зможете отримати правильне усунення таблиць
  • Якщо ви спробуєте агрегувати дані за заархівованими таблицями
  • Якщо ви фільтруєте щось, але НЕ visit.data, наприклад, шукайте безпосередньо по клавіші подання.

Для останнього сценарію ви можете захистити себе від найгірших наслідків, додавши ще одне обмеження перевірки на cid- якщо це можливо. Ви згадали, що послідовність cidне "чистої" щодо дат та просування рядків у таблиці. Однак ви могли б підтримувати таблицю, яка містить інформацію: "З цього часу немає cidвище цього числа visit.data" чи подібні? Це може призвести до додаткового обмеження.

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

До речі, якщо ви добре знаєте запити - можливо, вам навіть не знадобляться однакові індекси у двох базах даних (це передбачає, що ви на 100% впевнені, що отримаєте правильне усунення таблиць). Можна навіть розглянути можливість використання магазинів стовпців для ArchiveDb.


-1

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


Для підтримання сумісності додатків операційна програма повинна йти далі, ніж це. Ви читали питання?
Джон Сейгель
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.