[sql] Foreign keys in mongo?

enter image description here

How do I design a scheme such this in MongoDB? I think there are no foreign keys!

This question is related to sql mongodb foreign-keys nosql

The answer is


Short answer: You should to use "weak references" between collections, using ObjectId properties:

References store the relationships between data by including links or references from one document to another. Applications can resolve these references to access the related data. Broadly, these are normalized data models.

https://docs.mongodb.com/manual/core/data-modeling-introduction/#references

This will of course not check any referential integrity. You need to handle "dead links" on your side (application level).


How to design table like this in mongodb?

First, to clarify some naming conventions. MongoDB uses collections instead of tables.

I think there are no foreign keys!

Take the following model:

student
{ 
  _id: ObjectId(...),
  name: 'Jane',
  courses: [
    { course: 'bio101', mark: 85 },
    { course: 'chem101', mark: 89 }
  ]
}

course
{
  _id: 'bio101',
  name: 'Biology 101',
  description: 'Introduction to biology'
}

Clearly Jane's course list points to some specific courses. The database does not apply any constraints to the system (i.e.: foreign key constraints), so there are no "cascading deletes" or "cascading updates". However, the database does contain the correct information.

In addition, MongoDB has a DBRef standard that helps standardize the creation of these references. In fact, if you take a look at that link, it has a similar example.

How can I solve this task?

To be clear, MongoDB is not relational. There is no standard "normal form". You should model your database appropriate to the data you store and the queries you intend to run.


We can define the so-called foreign key in MongoDB. However, we need to maintain the data integrity BY OURSELVES. For example,

student
{ 
  _id: ObjectId(...),
  name: 'Jane',
  courses: ['bio101', 'bio102']   // <= ids of the courses
}

course
{
  _id: 'bio101',
  name: 'Biology 101',
  description: 'Introduction to biology'
}

The courses field contains _ids of courses. It is easy to define a one-to-many relationship. However, if we want to retrieve the course names of student Jane, we need to perform another operation to retrieve the course document via _id.

If the course bio101 is removed, we need to perform another operation to update the courses field in the student document.

More: MongoDB Schema Design

The document-typed nature of MongoDB supports flexible ways to define relationships. To define a one-to-many relationship:

Embedded document

  1. Suitable for one-to-few.
  2. Advantage: no need to perform additional queries to another document.
  3. Disadvantage: cannot manage the entity of embedded documents individually.

Example:

student
{
  name: 'Kate Monster',
  addresses : [
     { street: '123 Sesame St', city: 'Anytown', cc: 'USA' },
     { street: '123 Avenue Q', city: 'New York', cc: 'USA' }
  ]
}

Child referencing

Like the student/course example above.

Parent referencing

Suitable for one-to-squillions, such as log messages.

host
{
    _id : ObjectID('AAAB'),
    name : 'goofy.example.com',
    ipaddr : '127.66.66.66'
}

logmsg
{
    time : ISODate("2014-03-28T09:42:41.382Z"),
    message : 'cpu is on fire!',
    host: ObjectID('AAAB')       // Reference to the Host document
}

Virtually, a host is the parent of a logmsg. Referencing to the host id saves much space given that the log messages are squillions.

References:

  1. 6 Rules of Thumb for MongoDB Schema Design: Part 1
  2. 6 Rules of Thumb for MongoDB Schema Design: Part 2
  3. 6 Rules of Thumb for MongoDB Schema Design: Part 3
  4. Model One-to-Many Relationships with Document References

From The Little MongoDB Book

Yet another alternative to using joins is to denormalize your data. Historically, denormalization was reserved for performance-sensitive code, or when data should be snapshotted (like in an audit log). However, with the ever- growing popularity of NoSQL, many of which don’t have joins, denormalization as part of normal modeling is becoming increasingly common. This doesn’t mean you should duplicate every piece of information in every document. However, rather than letting fear of duplicate data drive your design decisions, consider modeling your data based on what information belongs to what document.

So,

student
{ 
    _id: ObjectId(...),
    name: 'Jane',
    courses: [
    { 
        name: 'Biology 101', 
        mark: 85, 
        id:bio101 
    },
  ]
}

If its a RESTful API data, replace the course id with a GET link to the course resource


The purpose of ForeignKey is to prevent the creation of data if the field value does not match its ForeignKey. To accomplish this in MongoDB, we use Schema middlewares that ensure the data consistency.

Please have a look at the documentation. https://mongoosejs.com/docs/middleware.html#pre


Examples related to sql

Passing multiple values for same variable in stored procedure SQL permissions for roles Generic XSLT Search and Replace template Access And/Or exclusions Pyspark: Filter dataframe based on multiple conditions Subtracting 1 day from a timestamp date PYODBC--Data source name not found and no default driver specified select rows in sql with latest date for each ID repeated multiple times ALTER TABLE DROP COLUMN failed because one or more objects access this column Create Local SQL Server database

Examples related to mongodb

Server Discovery And Monitoring engine is deprecated Avoid "current URL string parser is deprecated" warning by setting useNewUrlParser to true MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017] Failed to auto-configure a DataSource: 'spring.datasource.url' is not specified Failed to start mongod.service: Unit mongod.service not found db.collection is not a function when using MongoClient v3.0 MongoError: connect ECONNREFUSED 127.0.0.1:27017 MongoDB: How To Delete All Records Of A Collection in MongoDB Shell? How to resolve Nodejs: Error: ENOENT: no such file or directory How to create a DB for MongoDB container on start up?

Examples related to foreign-keys

Migration: Cannot add foreign key constraint The ALTER TABLE statement conflicted with the FOREIGN KEY constraint Can a foreign key refer to a primary key in the same table? Introducing FOREIGN KEY constraint may cause cycles or multiple cascade paths - why? MySQL Error 1215: Cannot add foreign key constraint MySQL Cannot Add Foreign Key Constraint Delete rows with foreign key in PostgreSQL How to remove constraints from my MySQL table? MySQL - Cannot add or update a child row: a foreign key constraint fails How to remove foreign key constraint in sql server?

Examples related to nosql

Firestore Getting documents id from collection What is Hash and Range Primary Key? Mongodb: Failed to connect to 127.0.0.1:27017, reason: errno:10061 Explanation of JSONB introduced by PostgreSQL DynamoDB vs MongoDB NoSQL Querying DynamoDB by date Delete all nodes and relationships in neo4j 1.8 When to use CouchDB over MongoDB and vice versa Difference between scaling horizontally and vertically for databases NoSQL Use Case Scenarios or WHEN to use NoSQL