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
мне кажется коротким и фунт-глупым.