Страницы

Поиск по вопросам

среда, 20 февраля 2019 г.

Как правильно организовать структуру бд

Вводная:
Есть таблица sms которая содержит данные об ожидающей отправки sms. Так же есть таблица text_patterns, которая хранит текстовые шаблоны, подготовленные пользователем. В таблице sms есть поле pattern_id - связь с текстовым шаблоном
Пользователь загружает csv файл в систему. В файле csv список на какой номер какой текстовый шаблон отправить. 2 колонки. Номер, id шаблона.
Сейчас все это обрабатывается и работает
Задача:
Хотим добавить фичу, чтобы во второй колонке можно было писать не только существующий текстовый шаблон, но и сам текст для отправки. Т.е. я буду смотреть что в этом поле - если цифра, то это текстовый шаблон, а если строка - то какая-то новая логика обработки.
Никак не могу понять, как мне хранить эти данные в базе.
Варианты решения:
Если текст, то создавать новый текстовый шаблон в таблице text_patterns и дальше работать по старой схеме. Решение не нравится, т.к. шаблоны могу быть очень уникальны и получится для каждого номера свой отдельный шаблон. Пропадает логика шаблонов. Добавить в таблицу sms текстовое поле в котором хранить значение. т.е. добавить поле sms_text и признак связи с тестовым шаблоном is_pattern (0|1). Решение не нравится т.к. у нас будут пустые поля на каждой строке, либо pattern_id либо sms_text. Так же для дальнейшей обработки данных мне нужно будет все время писать 2 запроса вместо одного. Один для sms с шаблонами, другой для sms с кастомным текстом.
Может есть какие-то более красивые решения ?


Ответ

Ваш второй вариант похож на правду, только его надо немного доделать. Нужны два поля: id-шаблона и текст шаблона, оба поля допускают значения NULL. id-шаблона должен быть foraign key, указывающий на таблицу с шаблонами. Не пугайтесь NULL значений, СУБД фактически их не хранит, например MySQL для таких полей хранит один бит в заголовке записи показывающий есть поле или нет, другие СУБД действуют примерно так же. Никакого признака есть "уникальный шаблон" или нет, в записи не нужно, сам факт присутствия текста в поле sms_text является признаком. На уровне триггеров можно не допускать вставки записей где заполнены оба поля или не заполнено ни одно из них.
Так же для получения текущего шаблона два запроса не нужно, все решается одним запросом:
select ..., coalesce(T.text,S.sms_text) from sms S left join text_patterns T on T.id=S.pattern_id
Мы объединяем таблицы по LEFT JOIN, таким образом, если поле pattern_id пустое - то запрос все равно вернет запись, только в ней текст из таблицы шаблонов будет NULL. Функция coalesce() даст первое из перечисленных полей, которое НЕ NULL, т.е. если id-шаблона задан и запись в шаблонах найдена, то текст будет взят от туда, если шаблон не задан, то текст будет взят из поля sms_text в самой записи таблицы sms. Возможно стоит переставить местами аргументы, тогда текст из самого sms будет иметь приоритет над найденным в шаблонах в случае если оба поля заполнены.

Комментариев нет:

Отправить комментарий