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


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

Вот методы и задачи:

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

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

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

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

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

4 2

4 ответа:

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

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

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

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

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

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

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

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

Вы можете сохранить атрибут пользователя, используя тип поля базы данных 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 );
}