Динамическое создание новых моделей активных записей и таблиц базы данных

#ruby-on-rails #ruby #database

#ruby-on-rails #ruby #База данных

Вопрос:

Я не уверен точно, как мне следует назвать этот вопрос. Я только начал программировать на стороне сервера, и мне нужна некоторая помощь.

Все руководства, которые я прочитал до сих пор по RoR, касаются создания предопределенной таблицы и предопределенных полей (id, name, email и т.д. и т.п.). Они используют ActiveRecord в качестве базового класса, а сохранение в db обрабатывается автоматически суперклассом.

То, что я пытаюсь запрограммировать, — это то, что позволяет использовать определяемую пользователем таблицу с полями. Поэтому подумайте об этом так. В веб-интерфейсе появится пустая таблица, пользователь назовет таблицу и добавит столбцы (поле), после чего добавит строки, а затем позже сохранит ее. Как бы я это реализовал? Я не прошу подробностей, просто обзор этого. Как я уже сказал, все руководства, которые я прочитал до сих пор, имеют дело с предопределенными таблицами с полями, в которых предопределен подкласс ActiveRecord.

Итак, в двух словах, я спрашиваю, как создавать таблицы в БД во времени выполнения и добавлять поля в таблицы.

Надеюсь, я выразился ясно, если нет, пожалуйста, дайте мне знать, и я постараюсь немного подробнее. Спасибо.

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

1. Если вы только начинаете с веб-программирования на стороне сервера, как насчет того, чтобы начать с Hello world? 🙂 Из вашего вопроса следует, что вы хотите создать базу данных, управляемую вебом, с целым набором метапрограммирования. Я предлагаю предпринять постепенные шаги к этому. Я могу в некоторой степени представить, как можно сделать то, что вы хотите, просто не объясняя это в «just starting server side programming speak». Я имею в виду это самым приятным образом. Ya?

2. Позволить обычным пользователям быть вашим разработчиком базы данных — рискованный бизнес.

3. То, что вы пытаетесь сделать, на самом деле ОЧЕНЬ ПРОДВИНУТАЯ и в принципе плохая идея даже тогда (но на самом деле довольно распространенная для новичков!). Пользователи системы должны хранить данные. Использовать их для создания таблиц — просто неудачный подход и плохая идея, если, возможно, у вас нет большого опыта работы с СУБД. Создателю схемы (в данном случае вам) просто нужно создать гибкие структуры данных, в которых будет храниться все, что вам нужно. Просто забудьте о пользовательском подходе к созданию таблиц. В конце концов, они тоже будут создавать индексы? Понимают ли они unique? Понимают ли они объединения? составные ключи? да.

4. 0xSina что-то спросила. Поэтому, пожалуйста, программисты, ответьте каким-либо образом или нет. Я не понимаю комментариев «плохая идея, не делайте так». У меня та же проблема, что и у 0xSina, и я не хочу разрешать клиенту создавать базу данных, но он просто хочет оплатить такое приложение. И что теперь делать?

Ответ №1:

Если вы не создаете инструмент администрирования БД (и даже, возможно, тогда), предоставление пользователю прямого доступа к уровню базы данных предлагаемым вами способом, вероятно, является плохой идеей. Помимо проблем со стабильностью и безопасностью, это будет очень медленно, если ваши пользователи будут создавать много таблиц.

Например, если вы хотите выполнить поиск определенного значения в 100 таблицах ваших пользователей, вам пришлось бы выполнить 100 отдельных запросов. Сайт будет работать экспоненциально медленнее, чем больше пользовательских таблиц будет создано.

Более разумным способом сделать это может быть создание табличной модели, подобной этой

 class Table < ActiveRecord::Base
  has_many :fields
  has_many :rows
end
  

К каждой таблице были бы прикреплены поля и строки для хранения соответствующих данных (которые были бы каким-то образом закодированы).

Однако, как справедливо отмечает @Aditya, на самом деле это не для начинающих!

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

1. Это антишаблон «внутренней платформы». Вы создаете «внутреннюю» базу данных, используя существующую платформу базы данных, которая будет работать плохо и ее будет сложнее понять, чем простое создание и модификация реальных таблиц. Для него было бы лучше динамически изменять схему отдельной базы данных или схему из приложения, с соблюдением определенных мер безопасности, конечно. Я согласен, что это, конечно, не для начинающих.

Ответ №2:

В целом я согласен с предыдущими ответами. Из вашего вопроса неясно, почему вы хотите создать таблицу во время выполнения. На самом деле не очевидно, в чем было бы преимущество этого. Если вы просто пытаетесь сохранить данные, которые, кажется, вписываются в таблицу со строками и столбцами, почему бы просто не сохранить их в виде массива в поле вашей пользовательской таблицы. Если вашему пользователю разрешено создавать много таблиц, то у вас может быть что-то вроде

 class User < ActiveRecord::Base
     has_many :tables
  end
  

и тогда в каждой таблице может быть поле для хранения сериализованного массива. Или вы могли бы последовать предложению Алекса — лучший выбор действительно зависит от того, что вы собираетесь делать с данными, как часто они меняются, нужно ли вам их искать и так далее …

Ответ №3:

Вы можете создать базу данных, как показано в руководствах, в которой хранятся названия таблиц и их столбцов, которые нужны вашему пользователю. Затем у вас может быть worker (который может быть собран с использованием Redis и Resque, здесь все просто для Resque и Redis) и пусть эти worker запустят миграцию (запишите миграцию с переменными и используйте параметры для их замены) для вас для новой таблицы в БД, как только в базе данных будет внесена новая запись. Скажите мне, если у вас есть вопросы по этому поводу.

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

1. он ТОЛЬКО НАЧИНАЕТ. «который может быть собран с использованием Redis и Resque» — это безумие.