Как реализовать ссылки в картографических базах данных? - PullRequest
3 голосов
/ 05 августа 2010

Я начинаю изучать карты-базы данных.Как реализовать ссылку в базе данных сокращения карт, такой как CouchDB или MongoDB?Например, предположим, что у меня есть водители и машины, и я хочу отметить, что какой-то водитель водит машину.В SQL это что-то вроде:

SELECT person_id, car_id FROM driver, car WHERE driver.car = car.car_id

(то есть, если моя память работает правильно - я некоторое время не программировал на SQL.)

В языках, на которые есть ссылки, этоПроще говоря: экземпляр Person может указывать на экземпляры Car.

Что такое эквивалент сокращения карты для такого рода отношений?

Ответы [ 2 ]

2 голосов
/ 06 августа 2010

В CouchDB вы должны написать карту / уменьшить, которая выведет ВСЕ автомобили и водителей со сложными ключами, а затем использовать диапазоны клавиш, чтобы выбрать оба. Например, давайте предположим, что ваши документы выглядят как эти два ...

{
  "_id": "...",
  "_rev": "...",
  "docType": "driver"
}

{
  "_id": "...",
  "_rev": "...",
  "docType": "car",
  "driver": "driver's _id"
}

Вы можете использовать duck, набрав вместо указания docType, но мне этот метод больше нравится.

Ваша функция карты:

function(doc)
{
  if(doc.docType == "driver")
    emit([doc.id, 0], doc);
  elseif(doc.docType == "car")
    emit([doc.driver, 1], doc];
}

Наш сложный ключ является массивом, причем первым элементом всегда является _id драйвера. Второй элемент в массиве предотвращает столкновение ключей и позволяет напрямую ссылаться на автомобиль или водителя (подробнее об этом позже).

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

?startkey=["driver _id"]&endkey=["driver _id", {}]

Это в основном говорит: «Дайте мне любой массив с драйвером _id в качестве первого элемента и что угодно во втором. Это работает, потому что объекты - второй элемент в массиве endkey - отсортированы как самые высокие. http://wiki.apache.org/couchdb/View_collation?redirect=ViewCollation#Collation_Specification для получения дополнительной информации о том, как элементы сортируются / взвешиваются в ключах.

Это также очень хорошо масштабируется, потому что мы можем добавить больше информации в нашу функцию карты без необходимости изменять наш запрос в клиенте. Допустим, мы добавляем спонсорский docType: мы просто добавляем еще один elseif для поля docType и затем emit([doc.driver, 2], doc);. Теперь мы можем получить все три документа в одном запросе с одним и тем же запросом диапазона ключей сверху.

Конечно, вы также можете указать отдельные документы вместо того, чтобы извлекать их все. ?key=["driver's _id", 1] будет тянуть только машину для указанного водителя.

Приветствие.

1 голос
/ 05 августа 2010

В базах данных документов вы можете встроить связанные объекты в документ, которому принадлежат объекты, например, Документ водителя также содержит все автомобили, принадлежащие водителю. Это сила баз данных документов; они позволяют легко хранить денормализованные данные.

{
  "_id": "joe_the_driver",
  "name": "Joe",
  "cars": [
    { "_id": "123-AB", /* car properties */ },
    { "_id": "456-YZ", /* car properties */ }
  ]
}

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

{
  "_id": "joe_the_driver",
  "car_ids": [ /* ID's that refer to car documents */ ]
}

{
  "_id": "123-AB",
  "driver_ids": [ /* ID's that refer to driver documents */ ]
}

Важно отметить, что большинство баз данных документов не имеют возможности обеспечивать отношения между документами так, как это делает база данных SQL. Ваша заявка отвечает за обеспечение и поддержание этих отношений.

...