Является ли управляемый моделью данных идентификатор ресурса аспектом ресурса или базы данных?
Мои примеры будут включать псевдо-код C# для целей обсуждения, но это не относится к какому-либо отдельному языку или инструментам базы данных.
Возьми простую модель
Customer { string Id }
Использование RavenDB при хранении new Customer()
он сгенерирует для меня идентификатор во время выполнения, предположим, "Клиенты /234". В этом сценарии я согласен с тем, что идентификатор является аспектом RavenDB. Принципиально это ничем не отличается от Guid.NewGuid().ToString()
поскольку он создает идентификатор, который не имеет человеческого понятного значения и просто достигает цели глобальной уникальности (для этой базы данных). Возможно, это просто более приятная версия руководства, и она создаст лучшие URL-адреса и позволит человеку сообщать свой идентификатор, если он когда-либо понадобится, намного проще, чем строка из 16 случайных шестнадцатеричных символов.
По другому сценарию возьмите:
User { string UserName, string Id }
В этом сценарии я хочу поместить истинное семантическое значение в мой идентификатор, а не просто в уникальное число.
С RavenDB это может быть выполнено так:
store.Conventions.DocumentKeyGenerator = (entity) =>
{
User user = entity as User;
if(user == null)
return defaultKeyGeneration (entity);
return "Users/" + user.UserName;
}
Который затем во время этой операции магазина вы бы в конечном итоге с "Пользователи /dotnetchris"
Я мог бы также подойти к этому, вместо того чтобы пользователь имел простое свойство Id, чтобы использовать свойство только для чтения:
User {
string Id { get { return "Users/" + UserName }
Мне трудно решить, какое из них является подходящим местом для этой конструкции.
Я склоняюсь к тому, что он должен быть включен в класс напрямую, так как это дает вам информацию о том, что будет легко загрузить этот объект по идентификатору из пользовательского ввода без необходимости запрашивать базу данных, чтобы найти Users.Where(user.UserName == "dotnetchris")
2 ответа
Как правило, я стараюсь, чтобы каждый идентификатор принадлежал приложению, а не базе данных. Единственная причина, по которой я передам право владения идентификатором модели, - это соображения производительности, например таблица SQL, которая должна быть реплицирована и имеет 500 миллионов строк.
Кажется, это сильно зависит от того, как данные могут или не могут быть ссылки в базе данных. Если "полный" идентификатор (т.е. Users/name
) требуется для какого-то ограничения в дизайне базы данных, тогда лучше было бы держать его близко к базе данных, но если это не так, вы получите больше пользы от сохранения его как части модели предметной области, чтобы учесть гибкость в коде (согласно вашему окончательному примеру кода).