Как создать общую базу данных, макет которой может меняться со временем?

Вот сложный вопрос: как я могу программно создать и опросить базу данных, содержимое которой я не могу предвидеть?

Я реализую общую систему входных форм. Пользователь может создавать формы PHP с макетом WYSIWYG и использовать их для любых целей, которые он пожелает. Он также может запросить ввод.

Итак, у нас три этапа:

  1. формируется и создается форма. Это одноразовая процедура, хотя форма может быть отредактирована позже. Это создает базу данных.
  2. кто-то или несколько человек используют форму – скажем, для ежедневных отчетов о продажах, запаса, расчета заработной платы и т. д. Их вклад в формы записывается в базу данных.
  3. другие, возможно, менеджмент, могут запрашивать базу данных и создавать отчеты.

Поскольку эти формы являются общими, я не могу предсказать структуру базы данных, кроме как сказать, что она будет отображать поля формы HTML и состоять из ввода данных из коллекции полей редактирования, заметок, радиокнопок и т. П.

Вопросы и замечания:

A) как я могу лучше всего структурировать базу данных с точки зрения таблиц и столбцов? Как насчет первичных ключей? Моя первая мысль заключалась в том, чтобы использовать имя элемента управления для идентификации каждого столбца, затем я понял, что пользователь может редактировать форму и переименовывать, так что, возможно, «имя» становится «служащим» или «заработная плата» становится «: зарплата». Я склоняюсь к уникальному номеру для каждого.

B) как лучше всего закрепить строки? Я думал о отметке времени, чтобы разрешить мне запрос и столбец для идентификатора строки из A)

C) Мне нужно обработать переименование столбца / вставить / удалить. Удаление Foe, я не уверен, удалять ли данные из базы данных. Даже если пользователь больше не вводит его из формы, он может запросить то, что было ранее введено. Или могут быть некоторые законодательные требования по сохранению данных. Любые ошибки в столбце переименовывают / вставляют / удаляют?

D) Для запроса я могу заставить мой PHP опросить базу данных, чтобы получить имена столбцов и создать форму со списком, в котором каждая запись имеет имя столбца базы данных, флажок, чтобы указать, следует ли ее использовать в запросе и на основе тип столбца, некоторые критерии выбора. Этого должно быть достаточно, чтобы строить поиски, такие как «должность =« старший продавец »и зарплата> 50 тыс.».

E) Мне, вероятно, приходится генерировать некоторые причудливые графики – графики, гистограммы, круговые диаграммы и т. Д. Для получения результатов запроса числовых данных с течением времени. Для этого мне нужно найти хороший FOSS PHP.

F) Что еще я забыл?

Мне все это кажется очень сложным, но я база данных n00b – может быть, это просто для вас гуру?


Изменить: пожалуйста, не говори мне, чтобы я этого не делал. У меня нет выбора 🙁

Изменить: в реальной жизни я не ожидаю, что столбцы переименовать / вставить / удалить будут частыми. Однако возможно, что после запуска в течение нескольких месяцев может потребоваться изменение базы данных. Я уверен, что это происходит регулярно. Я боюсь, что я сформулировал этот вопрос плохо и что люди думают, что изменения будут совершены волей-неволей каждые 10 минут или около того.

Реально, мои пользователи будут определять базу данных, когда они выкладывают форму. Они могут получить это в первый раз и никогда не изменять его, особенно если они переходят из бумажных форм. Даже если они решают изменить, это может произойти только один или два раза, после нескольких месяцев или лет – и это может произойти в любой базе данных.

Я не думаю, что здесь у меня есть особый случай, и мы не должны концентрироваться на изменениях. Возможно, лучше сосредоточиться на связях – какая хорошая схема первичного ключа? Скажем, возможно, для одного ввода текста, одного численного и памятки?

«Мне все это кажется очень сложным, но я база данных n00b – может, вам просто гуру?»

Нет, это действительно сложно. В основном то, что вы описываете, не является приложением базы данных, оно является создателем приложения базы данных. На самом деле это звучит так, как будто вы хотите закодировать что-то вроде Google App Engine или веб-версии MS Access. Написание такого инструмента займет много времени и знаний.

Google реализовал гибкие схемы, используя платформу BigTable. Это позволяет вам в значительной степени сгибать схему. Уловка заключается в том, что эта гибкость очень затрудняет работу с такими запросами, как «position = 'старший продавец и зарплата> 50 тыс.».

Поэтому я не думаю, что подход NoSQL – это то, что вам нужно. Вы хотите создать приложение, которое генерирует и поддерживает схемы РСУБД. Это означает, что вам необходимо создать репозиторий метаданных, из которого вы можете создавать динамический SQL для создания и изменения схем пользователей, а также генерировать интерфейс.

Вещи, которые должна хранить ваша схема метаданных

Для генерации схемы:

  • отношения с внешним ключом (РАБОТНИК работает в ОТДЕЛЕНИИ)
  • уникальные бизнес-ключи (может быть только один ОТДЕЛ под названием «Продажи»)
  • справочные данные (допустимые значения EMPLOYEE.POSITION)
  • тип данных столбца, размер и т. д.
  • независимо от того, является ли столбец необязательным (т.е. NULL или NOT NULL)
  • сложные бизнес-правила (бонусы работникам не могут превышать 15% от их зарплаты)
  • значение по умолчанию для столбцов

Для интерфейсного поколения

  • отображать имена или метки («Заработная плата», «Зарплата»)
  • виджет (выпадающий список, всплывающий календарь)
  • скрытые поля
  • производные поля
  • справочный текст, советы
  • проверка на стороне клиента (связанный с ним JavaScript и т. д.)

Последнее указывает на потенциальную сложность вашего предложения: регулярный дизайнер форм, такой как Joe Soap, не сможет сформулировать JS, чтобы (сказать) подтвердить, что входное значение находится между X и Y, так что вы будете иметь вывести его, используя шаблонные правила.

Это далеко не исчерпывающие списки, это просто с головы.

Для первичных ключей я предлагаю вам использовать столбец типа данных GUID. Временные метки не гарантированно уникальны, хотя, если вы запустите свою базу данных на ОС, которая идет на шесть мест (то есть не в Windows), вряд ли вы столкнетесь с столкновениями.

Последнее слово

«Моя первая мысль заключалась в том, чтобы использовать имя элемента управления для идентификации каждого столбца, затем я понял, что пользователь может редактировать форму и переименовывать, так что, возможно,« имя »становится« служащим »или« заработная плата »становится«: зарплата ». Я склоняюсь к уникальному номеру для каждого.

Я уже создал генераторы схемы базы данных. Они тяжело переживают. Одна вещь, которая может быть жесткой, – это отладка динамического SQL. Поэтому упростите себя: используйте реальные имена для таблиц и столбцов. Просто потому, что пользователь приложения теперь хочет увидеть форму под заголовком HEADCOUNT, это не значит, что вам нужно переименовать таблицу EMPLOYEES. Следовательно, необходимо отделить отображаемую метку от имени объекта схемы. В противном случае вы обнаружите, что пытаетесь понять, почему этот сгенерированный SQL-запрос не удалось:

update table_11123 set col_55542 = 'HERRING' where col_55569 = 'Bootle' / 

Таким образом безумие.

По сути, вы спрашиваете, как создать приложение без спецификаций. Реляционные базы данных не были разработаны так, чтобы вы могли сделать это эффективно. Общим подходом к этой проблеме является конструкция Entity-Attribute-Value и тип системы, в которой вы хотите ее использовать, вероятность отказа составляет почти 100%.

Например, нет смысла, чтобы столбец «Имя» мог стать «Зарпластом». Как бы отчет, в котором вы хотите, чтобы общая зарплата работала, если бы зарплатные ценности могли иметь «Фред», «Боб», 100 тыс., 1000, «много»? Базы данных не были предназначены для того, чтобы никому ничего не было. Для успешных схем базы данных требуется структура, которая означает усилие в отношении спецификаций на то, что нужно хранить и почему.

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

Как сказал Томас, рациональная база данных не подходит для вашей проблемы. Тем не менее, вы можете посмотреть на NoSQL dbs, как MongoDB.

См. Эту статью: http://www.simple-talk.com/opinion/opinion-pieces/bad-carma/ для чужого опыта вашей проблемы.

Это для A) и B), и это не то, что я сделал, но подумал, что это интересная идея, которую Reddit использует, см. Эту ссылку (см. Урок 3 ):

http://highscalability.com/blog/2010/5/17/7-lessons-learned-while-building-reddit-to-270-million-page.html

Не уверен относительно базы данных, но для диаграмм вместо использования PHP для диаграмм, я рекомендую изучить использование javascript ( http://www.reynoldsftw.com/2009/02/6-jquery-chart-plugins-reviewed/ ). Преимущества этого – часть обработки выгружается на клиентскую сторону для отображения диаграмм, и они могут быть интерактивными.

Другие респонденты верны, что вы должны очень осторожно относиться к этому подходу, потому что он более сложный и менее эффективный, чем традиционная реляционная модель, – но я делал такие вещи для учета различий между подразделениями на работе, и он отлично работал для объем использования.

В основном я настраивал его так: сначала таблица для хранения некоторой информации о Форме, которую пользователь хочет создать (очевидно, приспосабливайтесь по мере необходимости):

 --************************************************************************ -- Create the User_forms table --************************************************************************ create table User_forms ( form_id integer identity, name varchar(200), status varchar(1), author varchar(50), last_modifiedby varchar(50), create_date datetime, modified_date datetime ) 

Затем таблицу для определения полей, которые должны быть представлены в форме, включая любые ограничения, а также порядок и страницу, которые они должны быть представлены (мое приложение представляло поля в виде типа страниц с несколькими страницами).

 -************************************************************************ -- Create the field configuration table to hold the entry field configuration --************************************************************************ create table field_configuration ( field_id integer identity, form_id SMALLINT, status varchar(1), fieldgroup varchar(20), fieldpage integer, fieldseq integer, fieldname varchar(40), fieldwidth integer, description varchar(50), minlength integer, maxlength integer, maxval varchar(13), minval varchar(13), valid_varchars varchar(20), empty_ok varchar(1), all_caps varchar(1), value_list varchar(200), ddl_queryfile varchar(100), allownewentry varchar(1), query_params varchar(50), value_default varchar(20) ); 

Затем мой код perl будет проходить через поля для страницы 1 и помещать их в «форму мастера» … и кнопка «next» будет представлять поля страницы 2 в порядке и т. Д.

У меня были функции javascript для обеспечения ограничений, определенных для каждого поля …

Затем таблицу для хранения значений, введенных пользователями:

 --************************************************************************ -- Field to contain the values --************************************************************************ create table form_field_values ( session_Id integer identity, form_id integer, field_id integer, value varchar(MAX) ); 

Это было бы хорошей отправной точкой для того, что вы хотите сделать, но следите за тем, как он может реально замедлить работу любых отчетов, если они добавят 1000 настраиваемых полей. 🙂

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