Абстракция реализации первичного ключа - PullRequest
2 голосов
/ 08 февраля 2011

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

Например, мой DAL имеет методы GetPerson (string PersonID), которые должны принимать другие типы параметров для работы. Также большинство веб-страниц принимают строки запросов со встроенными в них PK (т. Е. / GetPerson? PersonID = BILL)

Это заставило меня задуматься о том, что я бы хотел внедрить некоторую инкапсуляцию, где я защищал себя от изменений PK. Иметь абстрактные методы для размещения и чтения PK из строки запроса. Аналогично, вместо передачи собственных типов в DAL, передайте объект PersonPK и скройте реализацию.

Теоретически мне нравится идея, я просто не уверен на практике, можно предотвратить превращение этого в "дырявую абстракцию". Например, когда пришло время генерировать вызовы БД, мне нужно взломать объект PK. И все еще будут десятки утверждений, которые нужно переписать.

Итак, на мой вопрос .... Кто-нибудь успешно использует PK абстракцию в своих проектах? Это сэкономило ваше время? Каковы ключи для успешной реализации этого?

EDIT: Некоторые из ответов подсказывают мне, что я ничего не понял.

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

Ответы [ 4 ]

2 голосов
/ 08 февраля 2011

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

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

Мое эмпирическое правило: если часть данных, хранящаяся в базе данных, имеет наименьшую вероятность даже оказаться перед конечным пользователем (гораздо реже доступной для редактирования), НЕ ИСПОЛЬЗУЙТЕ ее в качестве первичного ключа! Пример: адрес электронной почты может однозначно идентифицировать пользователя в системе. Да, это может быть использовано как pkey но!

  • Что если пользователь захочет изменить свой адрес? Вы должны обновлять одновременно каждую таблицу, где адрес электронной почты является внешним ключом!
  • Рассмотрим индексное число на каждой таблице, содержащей этот первичный ключ!
  • Подумайте о снижении производительности при сравнении двух строк вместо двух целых, чтобы связать две строки в простом объединении!

Многие разработчики зашли настолько далеко, что автоматически создали суррогатный ключ для каждой таблицы в БД. На самом деле это хорошая практика, особенно если суррогатные ключи не кажутся вам «естественными» сразу.

2 голосов
/ 08 февраля 2011

Не существует такого термина, как "абстракция ПК".

Существуют естественные первичные ключи и суррогатные первичные ключи.

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

1 голос
/ 08 февраля 2011

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

Ex:

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

user_id | network_id

Таким образом, уникальность выражается user_id + network_id ... однако, просто добавьте туда другой столбец для уникальности таким образом:

user_network_id | user_id | network_id

Гораздо проще "развернуть" эти одноколонные уникальные идентификаторы, когда дело доходит до рендеринга вашего SQL. С этим методом также проще обращаться к объектам в памяти.

0 голосов
/ 08 февраля 2011

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

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

C.Как отмечает Митч Уит в своем посте, абстракция PK невозможна.

D.Я настоятельно рекомендую переварить то, что говорили другие в этой теме, провести некоторые исследования первичных ключей и их нормализации и укусить пулю.Вы будете рады, что сделали это, когда подошли к версиям 3, 4, 5 и т. Д. Кода своего приложения.

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

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