Ефективне зберігання наборів пар ключових значень з дивовижними різними ключами


9

Я успадкував додаток, який асоціює багато сайтів із різними видами діяльності. Існує приблизно 100 різних типів діяльності, і кожен має різний набір 3-10 полів. Однак усі види діяльності мають принаймні одне поле дати (може бути будь-яка комбінація дати, дати початку, дати закінчення, запланованої дати початку тощо) та одного поля відповідальної особи. Усі інші поля сильно відрізняються, і поле дати дати необов’язково називатиметься "датою початку".

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

введіть тут опис зображення

Кожна активність має кілька полів активності; на кожному Сайті є кілька заходів, а таблиця SiteActivityData зберігає KVP для кожного SiteActivity.

Це робить (веб-додаток) дуже легким для кодування, тому що все, що вам потрібно зробити, це перебирати записи в SiteActivityData для певної діяльності та додавати до мітки та управління введенням для кожного рядка форму. Але проблем багато:

  • Цілісність погана; можна помістити поле в SiteActivityData, яке не належить до типу активності, а DataValue - це поле варчару, тому цифри та дати потрібно постійно додавати.
  • Повідомлення та спеціальний запит цих даних є складним, схильним до помилок та повільним. Наприклад, для отримання списку всіх видів певного типу, які мають Кінцеву дату у визначеному діапазоні, потрібні повороти та лиття вархарів до дат. Автори звітів ненавидять цю схему, і я не звинувачую їх.

Тож, що я шукаю, це спосіб зберігати велику кількість видів діяльності, які майже не мають спільних полів, щоб полегшити звітність. Я придумав поки що - це використовувати XML для зберігання даних про активність у форматі псевдо-noSQL:

введіть тут опис зображення

Таблиця активності міститиме XSD для кожної діяльності, виключаючи потребу в таблиці ActivityField. SiteActivity міститиме XML-значення ключового значення, тому кожна діяльність для сайту тепер буде в одному рядку.

Діяльність виглядатиме приблизно так (але я ще не розробив її повністю):

<SomeActivityType>
  <SomeDateField type="StartDate">2000-01-01</SomeDateField>
  <AnotherDateField type="EndDate">2011-01-01</AnotherDateField>
  <EmployeeId type="ResponsiblePerson">1234</EmployeeId>
  <SomeTextField>blah blah</SomeTextField>
  ...

Переваги:

  • XSD перевірить XML, вловлюючи помилки, такі як введення рядка в числове поле на рівні бази даних, що було неможливо зі старою схемою, яка зберігала все у varchar.
  • Набір записів KVP, які використовуються для побудови веб-форм, можна легко відтворити за допомогою select ... from ActivityXML.nodes('/SomeActivityType/*') as T(r)
  • Підзапрос xpath XML може бути використаний для створення набору результатів, який містить стовпці для дати початку, дати закінчення тощо, не використовуючи поворот, щось подібне select ActivityXML.value('.[@type=StartDate]', 'datetime') as StartDate, ActivityXML.value('.[@type=EndDate]', 'datetime') as EndDate from SiteActivity where...

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

Додатковий запитання: Якщо я визначаю тег як тип даних дати в XSD, використовуючи xs:date, чи буде SQL Server індексувати його як значення дати? Мене хвилює, якщо я запитую за датою, потрібно буде привести рядок дати до значення дати та створити будь-який шанс використання індексу.


Наскільки актуальними повинні бути дані звітів? Чи будуть звіти вражати виробництво?
Джеймс Андерсон

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

Скільки перекриттів у полях? Чи охоплюють десять полів усі 100 підтипів, чи є ~ 500 повністю розрізнених полів?
Йон усіх торгів

Є 72 поля та 75 видів діяльності. 30 полів використовується лише однією діяльністю, а більшість решти використовується 5-10 видами діяльності. Існує кілька полів, які використовуються ~ 30 різних видів діяльності. Здебільшого існує не так багато спільного в діяльності.
Пол Абботт

Відповіді:


7

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

Спочатку не вистачає респондентів, щоб коментувати, тож ми йдемо!

Якщо основною метою є звітування, і у вас є DW (навіть якщо це не зіркова схема), я б рекомендував спробувати перетворити це на зіркову схему. Переваги - швидкі, прості запити. Мінус - ETL, але ви вже розглядаєте можливість переміщення даних до нового дизайну, а схема ETL до зірки, швидше за все, простіша в створенні та підтримці, ніж рішення для обгортки XML (а SSIS включений у ваше ліцензування на SQL Server). Плюс це запускає процес визнаного дизайну звітності / аналітики.

Тож як це зробити ... Здається, у вас є те, що відомо як Факт безрезультатних . Це перетин атрибутів, які визначають подію без пов’язаної міри (наприклад, ціна продажу). У вас є дати для деяких чи всіх заходів? Ймовірно, у вас дійсно має бути перетин активності, сайту та дат (и).

DimActivity- Я здогадуюсь, що існує закономірність, яка може дозволити вам розділити їх на принаймні відносно спільні стовпці. Якщо так, у вас може бути три? п’ять? розміри для занять. У гіршому випадку у вас є кілька послідовних стовпців, наприклад, ім'я діяльності, ви можете фільтрувати, а для залишків випадкових деталей ви залишаєте загальні заголовки, такі як "Attribute1" тощо.

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

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

CREATE TABLE [DIM].[Site]
(
 SiteSK INT NOT NULL IDENTITY PRIMARY KEY
,SiteNK INT NOT NULL --source system key
,SiteName VARCHAR(500) NOT NULL
)

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

DimEmployee - ваш XML включив це, якщо це більш загальна зміна в DimPerson, і заповніть відповідними атрибутами особи, оскільки вони доступні і стосуються звітності.

А ваш факт:

FactActivitySite
DimSiteSK - FK to DimSite
DimActivitySK - FK to DimActivity
DimEmployee - FK to DimEmployee
DimDateSK - FK to DimDate

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

Розширте факт дату , щоб все , що вам потрібно: StartDateSK, EndDateSK, ScheduledStartDateSK.

Усі параметри повинні мати невідомий рядок, як правило, з твердим кодом -1 SK. Якщо ви завантажуєте факт, а у активності немає жодної із включених дат, він повинен просто завантажити -1.

Справа в тому, що це сукупність цілих посилань на ваші атрибути, що зберігаються в вимірах, з'єднайте їх разом, і ви отримаєте всі ваші дані в дуже чистому шаблоні з'єднання, а факт, завдяки його типам даних, надзвичайно малий і швидкий. Оскільки ви перебуваєте в SQL Server, додайте індекс магазину стовпців, щоб додатково підвищити продуктивність. Ви можете просто скинути його та відновити під час ETL. Як тільки ви перейдете до SQL 2014+, ви можете записувати до індексів стовпців.

введіть тут опис зображення

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


(запитання від wesdev): @Dave, яким інструментом ERD ви користувалися?
ypercubeᵀᴹ

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