Сохранить пользователя и профиль пользователя в разных таблицах?

26

Я видел в нескольких проектах, что разработчики предпочитают хранить важную информацию о пользователе в одной таблице (адрес электронной почты / логин, хэш пароля, отображаемое имя), а остальные несущественные профили пользователя - в другой (дата создания, страна и т. Д.). Под несущественным я подразумеваю, что эти данные нужны только изредка. Очевидное преимущество заключается в том, что если вы используете ORM, запросить меньше полей, очевидно, хорошо. Но тогда вы можете иметь две сущности, сопоставленные с одной и той же таблицей, и это избавит вас от запросов к тому, что вам не нужно (хотя и более удобно). Кто-нибудь знает какие-либо другие преимущества хранения этих вещей в двух таблицах?

Андрей
источник
1
@MichaelT спасибо! Интересно, что нет единого мнения по всем связанным вопросам.
Андрей
Вот почему я пошел со списком связанных вопросов, а не пытался ответить на него сам. Это на самом деле сводится к тому, как обстоят дела в каждом конкретном случае, и к тому, как разрабатывается конкретное приложение. Помните, что вы всегда можете использовать представление, чтобы объединить два бита, если это необходимо. Рассмотрите также возможность отсоединения одного (удаления учетной записи), но при этом оставьте другой (вопросы должны быть связаны с учетной записью, но учетная запись не всегда имеет профиль ...). Это может быть интересный вопрос, чтобы перейти в чат Software Engineering или перейти в DBA.SE и задать его в чате.
1
@MichaelT Я думаю о создании своего рода обобщенной структуры, которая обеспечит модель пользователя.
Андрей
В некоторых прошлых проектах я специально перемещал столбцы, которые, как предполагалось, очень часто записывались в свои собственные отдельные таблицы, чтобы защитить основную таблицу на случай, если файл базы данных будет поврежден или поврежден.
GrandmasterB

Ответы:

11

Это зависит от размера и требований вашего проекта.

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

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

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

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

Таким образом, обычно данные хранятся в двух типах систем:

  • Идентификационные данные обычно отправляются в каталог или решение IAM.
  • Данные о предпочтениях окажутся в базе данных.

Сказав, что на практике люди будут нарушать эти правила и использовать один или другой (например, SQL-сервер за провайдером членства ASP.NET).

По мере того как идентификационные данные становятся больше или организация, которая их использует, становится все больше, возникают различные типы проблем. Например, в случае с каталогом, он попытается немедленно скопировать изменения пароля на все серверы в многосерверной среде. Тем не менее, пользовательские настройки требуют только согласованности. (К вашему сведению: оба они являются разными оптимизациями теоремы CAPS.)

Наконец, каталоги (особенно онлайн / облачные каталоги) также будут выдавать токены доступа для других ресурсов, использующих протоколы, такие как OAUTH (например, рассмотрим Facebook, Google, учетную запись Microsoft, ADFS), тогда как в базе данных такой необходимости нет. База данных будет поддерживать довольно сложные объединения и структуру запросов, в которых каталог не нужен.

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

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

Если вы перейдете к БД, IMO, используя одну БД против двух, в конечном итоге перейдет к управлению доступом, как для пользователей, так и для приложений.

Омер Икбал
источник
3

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

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

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

Тулаинс Кордова
источник
1

Моя главная причина держать их отдельно - попытаться избежать того, что известно в объектно-ориентированном программировании как «класс бога». ORM связывает таблицы и поля с классами и атрибутами, поэтому он становится релевантным как уровень SQL (даже без ORM в целом действует сходный принцип).

Класс User (и, по ассоциации, пользовательская таблица) часто является таблицей, которая становится классом бога с сотнями атрибутов / полей, десятками или сотнями методов и определением класса (для методов) более 1000 строк. Я видел все это. Больше чем единожды.

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

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