При работе с IoT-устройствами через Zigbee2MQTT и MySQL часто возникает соблазн просто сохранять каждое поле JSON-сообщения как отдельную строку. Это удобно для отображения, но ломает управление — особенно для многоканальных устройств вроде fish_power с каналами state_l1…state_l5.
sensor_data.zigbee2mqtt/fish_power/state_l1).UNIQUE KEY(topic) — MariaDB ругалась на дубли.SQLSTATE[HY000]: General error: 1267 Illegal mix of collations — из-за несовместимых кодировок между таблицами.Использовал оконную функцию ROW_NUMBER() в MariaDB 10.11:
CREATE TABLE sensor_data_clean AS
SELECT topic, value, timestamp
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY topic ORDER BY timestamp DESC) AS rn
FROM sensor_data
) t
WHERE rn = 1;
Это оставило только последнее значение для каждого топика.
После чистки — сделал topic первичным ключом:
ALTER TABLE sensor_data ADD PRIMARY KEY (topic);
Теперь каждое устройство представлено ровно одной строкой — актуальное состояние всегда под рукой.
Оказалось, часть таблиц использовала utf8mb4_general_ci, а часть — utf8mb4_unicode_ci. Это ломало JOIN-запросы.
Привёл всё к единому стандарту:
ALTER TABLE automations CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE sensor_history CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- и другие проблемные таблицы
Теперь все текстовые поля совместимы.
sensor_dataON DUPLICATE KEY UPDATEСистема стала быстрее, надёжнее и проще в поддержке. А главное — теперь можно строить адекватную веб-панель, где одно устройство = одна карточка, а не десяток разрозненных полей.
P.S. Всегда делайте бэкап перед ALTER TABLE — даже на Raspberry Pi!
Блог только запустил, все статьи генерирую через нейросеть т.к. лень, возможны ошибки. Просто чтобы вы знали и не запускали ядерный реактор по моим статьям ))
Если у вас есть вопросы, или Нашли неточность? пишите в коментах — вместе поправим и сделаем статью более качественной. Я лично объясню нюансы из практики.
Комментарии
Пока нет комментариев. Будьте первым!