Сохранение пользовательских атрибутов в пользовательской таблице

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

Вот методы и проблемы:

Метод 1. Если у вас есть пользователь, например христианин, вы можете сохранить это значение в таблице пользователей в столбце «Религия». Проблема с этим методом заключается в том, что слово «христианин» будет встречаться в таблице пользователей очень много, что мне кажется избыточным.

проблема 1: Кроме того, при использовании этого метода нигде в базе данных нет места, где хранятся все возможные значения, такие как «Buddhist», «Muslim» и т. д. Это сделало бы заполнение раскрывающегося списка трудным, если не невозможным.

Метод 2: Другой метод, который я придумал, - это индексирование этих значений. Измените столбец «Религия» в таблице пользователей на «Идентификатор религии» и пронумеруйте их. Христианин = 1, Муслим = 2 и т. Д. Затем установите связь по внешнему ключу с другой таблицей со значениями поиска.

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

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


person user    schedule 30.12.2011    source источник


Ответы (4)


нормализация базы данных - это все о компромиссах. Как я на это смотрю, я всегда начинаю с максимально приближенных к 3nf (т. Е. Метода 2). Когда либо размер моих данных, либо мои требования к производительности изменяются ... я рассматриваю возможность денормализации (т.е. метод 1).

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

person Joel Martinez    schedule 30.12.2011
comment
Отличный ответ. Я с самого начала ищу как можно больше долгосрочных предвидений. Что бы вы подумали о том, чтобы сохранить таблицу параметров пользователя и записать каждый атрибут в эту таблицу? Как вы думаете, какой метод будет наиболее эффективным и долгосрочным? - person user; 30.12.2011
comment
Это один из вариантов, который я использовал в прошлом. Он очень гибкий, но поверьте мне, когда я скажу, что усилия, скорее всего, не окупятся. Производительность будет ужасной, если вы захотите присоединиться к этой таблице, и новым разработчикам, присоединяющимся к команде, будет сложно понять схему. Эффективный и долгосрочный не всегда находятся в согласии друг с другом. вы знаете, что у вас есть определенные требования к производительности, спланируйте их заранее) - person Joel Martinez; 30.12.2011
comment
Спасибо. Кажется, что при нормализации таблицы я уже сейчас на стадии денормализации для повышения производительности. В соответствии с правилами нормализации, будет ли таблица параметров пользователя наиболее нормализованной? - person user; 30.12.2011
comment
нет ... наличие таблицы параметров пользователя может легко нарушить целостность данных. Приведу вам пример. Многие люди, использующие этот шаблон, в конечном итоге используют одну и ту же таблицу параметров либо для многих столбцов в одной таблице, либо для многих столбцов в разных таблицах. Поэтому они добавляют поле optionType, чтобы указать, к какому полю применяется подмножество параметров, после чего вы получаете правила (которые обычно управляются приложением), в которых вы можете ввести только диапазон идентификаторов параметров, соответствующих определенному optionType. Потом кто-то куда-то вставляет неправильное значение, и ваши отчеты идут к черту. #FromExperience - person Joel Martinez; 30.12.2011
comment
Считается ли сохранение нескольких повторяющихся значений в столбце для пользователей, таких как Christian (для многих пользователей), нормальным нарушением формы? - person user; 30.12.2011
comment
Это почти бесполезно, но единственный реальный ответ здесь - все зависит от обстоятельств. Как сказал @normalocity, это обычно зависит от того, разрешаете ли вы произвольные записи или контролируете значения. Но вы обнаружите, что во многих базах данных будет таблица с ограничениями внешнего ключа и всеми этими замечательными инструментами обеспечения целостности данных. Затем будет база данных отчетов, которая денормализует все данные для быстрого создания отчетов. Так что это зависит от того, нужно ли вам оптимизировать для записи или чтения. Не зацикливайтесь на правильном ответе, просто на том, что имеет для вас смысл прямо сейчас;) - person Joel Martinez; 30.12.2011

Я добавлю сюда еще один ответ, чтобы внести свой вклад в обсуждение. В комментарии вы упомянули, что у вас может быть до 10-15 соединений, которые вам потребуются для получения всех отображаемых имен для внешних ключей.

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

  1. Запросите свою таблицу без объединений ... это означает, что вы просто получите идентификаторы для многих своих значений.
  2. Во время отображения данных в любое время, когда вам нужно отобразить удобное для текста значение, попробуйте извлечь его из кеша.
  3. Если его там нет, сразу же возьмите всю таблицу поиска и кешируйте ее на час или день (в зависимости от того, что имеет смысл).
  4. Кэшированное значение может быть таким же простым, как словарь, поэтому вы можете взять словарь из кеша и вытащить описание строки для отображения.

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

person Joel Martinez    schedule 30.12.2011

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

Метод 2 будет работать нормально, если есть причина, по которой вы хотите поддерживать только определенный список конфессий и / или вы хотите контролировать, когда добавляются новые веры.

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

person jefflunt    schedule 30.12.2011
comment
Да, все, что ты сказал, правда. Однако я сосредоточен на эффективности базы данных. Я хочу использовать наиболее эффективный метод. Меня не беспокоит, может ли пользователь добавлять свои собственные значения атрибутов. Дело в том, что с таблицами поиска это приведет к множеству дополнительных таблиц, внешних ключей и объединений. Без них в пользовательской таблице будет храниться много избыточных данных. - person user; 30.12.2011
comment
нет ничего плохого в небольшом соединении здесь и там ;-) поместите на него представление, и ваши приложения будут отображаться в этом представлении, и вам не придется беспокоиться о присоединении так часто (с точки зрения написания запросов) - person Joel Martinez; 30.12.2011
comment
Я беспокоюсь не об одном объединении. При заполнении информации о пользователе может быть до 10-15 соединений. Это похоже на объединение-излишек. - person user; 30.12.2011
comment
да, это немного чрезмерно. Однако, если ваша политика кэширования достаточно агрессивна, вы можете смягчить это, только запрашивая (и, таким образом, присоединяясь), когда уровень вашего приложения получает промах кеша. - person Joel Martinez; 30.12.2011
comment
Дело в том, что вы не можете предсказать реальные проблемы с производительностью, пока не столкнетесь с ними с реальными пользователями. Ни один из предложенных вами методов на самом деле не является плохим, поэтому любой из них должен работать нормально, и все будет зависеть от того, как на самом деле используется ваше приложение. Так легко переключиться с одного на другой, почему бы просто не выбрать одно и продолжить работу? Я уверен, что вам нужно принять еще много других важных решений по поводу вашего приложения, кроме этого. - person jefflunt; 30.12.2011

Вы можете сохранить атрибут пользователя, используя тип поля базы данных enum (), чтобы задать список религий http://dev.mysql.com/doc/refman/5.0/en/enum.html. Это поле будет принимать только те значения, которые вы укажете при создании столбца. Это также упрощает добавление дополнительных типов путем изменения столбца в вашей базе данных.

В PHP вы можете заполнить раскрывающийся список с помощью этой функции из http://akinas.com/pages/en/blog/mysql_enum, чтобы получить массив значений перечисления для перебора:

function enum_select( $table , $field ){
    $query = " SHOW COLUMNS FROM `$table` LIKE '$field' ";
    $result = mysql_query( $query ) or die( 'error getting enum field ' . mysql_error() );
    $row = mysql_fetch_array( $result , MYSQL_NUM );
    #extract the values
    #the values are enclosed in single quotes
    #and separated by commas
    $regex = "/'(.*?)'/";
    preg_match_all( $regex , $row[1], $enum_array );
    $enum_fields = $enum_array[1];
    return( $enum_fields );
}
person David Hemphill    schedule 30.12.2011
comment
не могли бы вы заполнить раскрывающийся список значениями перечисления? где хранятся значения перечисления? - person user; 30.12.2011
comment
Чтобы уточнить, представленная выше функция извлекает значения перечисления в возвращаемый массив, чтобы вы могли перебирать массив в выбранном коде. - person David Hemphill; 30.12.2011
comment
и если вы используете sql-сервер, вы можете использовать ограничение проверки, которое проверяет ожидаемые значения - person Joel Martinez; 30.12.2011