Поддерживает ли CouchDB ссылочную целостность?

Я новичок в CouchDB и узнаю об этом. Я не сталкивался с поддержкой ссылочной целостности CouchDB. Можем ли мы создать внешний ключ для поля в документе CouchDB?

Например, Можно ли обеспечить наличие имени поставщика, используемого в документе заказа, в базе данных поставщиков?

Поддерживает ли CouchDB ссылочную целостность? И можно ли сделать поле в документе первичным ключом?


person Sundar    schedule 23.12.2009    source источник


Ответы (3)


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

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

что-то типа

function(doc) {
  if (doc.type == 'order')
    emit(doc.vendor,doc);
}

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

Введение в представления CouchDB

person BaroqueBobcat    schedule 23.12.2009

Эти вопросы невероятно специфичны для реляционных баз данных.

В CouchDB или любой другой не-RDBMS вы не будете хранить свои данные так же, как в RDBMS, поэтому такое проектирование отношений может быть не лучшим. Но просто чтобы дать вам представление о том, как вы могли бы это сделать, давайте предположим, что у вас есть документ для поставщика и набор документов для заказов, которые должны быть «связаны» с документом поставщика.

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

{"type":"order","vendor-id":"asd7d7f6ds76f7d7s"}

Чтобы найти все заказы для конкретного поставщика, у вас будет представление карты примерно так:

function(doc) { if (doc.type == 'order') {emit(doc['vendor-id'], doc)}}

Документ _id не изменится, поэтому там есть «целостность», даже если вы измените другие атрибуты в документе поставщика, такие как его имя или платежная информация. Если вы вставите имя поставщика или другие атрибуты из документа поставщика непосредственно в документ заказа, вам потребуется написать сценарий, если вы когда-либо захотите изменить их массово.

Надеюсь, это немного поможет.

person mikeal    schedule 23.12.2009
comment
Другими словами, ссылочная целостность — это самостоятельная работа. Программист должен не забыть сначала создать документ поставщика, а затем написать элементы, которые ссылаются на его _id, потому что CouchDB не может обеспечить это для них. Точно так же программист при удалении должен помнить, что сначала нужно удалить заказы, связанные с поставщиком, прежде чем удалять поставщика — CouchDB не сделает этого за них. Таким образом, CouchDB позволит вам постоянно входить в несогласованные состояния; нет поддержки для защиты от него. - person Brandon Rhodes; 15.06.2010
comment
Я бы не назвал висячий документ без ссылки на него несогласованным состоянием, поскольку состояние в этом случае является ссылкой из другого документа, который будет удален. Но ваша характеристика семантики здесь точна. Ссылки — это просто индексы, и удаление документа не приводит к какой-то более крупной транзакции, которая очистит обратную ссылку, хотя и очистит прямую ссылку. - person mikeal; 16.06.2010
comment
Что еще более важно, сервер CouchDB поддерживает REST-3 (и вы можете создать возможности REST-4, если хотите, с проектной документацией). Применение термина ссылочной целостности имеет не больше смысла для базы данных документов, чем для видеоигры. Это не реляционная база данных и не претендует на это. - person Elf Sternberg; 04.07.2011

Хотя невозможно создать ограничение FK, это возможно с помощью функции Couch Validate.

function(newDoc, oldDoc, userCtx, secObj) {
    if(newDoc && newDoc.type) switch(newDoc.type){
        case 'fish':
            var allSpecies = ['trout','goldfish'];
            if(!allSpecies.contains(newDoc.species)){
                throw({forbidden : 'fish must be of a know species'});
            }
            break;
        case 'mammals':
            if(!['M','F'].contains(newDoc.sex)){
                throw({forbidden : 'mammals must have their sex listed'});
            }
            break;
    }
}

Теперь, если бы человек был действительно умным (а я нет), он мог бы обратиться к самой БД для получения списка видов... это был бы внешний ключ.

Вы также можете прочитать: Как мне высушить мой CouchDB просмотров?

person Jefferey Cave    schedule 19.02.2016