#azure-cosmosdb #unique-constraint
#azure-cosmosdb #уникальное ограничение
Вопрос:
Предположим, я хочу сохранить данные, которые выглядят следующим образом
type Person = {
Name:string
PassportNumber:string
}
type PolicyStatus =
|SaleInProgress
|PolicyActive
|Cancelled
type Policy = {
PincipalPerson: Person
PolicyDependents: Person list
PolicyId:int
PolicyState:PolicyStatus
}
(Я выразил эти типы как записи F #, поскольку они очень похожи на json, но пусть это вас не отвлекает)
Я хочу сделать так, чтобы каждый пользователь, который присутствует в a Policy
, был уникальным. Это означает, например, что если кто-то является участником какой-либо политики, он также не может зависеть от какой-либо другой политики.
Итак, если я сохраню их в Policy
коллекции, то я не думаю, что есть способ указать, что объединение иждивенцев и участников должно иметь уникальные идентификаторы паспорта, не так ли?
Если бы я использовал некоторые RDM, то я мог бы просто держать людей в другой таблице, иметь внешний ключ между Policy
и People
и уникальным ограничением PassportNumber
.
Итак, каков идиоматический «NoSQL» способ сделать это в Cosmos DB?
Комментарии:
1. Можете ли вы более точно сформулировать свои ограничения уникальности?
2. @MoB. Если я помещу каждого участника, являющегося участником, в массив, а каждого зависимого пользователя — в другой массив, а затем объединю эти массивы, результирующий массив должен содержать людей с уникальными идентификаторами паспортов. Дубликатов быть не должно.
Ответ №1:
Невозможно применить требуемые ограничения уникальности непосредственно в Cosmos DB, по крайней мере, если ваши данные структурированы так, как вы предложили. Ограничения уникальности, поддерживаемые Cosmos DB, основаны на (комбинациях) целых значений свойств (например, имя фамилия или PassportNumber
), поэтому вы не можете просмотреть массив значений.
Если вы хотите обеспечить соблюдение ограничений уникальности на уровне базы данных и готовы изменить свою модель данных, рассмотрите возможность внедрения политики в объект person:
type Person = {
Name: string
PassportNumber: string // with uniqueness constraint
IsPrincipalPerson: Nullable<bool> // specifies if the person is principal or dependent
PolicyId: Nullable<int>
PolicyState: Nullable<PolicyStatus>
}
Недостатком этой модели является то, что если вам нужно изменить состояние политики, вы должны изменить его во всех объектах person, в которых встречается идентификатор политики. В качестве альтернативы вы можете использовать следующую модель:
type Person = {
Name: string
PassportNumber: string // with uniqueness constraint
IsPrincipalPerson: Nullable<bool> // specifies if the person is principal or dependent
PolicyId: Nullable<int> // refers to a policy object
}
type Policy = {
PolicyId: int
PolicyState: PolicyStatus
}
Теперь несколько объектов person могут совместно использовать объект политики, но ограничения уникальности по-прежнему применяются, поскольку у каждого пользователя может быть не более одной политики (как основной, так и зависимой). Недостатком является то, что вам нужно позаботиться о собственной ссылочной целостности person.PolicyId
, поскольку отношения с внешним ключом не поддерживаются.
Комментарии:
1. Спасибо. Этот конкретный проект может быть первым, когда я использую хранилище данных NoSQL для серьезного проекта. Я изо всех сил пытаюсь понять преимущества. Аргумент whole schemaless не применяется, поскольку большинство RDMSS имеют встроенную поддержку полей json. Единственное преимущество, о котором я могу думать, — это горизонтальная масштабируемость, которую может обеспечить большинство баз данных NoSQL. Но если у меня небольшое количество пользователей, я не вижу смысла жертвовать полезными ограничениями, которые я могу получить из RDMS.
2. Справедливости ради, Cosmos DB намного превосходит (особенно по производительности), например, SQL Server в обработке данных JSON без схемы, с автоматической индексацией всех свойств, включая вложенные значения и значения массива. Cosmos DB также имеет хорошую поддержку для очень быстрой разбивки на страницы на основе набора ключей. Но, как вы видели, есть некоторые действительно серьезные недостатки: нет внешних ключей, нет реляционных объединений, нет транзакций чтения, нет транзакций чтения-записи, нет частичных обновлений (пока), ограничение размера документа. Моей команде пришлось решать все эти проблемы на стороне клиента, что было болезненно.
3. Кроме того, ваше ограничение уникальности для обоих
PrincipalPerson
, иPolicyDependants
его было бы не так просто применить в СУБД.4. В СУБД ограничение уникальности легко с
Person
помощью таблицы с уникальнымPassportNumber
и чужимPolicy.Principal
дляPerson
и таблицы сопоставления для зависимых. Но тогда вам придется иметь дело с несоответствием импеданса. Тем не менее, отмечено о преимуществах Cosmos.