Introduction to Dgraph for SQL Users

Handle Data Changes

There are three operations that you can use to change data in a database: data can be added, updated, or deleted. SQL and GraphQL handle these changes using very different syntax, but as you will see below, GraphQL uses syntax that is easier to learn because it is more consistent across these three operations.

Data changes in SQL

As a SQL user, you are familiar with the INSERT, UPDATE, and DELETE statements used to perform these actions. When you first learned SQL, you might have found it difficult to learn the syntax for these operations, in part because these statements use very different syntax, as shown below:

Add data in SQL:

INSERT INTO table_name
  (column_a, column_b, ...)
VALUES
  (value_1, value_2, ...)

Update data in SQL:

UPDATE table_name
SET
  column_a = value_1,
  column_b = value_2,
  ...
WHERE condition

Delete data in SQL:

DELETE FROM table_name
WHERE condition

Seeing these statements together, the inconsistencies are obvious: You can’t add data using syntax like column_a = value_1 and you can’t update data using syntax like (column_a) VALUES (value_1).

Data changes in GraphQL

Fortunately, GraphQL uses consistent syntax when adding, updating or querying data. GraphQL also lets you do something you can’t do with SQL: update and query data with a single transaction, using a mutation.

Queries start with the optional query keyword and mutations start with a required mutation keyword, but otherwise they follow the same syntax. You can use mutations to add, update and delete data, as follows:

Add data in GraphQL:

mutation ADD_TYPE {
  addType(input: [addTypeInput!]!) AddTypePayload
}

Update data in GraphQL:

mutation UPDATE_TYPE {
  updateType(input: {
    filter: TypeFilter!
    set: TypePatch
    remove: TypePatch
  }) UpdateTypePayload
}

Delete data in GraphQL

mutation DELETE_TYPE {
  deleteType(filter: TypeFilter!) DeleteTypePayload
}

With GraphQL, you can read data in the same request as when you write data. To do the same thing with SQL, you have to make multiple requests:

  1. Insert data
  2. Read last insert id
  3. Query with last insert id

With GraphQL, you declare what you want to read in the payload and that data is returned back to you - mutations handle all three steps at once! You might wonder what use case there is for reading back the same data that was mutated. By reading back data from mutations, deeply-referenced data can be retrieved and client-side caches can be easily kept up-to-date.

Dgraph’s implementation of GraphQL provides you with the numUids field to return how many writes and deletes were by a mutation. When deleting data, the mutation returns the state of the objects before deletion. More importantly, Dgraph lets you add and update deeply-nested objects in a single request.

With SQL you would have to add an author, then get the id of the author and use that id to add their post. Or you could add the post and author at the same time, and then retrieve both of their ids and update the post you just added to add the linking foreign key.

GraphQL works especially well for deeply-nested data with two-way relationships. There is no need to handle tedious SQL tasks like writing the last insert ids to pivot tables, because GraphQL stores the edges automatically.