Как сохранить ссылочную целостность для пользователей в отдельном поставщике членства?

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

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

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

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

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

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

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

2 ответа

Решение

Этот вопрос на самом деле о двух разных вещах.

  1. Если внешний ключ к удаленной базе данных также будет внешним ключом к локальной таблице.
  2. Можете ли вы сохранить ссылочную целостность для сторонней базы данных

Это совершенно разные вещи, хотя быстрый ответ на них на самом деле один и тот же:

Нет.

Но позвольте мне немного углубиться в детали.

1. Использование внешних ключей для удаленной базы данных

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

Пример. Допустим, у вас есть блог, где пользователи могут оставлять комментарии. Эти пользователи будут входить через Facebook. Теперь у вас есть удаленная база данных (Facebook) и локальная, в которой хранятся комментарии ваших пользователей. Теперь вы можете следовать одной из двух схем:

  • comments таблица, которая хранит facebook_id как внешний ключ

или же

  • отдельный users таблица хранения facebook_id вместе с местным id и comments таблица, которая использует ваш локальный идентификатор в качестве внешнего ключа.

Вы не должны использовать facebook_id в обоих. Хотя это на самом деле работает, вы вводите зависимость от удаленной базы данных без необходимости. Вы не сможете добавить комментарий от пользователя, не принадлежащего Facebook, поскольку это нарушит ваш дизайн.

2. Ссылочная целостность с удаленными базами данных

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

Пример: Вернемся к вышеупомянутому гипотетическому блогу. Некоторые пользователи Facebook опубликовали комментарий. Позже тот же человек решает удалить свою учетную запись Facebook. Скорее всего, база данных Facebook не сообщит вам об этом, оставив в вашей базе данных "мертвые" записи, которые больше не ссылаются на действительную запись в удаленной базе данных. Это нарушает ссылочную целостность. Поэтому, если у вас нет хорошего способа сохранить эту целостность, например, получать уведомления об удалении и т. Д., Вы должны разработать приложение так, чтобы оно не сломалось, если пользователь Facebook был удален.

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

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

ИМХО: Вы должны поддерживать то, что запрашиваете, в интеграции на уровне бизнеса, а не на уровне базы данных.

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

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

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