CiviCRM Schema Design¶
A number of Entity-Relationship Diagrams are available which help with exploring and better understanding the CiviCRM database design.
Alternate Methods to ERDs to explore CiviCRM's Database Design¶
Another method of viewing CiviCRM's Database model is to use one of various MySQL coding tools e.g. DBeaver, PHPMyAdmin or MySQL Workbench. These tools allow coders to inspect the Table Structure more easily and look at all the constraints attached to tables very easily.
MySQL Workbench Workflow¶
- Look at the list of tables in the database. The table name generally gives you a good idea of the type of data it stores.
- Pick one table and look closer. Let's look at
civicrm_country(a relatively simple example) by opening the "Table inspector" for that table.- We can look at the list of columns in the table.
We can see that columns have comments which explain (to some extent) the meaning of the data stored in the columns. From the Column Names and the comments we can start to get some idea of the relationship between tables. For example we can see that there is a column address_format_idwhich indicates to us that the tablecivicrm_countryhas a relationship to the tablecivicrm_address_format - We can also look at the Foreign Keys that are relevant to this table
Here we can get more of a comprehensive picture of what tables civicrm_countryrelates to. We can tell that because we see not only what tables are referenced bycivicrm_countrybut also the tables that referencecivicrm_country.
- We can look at the list of columns in the table.
General Characteristics of CiviCRM Tables¶
When we look at CiviCRM Tables there are a few patterns that generally hold true:
- Every table has a id column which is Auto Increment and therefore unique key for that table
- Columns which reference other tables generally speaking will be named in the format of
other table name+_id. For example incivicrm_countrythere isaddress_format_idwhich indicates that is referencescivicrm_address_format.id - Many-to-many relationships use "join tables" as intermediary tables. For example, a contact can have many activity records, and an activity can have many contact records. So the table
civicrm_activity_contactis used as the glue because it has foreign keys to both. - In some places CiviCRM defines schema using a construct called Pseudoconstants which produces some slightly more complex logic
- Lots of columns reference
civicrm_option_valueswhen they just need a simple (and user-configurable) list of options. For example, look atcivicrm_contributionwhich has a column calledpayment_instrument_id. You'll notice there's no table calledcivicrm_payment_instrument. So in this case thepayment_instrument_idcolumn actually references the value column incivicrm_option_values(but only for records incivicrm_option_valueswith the appropriateoption_group_id.) Here there is no foreign key, so referential integrity is managed at the application layer, not the database layer. - Some tables use "dynamic foreign keys". For example, look at
civicrm_notewhich has columnsentity_idandentity_table. This is because a note can be attached to different entities (e.g. contact, contribution, etc). So two columns are used to indicate what the note references. Here again, the application layer is responsible for ensuring referential integrity, so you won't find any foreign keys.
- Lots of columns reference