like key-value stores, graph databases not only manage nodes, but also edges. Edges are things that connect two other data elements, and graph datastores have them as a basic element managed by the store. Think of them as the line between two boxes; thats exactly what they are.Edges often take developers a while to get used to, because there isnt much precedent in the world of software. Even the so-called relational database doesnt actually have relationships as a first-class concept: we have to infer them from primary/foreign key declarations; and that only works if developers actually declare them, which is not all that common.Edges dont exist in normal code either. Pretty much all mainstream programming languages only have pointers, not relationships aka edges. Edges are bidirectional, managed things, while pointers are one-directional and not managed at all. Lets take an example (using a simplified version of the InfoGrid API, see the FirstStep example for complete code of a basic URL tagging application):MeshObject customer = createMeshObject(); // create first node, called MeshObject in InfoGridMeshObject order = createMeshObject(); // create second nodecustomer.relate( order );What did we just do?We created a customer object, and an order object, and then we said the two are related. (The graph database makes sure the objects get persisted automatically when the Transaction is closed; not shown here as we try to stay on topic.)If we had to do that in straight Java, wed do something like this:Customer customer = new Customer();Order order = new Order();customer.addOrder( order );order.setCustomer( customer );and wed have to write the code to manage the edge ourselves, such as:class Customer { ... private List<Order> ordersOfThisCustomer = new ArrayList<Order>();}class Order { ... private Customer customerPlacingThisOrder;}The question is: why do we have to do all this work for a simple 1-N relationship between customers and orders? The graph database API is much better: for one, it lets the database worry about how and when to save and restore the involved objects. It could, for example, (as InfoGrid does), decide to restore from disk the Customer object but not the Order object for some time because the application code does not currently need to know the Customers orders. And referential integrity is always guaranteed. For example:customer.traverseToNeighbors().getSingleMember(); // returns the single Order objectorder.traverseToNeighbors().getSingleMember(); // returns the single Customer object// now we delete the edgecustomer.unrelate( order );customer.traverseToNeighbors().getSingleMember(); // returns nullorder.traverseToNeighbors().getSingleMember(); // returns nullIf there is no graph database involved, we need to do it manually, like this:customer.removeOrder( order );order.setCustomer( null );... and hope that we dont forget one of those calls, because then referential integrity would be out the window, and the next application crash is a certainty.Imagine if we wanted to restore the Customer and the Order object at different times from disk. Without help from sophisticated run-time infrastructure like a graph database, band-aid-technologies such as object-relational mapping is most likely going to create a separate instance for, say, the restored Order object, and code such as List.remove( ... ) is not going to work because we have two Java objects in memory that represent the same order. (Shudder.)Of course,