In the Joining layer data recipe, we discussed that joins only append additional columns to existing features (1:1 or n:1 relationships). Using joins, it is, therefore, not possible to model 1:n relationships, such as "one zip code area containing n schools". These kinds of relationships can instead be modeled using relations. This recipe introduces the concept of relations and shows how you can put them to use.
To follow this exercise, load zip code areas and schools from zipcodes_wake.shp and schools_wake.shp.
Relations are configured in Project Properties. The dialog is very similar to the join dialog:


As the preceding screenshot shows, setting up this relation enables you to get access to all schools within a certain zip code in a very convenient way. As the edit button suggests, it is even possible to edit the school data from this view. You can simply edit the values in the table view. You can add and delete schools from the dataset using the + and X buttons. The next two buttons enable you to quickly add new entries to the relation or to remove them.
In this example, removing a school from the dataset works just fine, but adding a school via this dialog makes less sense because you cannot create a point geometry through this process.
If you press the button to add to the relation, you will get a dialog that allows you to choose which existing school you want to add. In the background, the school's ADDRZIPCOD value is updated to match the zip code we just assigned it to.
Similarly, if you select a school and press the button to remove the relation, what actually happens is that the school's ADDRZIPCOD value is set to NULL.