Как создать полностью настраиваемое приложение (или базу данных) без потери производительности / хорошего дизайна? - PullRequest
1 голос
/ 04 июня 2009

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

Итак, моя настоящая ситуация, например, простая таблица пользователя:

id | name | surname | nickname | email       | phone
1  | foo  | bar     | foobar   | foo@bar.com | 99999

Вот так.

Но, скажем, один из моих клиентов хотел бы иметь 2 адреса электронной почты или номера телефонов для одного конкретного пользователя.

До сих пор я решал эту проблему, просто добавляя столбцы в таблицу пользователей:

id | name | surname | nickname | email       | phone | email_two    | phone_two
1  | foo  | bar     | foobar   | foo@bar.com | 99999 | foo@bar.net  | 999998

Но я не могу использовать этот способ с версией нового приложения. После этого мне хотелось бы пить мохито, не нравится призыв заказчика изменить структуру:)

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

id | table_refer | type_field | id_object | value
1  | users       | phone      | 1         | 999998
2  | users       | email      | 1         | foo@bar.net

сохранение таблицы пользователей без изменений.

Но у этого способа есть 2 проблемы:

  1. Насколько я знаю, нет возможности использовать чужой ключ таким образом, что, если я автоматически удаляю 1 пользователя, внешний ключ удаляет в каскаде все строки во второй таблице, которые имеют значение 'table_refer' = users и id_object = users.id. Конечно, я могу использовать некоторые функции триггеров, но я потеряю часть надежности.
  2. Когда мне нужно будет выполнить запрос к базе данных, прежде чем получить пользователей, которые соответствуют 'foo@bar.net', мне нужно будет также проверить все ... hem .. option_table, и это сделает мой код сложный, менее надежный и запутанный со многими объединениями ... при условии, что таблица пользователей не будет единственной, "расширенной" опцией "option_table", кажется серым.

Моя цель - позволить своим клиентам добавлять столько настраиваемых полей, сколько им нужно, почти для всего объекта в приложении (пользователей, элементов, счетов, просмотров печати, фотографий, новостей и т. Д.), Предполагая, что большинство из этих таблиц будут разделены (разделены на 2 таблицы, с 3 таблицами и иерархией наследования).

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

РЕДАКТИРОВАТЬ :

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

Я думаю, что таблица 2 ° (maibe 1 для каждого объекта) может быть хорошим решением, но я все еще жду лучших путей!

Ответы [ 5 ]

4 голосов
/ 04 июня 2009

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

Дизайн базы данных - это всегда серия компромиссов. Вам нужно посмотреть на все углы, возможно, создать несколько прототипов, выполнить профилирование и т. Д. «One True Answer ™» не существует.

1 голос
/ 04 июня 2009

Предложенная модель состоит из двух шаблонов базы данных: таблица значений атрибутов сущности и полиморфная ассоциация .

Entity-attribute-value имеет некоторые довольно большие проблемы как в области производительности, так и в отношении целостности данных. Если вам не требуется доступ к дополнительным атрибутам в запросах, вы можете сериализовать сопоставление значения атрибута с текстовым полем в некоторой стандартной сериализации (JSON, XML). Не «чисто» с точки зрения дизайна базы данных, но, возможно, хороший прагматичный выбор, учитывая, что вы знаете о компромиссах. В postgres вы также можете использовать модуль contrib hstore для хранения пар ключ-значение, чтобы сделать его пригодным для использования в запросах, если допустимо ограничение только для строковых значений.

Для полиморфной ассоциации вы можете получить ссылочную целостность, введя таблицу ассоциации:

users                attrib_assocs       custom_attribs
-----                -------------       --------------
attrib_assoc_id -->  id             <--  assoc_id
...                  entity_type         field
                                         value

Чтобы получить немного большей целостности, также добавьте entity_type к первичному ключу и соответствующим внешним ключам и проверочное ограничение для таблицы пользователей, которое entity_type равно 'user'.

0 голосов
/ 04 июня 2009

Я не уверен насчет специфики postgresql, но если вам нужны настраиваемые структуры данных в БД, по которым вы не хотите выполнять поиск, s преобразует данные в LOB это вариант.

Фактически именно так ASP.NET по умолчанию работает с персонализацией, которая соответствует настройкам пользователя.

Я не рекомендую этот подход, если вы хотите найти поля по любой причине.

0 голосов
/ 04 июня 2009

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

Для хранения пользовательских записей вы можете создать таблицу field_types(id, name, datatype) и таблицу custom_fields(user_id, field_type_id, value), а затем выбрать что-то вроде этого:

SELECT * FROM custom_fields WHERE user_id=XXX AND field_type_id IN (X,Y,Z).

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

0 голосов
/ 04 июня 2009

если вы сделаете это таким образом, все ваши запросы должны будут присоединиться к столбцу table_refer и использовать его, что снизит производительность и сделает простые запросы сложными, а сложные запросы очень сложными.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...