Можливість перепроектування баз даних: який дизайн таблиці використовувати для цього збору даних датчика?


13

Фон

У мене є мережа приблизно з 2000 датчиків, кожен з яких має близько 100 точок даних, які ми збираємо на 10-хвилинних інтервалах. Ці точки даних є типово значеннями int, але деякі - це рядки та поплавці. Ці дані повинні зберігатися протягом 90 днів, якщо це можливо, ще ефективніше.

Дизайн баз даних

Первісно поставивши завдання цього проекту, я написав додаток C #, який писав файли, розділені комами для кожного датчика. У той час їх було не так багато, коли хтось захотів подивитися на тенденції, ми відкриємо csv в Excel і графікуємо за потребою.

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

Для наступної версії я перейшов на Microsoft SQL Server Express і перемістив усі сенсорні дані в одну велику таблицю. Це також працює, і дозволяє нам робити запити, щоб знайти значення серед усіх цікавих датчиків. Однак я зіткнувся з обмеженням 10 Гб для версії Express і вирішив перейти на MySQL, а не інвестувати в стандарт SQL Server.

Питання

Я задоволений продуктивністю та масштабованістю MySQL, але впевнений, що найкраще дотримуватися підходу «всі дані в одному столі». 10 Гб в одній таблиці, схоже, вимагають іншого дизайну. Я мушу зазначити, що необхідність запиту даних для графіки все ще існує, і я переживаю, що виникнуть проблеми з виконанням запиту, який графікує, наприклад, дані про температуру для одного датчика протягом 90 днів. (Іншими словами, графік повинен бути швидким для створення, не чекаючи, коли SQL розбереться через купи даних лише для того, щоб виділити цікавий датчик.)

Чи слід розділити цю таблицю якимось чином для підвищення продуктивності? Або не незвично мати такий великий стіл?

У мене є індекси на стовпчиках Sensor і Timestamp, що в значній мірі визначає межі для будь-якого запиту. (тобто отримати дані для датчика X час від часу А до часу В).

Я читав трохи про заточування та розбиття, але не вважаю, що це доречно в цьому випадку.


Редагувати:

На основі зауважень та відповідей, деякі додаткові відомості можуть бути корисними:

Не невизначене зберігання: На даний момент я не зберігаю дані за останні 90 днів. Щодня я запускаю запит, який видаляє дані старші 90 днів. Якщо це стане важливим у майбутньому, я буду зберігати більше, але поки це достатньо. Це допомагає підтримувати розмір перевірки та високої продуктивності (er).

Тип двигуна: в оригінальній реалізації MySQL використовується MyISAM. Цього разу створюючи таблиці для нової реалізації (одна таблиця даних замість багатьох), вони встановили дефолт у InnoDB. Я не вірю, що у мене є вимога до того чи іншого.

Нормалізація: Окрім таблиці збору даних, звичайно, є й інші таблиці. У цих таблицях підтримки зберігаються такі речі, як мережева інформація для датчиків, інформація про вхід для користувачів тощо. Нормалізувати не багато (наскільки я знаю). Причина, що в таблиці даних є стільки стовпців, полягає в тому, що існує багато змінних від кожного датчика. (Багаторазові температури, рівень освітлення, тиск повітря і т. Д.) Нормалізація для мене означає, що немає зайвих даних або повторюваних груп. (Принаймні для 1NF.) Для даного датчика для зберігання всіх значень у певний час потрібен один ряд даних, і там немає жодних зв’язків 1: N (що я бачу).

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


Редагувати 2:

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

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

З цієї причини я стверджував, що близько 100 точок даних збираються та зберігаються, навіть якщо значення є сумнівним. Але при звичайному щоденному використанні користувачі, як правило, вивчають, можливо, десяток цих параметрів. Якщо користувач зацікавиться певним географічним районом, він може (використовуючи програмне забезпечення) генерувати графіки або електронні таблиці даних, можливо, на кілька десятків датчиків. Не рідкість дивитися на 30-денний графік з двома-трьома сюжетними лініями, що показують такі речі, як температура, тиск повітря та рівень освітлення. Для цього буде запущений запит, подібний до цього:

SELECT sensor_id, location, data_timestamp, temp1, air1, light1
FROM data
WHERE data_timestamp >= '2012-02-01'
AND sensor_id IN (1, 2, 3);

(У оригінальній версії MySQL, де у кожного датчика була своя таблиця, було б видано три окремі запити, але результати об'єднані в програмне забезпечення для створення графіка.)

Оскільки в dataтаблиці міститься стільки рядків (~ 10 мільйонів), незважаючи на індекси idта data_timestamp, продуктивність помітно гірша, ніж сценарій з декількома таблицями (4500 рядків повернулися за 9 секунд на відміну від менш ніж однієї секунди з цим прикладом). Можливість знайти, які датчики відповідають певним критеріям, практично дорівнює нулю в схемі з декількома таблицями, і, отже, причина переходу до однієї таблиці.

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

Дані відкидаються через 90 днів. Це може бути заархівовано, але наразі це не є вимогою.

Сподіваємось, ця інформація допомагає більш адекватно показати, як дані використовуються після збору та зберігання.


Щоб отримати правильну відповідь на це запитання, ви, мабуть, слід розширити питання про те, як фактично використовуються дані. Ви випереджаєте криву глибини інформації, яку ви надали до цього часу, але, можливо, ви ставите своє запитання з іншого боку.
Марк Сторі-Сміт

Хороший момент, @Mark, я також докладно розповім про це. Я намагався не мати занадто довгого питання, боюсь, що він переможе.
JYelton

Відповіді:


5

Вам варто подумати про розділення столу з великої причини.

Усі індекси, які ви маєте на гігантській таблиці, навіть лише один індекс, можуть генерувати велику кількість завантаження процесора та дискових вводу / виводу просто для виконання обслуговування індексу при виконанні INSERT, UPDATE та DELETE.

Я написав попереднє повідомлення ще 7 жовтня 2011 року про те, чому розділення таблиці буде великою допомогою. Ось один уривок з мого минулого допису:

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

Пізніше про це можна прочитати весь мій пост .

Щоб вирізати право на погоню, вам потрібно дослідити та з’ясувати, які дані рідко використовуються у вашій таблиці 10 ГБ. Ці дані повинні бути розміщені в архівній таблиці, яка є легкодоступною, якщо вам потрібні відповідні запити історичного характеру. Міграція архіву з 10 ГБ, а потім OPTIMIZE TABLEтаблиці 10 ГБ, може призвести до швидкого запуску робочого набору SELECT, INSERT, UPDATE та DELETE. Навіть DDL буде працювати швидше на 2 Гб, ніж на 10 ГБ.

ОНОВЛЕННЯ 2012-02-24 16:19 EDT

Два моменти для розгляду

  1. З вашого коментаря, звучить, як нормалізація - це те, що вам може знадобитися.
  2. Можливо, вам доведеться перенести все, що старше 90 днів, в архівну таблицю, але все одно отримати доступ до архіву та робочого набору одночасно. Якщо ваші дані - це MyISAM, рекомендую використовувати механізм зберігання даних MERGE. По-перше, ви створюєте карту таблиці MERGE один раз, яка об'єднує робочу таблицю MyISAM та архівну таблицю MyISAM. Ви зберігаєте дані менше 91 дня в одній таблиці MyISAM, а будь-які дані, старіші за 90 днів, повертати в архів. Ви б запитували лише таблицю MERGE таблиці.

Ось два повідомлення, якими я користувався:

Ось додатковий пост, який я зробив на таблицях з великою кількістю стовпців

Забагато стовпців у MySQL


Є колонки, які рідше потрібні, але всі датчики приділяють приблизно однаковий відсоток уваги. Таким чином, я можу уявити, що розділення таблиці вертикально було б вигідним. Наприклад, таблиця з 20 стовпцями (часто звертається) та таблиця з 80 стовпцями (нечасто доступними). Я не впевнений, що це те саме, що і розділення.
JYelton

Дякуємо за редагування Я читав вашу публікацію про "Забагато стовпців у MySQL." Я відредагую своє запитання деякими додатковими пунктами, які можуть бути корисними.
JYelton

5

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

Чи 90 днів - це звичайний проміжок часу, на який ви створюєте графік? Якщо так, у вас можуть бути дві таблиці: основна таблиця даних датчика, яка зберігає дані від 90 (або трохи більше, якщо ви хочете трохи промахуватися) днів тому до сьогодні, і все старіше, ніж це, входить в таблицю архіву. Це може допомогти зменшити розмір таблиці, з якої починаються згенеровані звіти, і, сподіваємось, більшість ваших даних 10 ГБ будуть знаходитися в таблиці архівів, а не в головній таблиці. Задачу архівації можна планувати виконувати щоночі.

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


Зберігати що-небудь за останні 90 днів до цього часу не потрібно, але було б добре. Я погоджуюся, що найкраще зберігати в таблиці «архіву». Графіки та аналіз даних коливаються від декількох годин до повних 90 днів. Більшість запитів на графік використовують лише дані за останній тиждень або близько того, але 90-денні графіки є загальними. Наша фірма не (ще) не вимагала більш тривалих звітів.
JYelton

@JYelton: У такому підході ти можеш мати стільки рівнів, скільки хочеш. Найсвіжіша таблиця могла мати лише сьогоднішній день. Наступна таблиця могла б скласти від сьогодні до 2 тижнів тому. Наступний стіл міг би мати від сьогодні до 90 днів тому. Останній стіл міг ВСЕ.
FrustratedWithFormsDesigner

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

@JYelton: Так, я думаю, ви правильно це розумієте. Якщо діапазони періодів запиту є стандартними (сьогодні - 1 день, сьогодні - 7 днів, сьогодні - 30 днів, сьогодні - 90 днів), то я не думаю, що це буде занадто складно, оскільки ви завжди будете знати, до якої таблиці слід хіт. Якщо часові діапазони можуть бути різної тривалості, коли початок діапазону може бути не поточною датою, то ви виправляєте логіку, що впроваджувати ви отримаєте складні запити і запити, що перехресні таблиці можуть дорогувати при операціях UNION на кількох таблицях.
FrustratedWithFormsDesigner
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.