Дизайн базы данных - раскрытие первичного ключа - PullRequest
2 голосов
/ 10 ноября 2009

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

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

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

Все мои инстинкты говорят мне, что это ужасно, и что суррогатные идентификаторы ДОЛЖНЫ использоваться ТОЛЬКО для базы данных - и никогда не подвергаться воздействию внешнего мира таким образом.

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

Мысли

Ответы [ 14 ]

5 голосов
/ 10 ноября 2009

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

--- РЕДАКТИРОВАТЬ ----

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

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

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

4 голосов
/ 10 ноября 2009

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

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

2 голосов
/ 10 ноября 2009

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

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

1 голос
/ 10 ноября 2009

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

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

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

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

1 голос
/ 10 ноября 2009

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

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

1 голос
/ 10 ноября 2009

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

1 голос
/ 10 ноября 2009

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

0 голосов
/ 10 ноября 2009

Разоблачение PK представляет угрозу безопасности. Пользователи могут отправиться в рыболовную экспедицию и просто попробовать несколько интересных ключей и посмотреть, что они увидят таким образом. Допустим, вы отправляете ссылку 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?

0 голосов
/ 10 ноября 2009

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

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

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

0 голосов
/ 10 ноября 2009

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

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