CQRS и первичный ключ: guid или нет?

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

service.SubmitCommand(new AddUserCommand() { UserId = key, ... });

Очевидно, что я не могу использовать int для первичного ключа, поэтому Guid является логическим выбором - за исключением того, что я читаю всюду о влиянии производительности, которое меня пугает:)

Но затем я также читал о гидах COMB и о том, как они обеспечивают преимущества Guid, сохраняя при этом хорошую производительность. Я также нашел реализацию здесь: Последовательный GUID в Linq-to-Sql?.

Итак, прежде чем принять это важное решение: есть ли у кого-то опыт в этом вопросе, советы?

Спасибо большое!

Люд

Ответ 1

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

  • Когда вы создаете пользователя, вы знаете имя пользователя, потому что вы отправили его как часть команды.
  • Когда вы входите в систему, вы знаете имя пользователя, потому что пользователь отправил его как часть команды входа.

Если вы правильно указали столбец имени пользователя, вам может не понадобиться GUID. Лучший способ проверить это - запустить тест - вставить миллион записей пользователей и посмотреть, как работают CreateUser и Login. Если вы действительно видите серьезную производительность, нажмите , которую вы подтвердили, отрицательно повлияли на бизнес и не могут быть решены путем кэширования, , затем добавить Guid.

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

Ответ 2

Вы не указали, какой механизм базы данных вы используете, но так как вы упомянули LINQ to SQL, я предполагаю, что это MS SQL Server.
Если да, то Kimberly Tripp имеет некоторые советы по этому поводу:

Подводя итог двум ссылкам в нескольких словах:

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

Ответ 3

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

Большинство тестов Sequential GUID vs INT as primary key работает с пакетной вставкой и выбирает данные из базы данных бездействия. Но в реальной жизни выбор и обновления происходят в САМОЕ время.

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

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

В свете вышесказанного, выбор GUIDs vs INTs мне кажется коротким и фунт-глупым.