Яндекс.Метрика

    Ни о чём

    СУБД: абстрагируя конкретизируй

    Нет, не очередное ORM, слава богу. Я хочу поговорить всего лишь о подходе к работе с абстрактной СУБД и парадоксальном эффекте, когда более конкретизируя модели данных, мы получаем бОльшую абстракцию СУБД.
    Сегодня традиционный подход в проектировании задач, как бы автоматически подразумевает SQL СУБД. Подставляя перед самым последним слоем в системе прокладку с громким названием «абстракция СУБД». А от чего мы абстрагируемся? От MySQL, Postgrеss и прочих SQL, повернутых боком. Если придираться, то это наверное будет «абстракция SQL», потому что есть много других типов СУБД.

    Создавая модель данных проекта мы уже изначально думаем таблицами, джойнами и юнионами. Мы заражены SQL. Это кажется настолько естественным, что проектировщики совершают определенную идеологическую ошибку и это не считается дурным тоном, за это не стыдно. Я говорю о том, что модель данных, как некая самостоятельная часть проекта вдруг разделяется между двумя компонентами: вычислительной моделью и хранилищем. Хранимые процедуры как-то переносят модель данных чуть больше в хранилище, но не целиком. Таким образом мы получаем следущеи негативные моменты такой концепции:

    — невозможность использовать не-SQL СУБД
    — нарушается стройность архитектуры
    — ORM страдают избыточным потреблением ресурсов

    Что предлагается, как альтернатива? Во-первых мы целиком помещаем модель данных в состав вычислительной модели. Забываем о SQL базах и таблицах общего назначения. Наша модель данных будет независимой, объектной и базироваться на конретной вычислительной модели, будет говорить в ее терминах, а не в терминах таблиц. Мы придумываем интерфейс или API, совершенно не заботясь, в каких оно там таблицах-шмаблицах будет храниться.

    Когда интерфейс определен, то можно создать драйвер, который соединит нашу модель с конкретной СУБД. Вот это будет полная абстракция. Подключать можно любую SQL, хоть файлы и даже BigTable, которая уже стоит на пороге. А сам драйвер будет всегда идеально заточен под конкретный вид хранилища и потери будут минимализированы.

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

    — полная абстракция СУБД
    — сохранение стройности архитектуры
    — отсутствие потерь скорости на ORM

    Естественно при таком подходе есть тоже свои нюансы. При определенных запросах может возникнуть оверхед. Например вы запрашиваете список продуктов:

    $products->getAll()

    Драйвер для этого перелопатит всю табицу, сделав пару-тройку джойнов, а вам на самом деле-то нужны были только ID продукта и его название. Я вижу решение в следующем. Я сказал, что не надо заботиться, как там данные храниться будут. Да это так, но не надо уж быть полным снобом. Мы же понимаем, что в 99% случаев хранилище будет каким-то реляционным. Поэтому помогите драйверу при проектировании интерфейса/API. Создайте дополнительный метод или предусмотрите параметр:

    $products->getIndex() или $products->getAll(‘brief’)

    Вот таким примерно образом мы создаем совершенно конкретную модель данных с полностью абстрактной СУБД. Использование ORM при этом теряет всякий смысл. Даже применение его внутри драйвера будет сомнительным, поскольку все его объектные прелести общего назначения не нужны. У нас уже есть конкретные, удобные, хорошо подоганные под цели приложения объекты в модели.