metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2010-10-24 06:39 am

NoSQL vs RDBMS: Too may FOREIGN KEYs

Сижу делаю очередную опердень, и наткнулся на печаль: таблицы содержат сильно больше внешних ключей и вообще структуры/связей (которые в FB основаны на индексах), чем собственно данных. Это после адекватной нормализации и отображения требуемой для расчетов структуры на базу данных. Типа того, что в таблице, где хранятся суммы, 4 поля, из них 3 - это разного рода ссылки на сущности "налогооблагаемый объект", "период расчета", "период уплаты", и одно поле - собственно сумма.
Причем раньше у меня было чисто технологическое ограничение - чем больше таблиц, тем больше приходилось писать вручную sql-скриптов, маппингов "таблицы-объекты", запросов для работы с таблицами. Я поэтому особо не нормализовал, шел по пути типа "нужно 12 месяцев - заводим 12 полей, нужно 4 квартала - заводим 4 поля". А сейчас, во первых, с кодогенератором это ограничение исчезло, а во вторых, 4 квартала и 12 месяцев превратились в "список периодов, диктуемый каждый отчетный год министерству по налогам и сборам Червем из астрального мира".

Т.е. если мы идем по пути "много структур данных и мало кода", который нам в голову диктует функциональщина, то отражение этого дела в RDBMS превращает ее в невероятно запутанный граф, в котором связи занимают больше места чем данные. Если бы это был NoSQL, а наши данные имели явно заметную тенденцию объединятся в объекты (т.е. работа с записями из связанных таблиц ведется всегда вместе), то мы бы просто ложили в NoSQL объект в виде xml/json/любой структурированный текст.
Бинарное представление в NoSQL было бы сильно эффективнее текста в плане размера и обработки, но, во первых для него нужна статическая типизация, схема и тому подобное (чтобы сериализация/десериализация были эффективными), и обработку этого должна делать СУБД, т.к. я совершенно не испытываю желания это все делать.
Кроме того, как уже неоднократно писалось: RDBMS работает эффективнее, т.к. ее данные, условно говоря - это последовательность бинарных записей одинаковой длины, хождение по которым - это +-длина записей. А всякая бинарщина и xml - это парсеры, сериализация и прочий плохо взаимодействующий с кэшами процессоров и выделением памяти тупизм.

В моем случае это все не применимо в принципе - 99% требуемой от разрабатываемого модуля функциональности уже реализовано в виде "Firebird+Универсальный толстый клиент на дельфи", основная обработка ведется SQL запросами и кодом внутри FB. Всунуться сюда с чем-то, хоть отдаленно похожим на NoSQL, невозможно. Т.е. постулат: NoSQL == разработка с нуля, что на данный момент неприемлемо никак.

Но вообще, даже если мы вместо чистого NoSQL придумаем какой-то хитрожопый вариант типа "статически типизированные объекты в бинарном виде", индексы по внутренностям этих объектов для оптимизации запросов, функциональщину в качестве языка запросов, то все равно останется проблема с тем, что объекты теперь не представимы в виде записей постоянной длины (хотя сейчас больше проблема с дисковым i/o, чем с нагрузкой на проц) и что все равно как-то придется идентифицировать объекты независимо от их физического расположения - а это означает опять ID, опять индексы, сопоставляющие ID и физическое расположение, опять связи по этим ID и прочая и прочая.

[identity profile] dair-spb.livejournal.com 2010-10-24 08:11 am (UTC)(link)

12 месяцев - 12 полей - это как???

[identity profile] volodymir-k.livejournal.com 2010-10-24 11:08 am (UTC)(link)
Какой смысл у этой заметки? Сказать, что в этом случае носкл непригодны? Ну да. Они пригодны, если данные имеют сильно выделенную крупную центральную сущность типа "клиент" и не нужно часто делать запросы вида "дайте сумму по поступлениям от бобруйских пенсионеров за чётные недели года через яндекс-деньги." Как только идёт перекос в сторону равноправия сущностей (отчётные периоды, услуги и клиенты) и нужны сложные запросы -- сливай воду.

[identity profile] norguhtar.livejournal.com 2010-10-24 11:25 am (UTC)(link)
Too may FOREIGN KEYs => use ORM!
Офигенно удобно, когда по большей части они скачут по управляющей структуре. Один черт количество SQL запросов будет сравнимо что при чистом SQL что при ORM, а мозгоклюйства на порядок меньше.

[identity profile] sergiej.livejournal.com 2010-10-24 01:33 pm (UTC)(link)
IMHO Денормализация нужна только когда проблемы с производительлностью. Сложность запросов это не беда, если особо не лениться то хоть семиэтажные маты селекты и пишутся и читаются человеком, ну а при ORM ваще нет о чём волноваться.
А вот ежели одна "логически" табличка (читаемая с одной формы или поиска) рассыпалась по 14-ти разным, и при этом 2 тысячи юзверей одновременно этот запрос юзают - прямая путя в денормализацию, запихнул всё в плоскую таблицу (ну или материализовывать) и будет полегче, и плевать на кошерность базы, ибо апгрейд железа для "нормализованной" базы начинает кусаться.

[identity profile] gds.livejournal.com 2010-10-24 07:52 pm (UTC)(link)
не совсем в тему.
Как-то думал над гибридом sql+nosql: по умолчанию все однотипные сущности хранятся в таблице (id:number * serialized:blob). Отдельно хранится "схема" -- что в serialized соответствует чему (типы, т.е.). Запросы писать на sql (да пофиг, на чём), но всё, что касается условий над аттрибутами/связями, преобразовывать в get_mytype_attr(blob, 'my_attr'). То есть, выполняться оно будет, как факт. Далее, как ключевой момент идеи, научиться переносить аттрибуты из сериализованного представления в отдельные столбцы. Переносить -- либо вручную, когда очевидно, что и как будет использоваться, либо по результатам профайлинга. Перенос аттрибута можно оформить полупрозрачным образом: посмотреть, умеет ли субд экономно хранить ещё один блоб, содержащий почти всегда нуллы, и на каждую "миграцию аттрибута" в фоновом режиме заполнять второй блоб (с учётом того, что могут проапдейтить то, что уже перенесено: заставить все update обнулять значение второго блоба). Или же блокировать любой доступ к таблице, добавлять столбец, модифицировать блоб in-place.
Хотя, прикидываю, в большинстве случаев такое нафиг не нужно. С другой стороны, если бы я использовал nosql в больших количествах, то, зная преимущества реляционок, был бы не прочь иметь такое решение.