Хранение пользовательских атрибутов в пользовательской таблице - PullRequest
2 голосов
/ 30 декабря 2011

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

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

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

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

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

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

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

Ответы [ 4 ]

1 голос
/ 30 декабря 2011

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

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

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

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

1 голос
/ 30 декабря 2011

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

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

0 голосов
/ 30 декабря 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 );
}
0 голосов
/ 30 декабря 2011

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

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

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

...