ТРАНЗАКЦИИ И
ДЕНОРМАЛИЗАЦИЯ В
MONGODB
JOIN
Transaction
Data
normalization
JOIN
 Иерархическая организация объектов.
 Слияние/объединение объектов на стороне клиента.
 Использование DBRef для организации связей между
коллекциями и «ленивой» загрузки.
 Усложняются опреации агрегирования с участием разных
коллекций.
 Требует более тщательного проектирования.
ПРИМЕР ИСПОЛЬЗОВАНИЯ DBREF
 public class Post : Entity
 {
 public string Id { get; set; }
 public string Title { get; set; }
 public string Summary { get; set; }
 public DateTime Added { get; set; }
 public DBRef Owner { get; set; }
 }

 var mongo = new Mongo(config.BuildConfiguration());
 mongo.Connect();
 var DB = mongo.GetDatabase(_dataBaseName)
 var post = new Post();
 post.Owner = new DBRef("User", userId); //First parameter is a mongoDB collection name and second is object id
 //To fetch object referenced by DBRef you should do following
 var owner = DB.FollowReference<User>(post.Owner);
TRANSACTION
 Можно использовать атомарность однодокументных
операций
 Использование дополнительных паттернов. Например,
commit в 2 шага.
 ACID?
ПРИМЕР ИСПОЛЬЗОВАНИЯ COMMIT В 2
ШАГА
 db.accounts.save({name: "A", balance: 1000, pendingTransactions: []})
 db.accounts.save({name: "B", balance: 1000, pendingTransactions: []})
 db.transactions.save({source: "A", destination: "B", value: 100, state: "initial"})
 db.transactions.update({_id: t._id}, {$set: {state: "pending"}})
 db.accounts.update({name: t.source, pendingTransactions: {$ne: t._id}}, {$inc: {balance: -t.value}, $push:
{pendingTransactions: t._id}})
 db.accounts.update({name: t.destination, pendingTransactions: {$ne: t._id}}, {$inc: {balance: t.value}, $push:
{pendingTransactions: t._id}})
 db.transactions.update({_id: t._id}, {$set: {state: "committed"}})
 db.accounts.update({name: t.source}, {$pull: {pendingTransactions: t._id}})
 db.accounts.update({name: t.destination}, {$pull: {pendingTransactions: t._id}})
 db.transactions.update({_id: t._id}, {$set: {state: "done"}})
ACID
 Atomicity
 Consistency
 Isolation
 Durability
DATA NORMALIZATION
 Объект в коллекции содержит необходимые ему данные.
 Дополнительная сложность организации транзакций может
приводить к нарушению целосности данных между разными
коллекциями в определенные моменты времени.
 Ограниченность встроенных механизмов ссылок и
древовидная структура объекта побуждает к
денормализации.
В ЗАКЛЮЧЕНИЕ
 При использовании любого инструмента нужно понимать его
преимущества и недостатки.
 При проектировании приложения нужно понимать
ограничения инструментов и способы борьбы с ними.
 Премущества часто перевешивают дополнительные затраты
адаптации под вашу задачу.

Transactions and Denormalization in MongoDB - Artem Slobolinsky - Dnipropetrovsk MUG 140303

  • 1.
  • 2.
  • 3.
    JOIN  Иерархическая организацияобъектов.  Слияние/объединение объектов на стороне клиента.  Использование DBRef для организации связей между коллекциями и «ленивой» загрузки.  Усложняются опреации агрегирования с участием разных коллекций.  Требует более тщательного проектирования.
  • 4.
    ПРИМЕР ИСПОЛЬЗОВАНИЯ DBREF public class Post : Entity  {  public string Id { get; set; }  public string Title { get; set; }  public string Summary { get; set; }  public DateTime Added { get; set; }  public DBRef Owner { get; set; }  }   var mongo = new Mongo(config.BuildConfiguration());  mongo.Connect();  var DB = mongo.GetDatabase(_dataBaseName)  var post = new Post();  post.Owner = new DBRef("User", userId); //First parameter is a mongoDB collection name and second is object id  //To fetch object referenced by DBRef you should do following  var owner = DB.FollowReference<User>(post.Owner);
  • 5.
    TRANSACTION  Можно использоватьатомарность однодокументных операций  Использование дополнительных паттернов. Например, commit в 2 шага.  ACID?
  • 6.
    ПРИМЕР ИСПОЛЬЗОВАНИЯ COMMITВ 2 ШАГА  db.accounts.save({name: "A", balance: 1000, pendingTransactions: []})  db.accounts.save({name: "B", balance: 1000, pendingTransactions: []})  db.transactions.save({source: "A", destination: "B", value: 100, state: "initial"})  db.transactions.update({_id: t._id}, {$set: {state: "pending"}})  db.accounts.update({name: t.source, pendingTransactions: {$ne: t._id}}, {$inc: {balance: -t.value}, $push: {pendingTransactions: t._id}})  db.accounts.update({name: t.destination, pendingTransactions: {$ne: t._id}}, {$inc: {balance: t.value}, $push: {pendingTransactions: t._id}})  db.transactions.update({_id: t._id}, {$set: {state: "committed"}})  db.accounts.update({name: t.source}, {$pull: {pendingTransactions: t._id}})  db.accounts.update({name: t.destination}, {$pull: {pendingTransactions: t._id}})  db.transactions.update({_id: t._id}, {$set: {state: "done"}})
  • 7.
  • 8.
    DATA NORMALIZATION  Объектв коллекции содержит необходимые ему данные.  Дополнительная сложность организации транзакций может приводить к нарушению целосности данных между разными коллекциями в определенные моменты времени.  Ограниченность встроенных механизмов ссылок и древовидная структура объекта побуждает к денормализации.
  • 9.
    В ЗАКЛЮЧЕНИЕ  Прииспользовании любого инструмента нужно понимать его преимущества и недостатки.  При проектировании приложения нужно понимать ограничения инструментов и способы борьбы с ними.  Премущества часто перевешивают дополнительные затраты адаптации под вашу задачу.