Дизайн базы данных - отображение первичного ключа

Представьте, что у меня есть таблица Customer.

И в этой таблице есть столбец идентификатора, первичный ключ int, Identity, весь этот джаз. У нашего Клиента также есть Имя.

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

Все мои инстинкты говорят мне, что это ужасно, и что суррогатные идентификаторы должны ПОЛЕЗНО использоваться только для базы данных и никогда не подвергаться внешнему миру таким образом.

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

Мысли?

Ответ 1

Я бы предложил не добавлять новое поле, но также не показывать идентификатор.

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

Ответ 2

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

--- EDIT ----

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

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

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

Ответ 3

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

С другой стороны, почему бы не разоблачить идентификатор? Если ваше приложение уязвимо просто потому, что кто-то аргументировал первичный ключ, у вас возникли проблемы.

Ответ 4

Хорошо использовать ключ в той форме, которую вы используете. Однако в вашем конкретном случае существует проблема, с которой можно играть в URL, и люди могли видеть информацию других людей. Это зависит от того, что находится в этом URL-адресе относительно того, будет ли это проблемой для вас или нет. Если это то, то я предлагаю вам подбросить соль в ваш url (второе число, руководство, хэши электронной почты клиентов и т.д.), Которые вы могли бы затем сопоставить с идентификатором, чтобы убедиться, что URL-адрес верен. Даже использование идентификаторов, которые не являются 1, 2, 3... вместо того, чтобы использовать каждый 7-й идентификатор... все еще догадывается. Другая сторона заключается в том, что у вас может быть только идентификатор, если вы так склонны... или весь URL-адрес. Ваша информация, как правило, не использует бизнес во внешнем мире, если вы этого не хотите. В этом случае ваш инстинкт был прав в том, что данные не должны потребляться людьми. Но этот URL-адрес является частью вашей системы, поэтому на самом деле просто вопрос об использовании информации бесполезно для людей, читающих URL-адрес.

Ответ 5

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

Ответ 6

Создайте новое поле, называемое CustomerNumber, которое уникально в системе, но не связано с ID/первичным ключом.

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

Ответ 7

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

Ниже приведен пример кода для добавления нового столбца, который генерирует руководство для каждой записи.

BEGIN TRANSACTION
GO
ALTER TABLE dbo.Customers ADD
    PublicCustomerID uniqueidentifier NULL
GO
ALTER TABLE dbo.Customers ADD CONSTRAINT
    DF_Customers_PublicCustomerID DEFAULT newid() FOR PublicCustomerID
GO
ALTER TABLE dbo.Customers SET (LOCK_ESCALATION = TABLE)
GO
COMMIT

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

Ответ 8

Не рекомендуется публиковать простой идентификатор. Способ, которым я работаю, - это зашифровать параметр строки запроса.

Ответ 9

Я начну с этого. Использование вашего суррогатного ключа в качестве ссылки назад к некоторому объекту базы данных ОЧЕНЬ распространено. Фактически, многие популярные фреймворки делают именно это из коробки (ASP MVC, Ruby on Rails, CodeIgniter).

Однако вы можете вместо этого использовать естественный ключ. Вы также можете попробовать Base64 кодировать поле ID. Даже такие небольшие меры, как это, помогут помешать кому-либо "исследовать" вашу базу данных.

Ответ 10

Вы можете реализовать механизм безопасности, не требуя от пользователя входа в систему. Вы не должны просто полагаться на неизвестность, чтобы защитить эти данные.

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

Ответ 11

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

Ответ 12

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

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

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

Ответ 13

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

Ответ 14

Воздействие ПК - это риск безопасности. Пользователи могут отправиться в рыболовную экспедицию и просто попробовать несколько интересных ключей и посмотреть, что они видят таким образом. Скажем, ссылка, которую вы отправляете, http://www.example.org/ShowCustomer?id=4711. Изучив этот отчет, пользователь узнает только информацию о клиенте № 4711. Участник может легко опробовать все идентификаторы клиентов, начиная с 1: http://www.example.org/ShowCustomer?id=1 и, таким образом, иметь список всех ваших клиентов. А как насчет id = 0? или id = -1? Или SQL-инъекции, такие как http://www.example.org/ShowCustomer?id=1;DROP%20TABLE%20CUSTOMERS?