How can I implement a foreign key like relationship in Mongo DB?
hiya see this: MongoDB normalization, foreign key and joining && further http://shop.oreilly.com/product/0636920018391.do ===> http://books.google.com/books/about/Document_Design_for_MongoDB.html?id=TbIHkgEACAAJ&redir_esc=y
MongoDB doesn't support server side foreign key relationships,
normalization is also discouraged. You should embed your child object
within parent objects if possible, this will increase performance and
make foreign keys totally unnecessary. That said it is not always
possible, so there is a special construct called DBRef which allows to
reference objects in a different collection. This may be then not so
speedy because DB has to make additional queries to read objects but
allows for kind of foreign key reference.
Still you will have to handle your references manually. Only while
looking up your DBRef you will see if it exists, the DB will not go
through all the documents to look for the references and remove them
if the target of the reference doesn't exist any more. But I think
removing all the references after deleting the book would require a
single query per collection, no more, so not that difficult really.
Edit update
http://levycarneiro.com/tag/mongodb/
levycarneiro.com/tag/mongodb [quote] So you create 4 collections: Clients, Suppliers, Employees and Contacts. You connect them all together via a db reference. This acts like a foreign key. But, this is not the mongoDB way to do things. Performance will penalized. [unquote]
Related
MongoDB supports references from one document to another.
Source: https://docs.mongodb.com/manual/core/data-modeling-introduction/
Does DynamoDB also supports this feature?
MongoDB references are not hard bound. Unlike foreign key constraint they would allow you to delete parent document even if the references are there in other document. It's a manual reference which you can maintain and use from application. However DBRef is provided by Monogo which is kind of hard bound but are strongly advised against because it limits the benefit of Mongo.
As far as manual reference goes, there is no reason why we can't use it in dynamoDB. the id of one table can be used as a field in another table. Again it won't be binding. But I don't think there is any hard bound reference system is in dynamoDB.
Mongo provides ObjectId as an inherent way to generate Ids, however you can use other types in _id field also. In dynamoDB it is more likely that you will choose an id type by yourself though you can use it's UUID feature also. But in dynamoDB you would mostly query on the primary key, so UUID won't be that helpful.
I come from traditional sql background where as you use FK relationship when you want to reference something in table.
I start to work on a project in mongodb, the referencing is different, basically relational kind of referencing is obsolete in nosql, it uses key referencing technique. I found it's freaking when I have so many duplication of reference key in my collection (table). My colleage says don't worry, it's just how mongo work, it won't have performances issue because it's still fast.
eg. user_id and user_access is in every of my collection, says I have 500 over collection, every time I have to query those two key to do something..
Just want to verify is that true it won't break someday?
I have created a SQL DB and examined the integrity. Now I wanted to put these tables in mongoDB, and I've kept it in the mapping rules. Table = collection, row = doc, and so on.
But how does one set about following in mongoDB:
create table pruefen
( MatrNr integer references Studenten on delete cascade,
VorlNr integer references Vorlesungen,
PersNr integer references Professoren on delete set null,
Note numeric(2,1) check (Note between 0.7 and 5.0),
primary key (MatrNr, VorlNr));
DBRef, I've tried but is not a foreign key replacement.
And if the application is to take over as it would look then?
MongoDB has no cascading deletes. When your application deletes data, it is also responsible for removing any referenced objects itself and any references to the deleted document. But usually when you use on delete in a relational database, you have a case of composition where one parent object owns one or more child objects, and the child objects are meaningless without the parent. In that situation, MongoDB encourages embedding instead of referencing. That means that you create an array in the parent object, and put the complete child documents into that array instead of keeping them in an own collection. That way they will be deleted together with the parent, because they are a part of it.
While keeping more than one value in a field is an absolute no-go in SQL, there is nothing wrong with that in MongoDB. That's because the MongoDB query language can easily work with arrays and embedded objects. You can even create indices on fields of sub-documents in arrays, so you can easily search for objects which are embedded in other objects.
When you still want to reference objects from another collection, you can either use a DBRef, or you can also use any other unique identifier (uniqueness is one of the few things which can be enforced by MongoDB. To do so, create an unique index with the createIndex command). But MongoDB does not enforce consistency in this case. You can create DBRefs which point to non-existing ObjectIds and when the document the DBRef points to is deleted, nothing will happen. The application is responsible for making sure that when it deletes a document, all documents which reference it are updated.
Constraints can not be enforced by MongoDB either. It can't even enforce a specific type for a field, due to the schemaless nature of MongoDB. Again, your application is responsible for making sure that the data it puts into mongodb is following specific specifications. When you want to automatize this, there are object-relational mapping frameworks for MongoDB for many programming languages available.
To wrap it all up: MongoDB is not as "smart" as SQL databases. It doesn't do much on its own. It does what it is told to do by the application, not more and not less. But that's the reason why it's so fast (no expensive consistency checks) and flexible (no database modifications necessary to implement new features).
One of the great things about relational database is that it is really good at keeping the data consistent within the database. One of the ways it does that is by using foreign keys. A foreign key constraint is that let's say there's a table with some column which will have a foreign key column with values from another table's column. In MongoDB, there's no guarantee that foreign keys will be preserved. It's upto the programmer to make sure that the data is consistent in that manner. This maybe possible in future versions of MongoDB but today, there's no such option. The alternative for foreign key constraints is embedding data.
since mongoDB does not support foreign keys, I've read that you can use for DBReF. Now I want to like to test this relationship.
The 2 collections are
db.professor.insert({"_id": 1122, "Name":"Heinrich","Rang": "C3","Raum":"D123"})
db.assistent.insert({"_id": 2244,"Name":"Schmidt","Fachgebiet":"Neuronale Netze","Boss":{"$ref":"professor","$id":1122}})
First question, but it should not be at the reference the wrong id may assume or. And if I entries with the correct ID $ id how can I test the reference?
Background is that I examine the data integrity features mongoDB!
Does anyone have sources on mongoDB and data integrity
MongoDBs inter collection data integrity is zero. This is not a bug in the way MongoDB works nor is it desired that this behaviour should change.
Not having inter collection data integrity is one of its core features as a NoSQL ( http://en.wikipedia.org/wiki/NoSQL ) product which this behaviour is commonly associated with (that being said it doesn't have to).
Of course this has nothing to do with general data integrity but cascading and referencing of relationships server-side.
A DBRef ( http://docs.mongodb.org/manual/applications/database-references/ ) is no different to just saving a ObjectId into your document. The only real difference is that it is a object of objects which also store a property to house the collection name. There is nothing special about the DBRef except that it comes pre-bundled with the MongoDB driver for most (if not all) languages as a helper to allow you to query the other row in your application.
Many do confuse the purpose of a DBRef however I assure you that there is nothing truly special about it.
So there is no check to see if you put in the wrong ObjectId and there is no cascade on the relationship and there is no "foreign key" behaviour in MongoDB.
Any and all relational integrity comes from your application and its ability to work in such a manner that prevents any problems within your data. This applies to both inserts and cascades of pseudo relations.
Considering these brief facts about MongoDB your test is almost useless, if you wish to test the data integrity of a relational model you should use a relational database.
Before I dive really deep into MongoDB for days, I thought I'd ask a pretty basic question as to whether I should dive into it at all or not. I have basically no experience with nosql.
I did read a little about some of the benefits of document databases, and I think for this new application, they will be really great. It is always a hassle to do favourites, comments, etc. for many types of objects (lots of m-to-m relationships) and subclasses - it's kind of a pain to deal with.
I also have a structure that will be a pain to define in SQL because it's extremely nested and translates to a document a lot better than 15 different tables.
But I am confused about a few things.
Is it desirable to keep your database normalized still? I really don't want to be updating multiple records. Is that still how people approach the design of the database in MongoDB?
What happens when a user favourites a book and this selection is still stored in a user document, but then the book is deleted? How does the relationship get detached without foreign keys? Am I manually responsible for deleting all of the links myself?
What happens if a user favourited a book that no longer exists and I query it (some kind of join)? Do I have to do any fault-tolerance here?
MongoDB doesn't support server side foreign key relationships, normalization is also discouraged. You should embed your child object within parent objects if possible, this will increase performance and make foreign keys totally unnecessary. That said it is not always possible, so there is a special construct called DBRef which allows to reference objects in a different collection. This may be then not so speedy because DB has to make additional queries to read objects but allows for kind of foreign key reference.
Still you will have to handle your references manually. Only while looking up your DBRef you will see if it exists, the DB will not go through all the documents to look for the references and remove them if the target of the reference doesn't exist any more. But I think removing all the references after deleting the book would require a single query per collection, no more, so not that difficult really.
If your schema is more complex then probably you should choose a relational database and not nosql.
There is also a book about designing MongoDB databases: Document Design for MongoDB
UPDATE The book above is not available anymore, yet because of popularity of MongoDB there are quite a lot of others. I won't link them all, since such links are likely to change, a simple search on Amazon shows multiple pages so it shouldn't be a problem to find some.
See the MongoDB manual page for 'Manual references' and DBRefs for further specifics and examples
Above, #TomaaszStanczak states
MongoDB doesn't support server side foreign key relationships,
normalization is also discouraged. You should embed your child object
within parent objects if possible, this will increase performance and
make foreign keys totally unnecessary. That said it is not always
possible ...
Normalization is not discouraged by Mongo. To be clear, we are talking about two fundamentally different types of relationships two data entities can have. In one, one child entity is owned exclusively by a parent object. In this type of relationship the Mongo way is to embed.
In the other class of relationship two entities exist independently - have independent lifetimes and relationships. Mongo wishes that this type of relationship did not exist, and is frustratingly silent on precisely how to deal with it. Embedding is just not a solution. Normalization is not discouraged, or encouraged. Mongo just gives you two mechanisms to deal with it; Manual refs (analoguous to a key with the foreign key constraint binding two tables), and DBRef (a different, slightly more structured way of doing the same). In this use case SQL databases win.
The answers of both Tomasz and Francis contain good advice: that "normalization" is not discouraged by Mongo, but that you should first consider optimizing your database document design before creating "document references". DBRefs were mentioned by Tomasz, however as he alluded, are not a "magic bullet" and require additional processing to be useful.
What is now possible, as of MongoDB version 3.2, is to produce results equivalent to an SQL JOIN by using the $lookup aggregation pipeline stage operator. In this manner you can have a "normalized" document structure, but still be able to produce consolidated results. In order for this to work you need to create a unique key in the target collection that is hopefully both meaningful and unique. You can enforce uniqueness by creating a unique index on this field.
$lookup usage is pretty straightforward. Have a look at the documentation here: https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/#lookup-aggregation. Run the aggregate() method on the source collection (i.e. the "left" table). The from parameter is the target collection (i.e. the "right" table). The localField parameter would be the field in the source collection (i.e. the "foreign key"). The foreignField parameter would be the matching field in the target collection.
As far as orphaned documents, from your question I would presume you are thinking about a traditional RDBMS set of constraints, cascading deletes, etc. Again, as of MongoDB version 3.2, there is native support for document validation. Have a look at this StackOver article: How to apply constraints in MongoDB? Look at the second answer, from JohnnyHK
Packt Publishers have a bunch of good books on MongoDB. (Full Disclosure: I wrote a couple of them.)