Databases Reference
In-Depth Information
dispatch a parcel to a customer's delivery address, which we find using the following
query:
START
user=
node
:users(
id
=
{userId}
)
MATCH
(user)-[:DELIVERY_ADDRESS]->(address)
RETURN
address
Later on, when adding some billing functionality, we introduce a
BILLING_ADDRESS
relationship. Later still, we add the ability for customers to manage all their addresses.
This last feature requires us to find all addresses—whether delivery, or billing, or some
other address. To facilitate this, we introduce a general
ADDRESS
relationship:
START
user=
node
:users(
id
=
{userId}
)
MATCH
(user)-[:ADDRESS]->(address)
RETURN
address
By this time, our data model looks something like the one shown in
Figure 4-8
.
DELIV
ERY_ADDRESS
specializes the data on behalf of the application's fulfillment needs;
BILL
ING_ADDRESS
specializes the data on behalf of the application's billing needs; and
AD
DRESS
specializes the data on behalf of the application's customer management needs.
Figure 4-8. Different relationships for different application needs
Being able to add new relationships to meet new application needs doesn't mean we
should always do this. We'll invariably identify opportunities for refactoring the model
as we go: there'll be plenty of times, for example, where renaming an existing relation‐
ship will allow it to be used for two different needs. When these opportunities arise, we
should take them. If we're developing our solution in a test-driven manner—described
in more detail later in this chapter—we'll have a sound suite of regression tests in place,
enabling us to make substantial changes to the model with confidence.
Application Architecture
In planning a graph database-based solution, there are several architectural decisions
to be made. These decisions will vary slightly depending on the database product we've