left-join for robustness; if there is no matching record in Page, we can return a record with a blank Article field.
## Staging and versioning
[todo]
## Schema auto-generation
SilverStripe has a powerful tool for automatically building database schemas. We've designed it so that you should never have to build them manually.
To access it, visit (site-root)/dev/build?flush=1. This script will analyze the existing schema, compare it to what's required by your data classes, and alter the schema as required.
Put the ?flush=1 on the end if you've added PHP files, so that the rest of the system will find these new classes.
It will perform the following changes:
* Create any missing tables
* Create any missing fields
* Create any missing indexes
* Alter the field type of any existing fields
* Rename any obsolete tables that it previously created to _obsolete_(tablename)
It **won't** do any of the following
* Deleting tables
* Deleting fields
* Rename any tables that it doesn't recognize - so other applications can co-exist in the same database, as long as their table names don't match a SilverStripe data class.
## Related code
The information documented in this page is reflected in a few places in the code:
*`[api:DataObject]`
* requireTable() is responsible for specifying the required database schema
* instance_get() and instance_get_one() are responsible for generating the database queries for selecting data.
* write() is responsible for generating the database queries for writing data.
*`[api:Versioned]`
* augmentWrite() is responsible for altering the normal database writing operation to handle versions.
* augmentQuery() is responsible for altering the normal data selection queries to support versions.
* augmentDatabase() is responsible for specifying the altered database schema to support versions.
*`[api:MySQLDatabase]`: getNextID() is used when creating new objects; it also handles the mechanics of
updating the database to have the required schema.
## Future work
* We realise that a fixed mapping between the database and object-model isn't appropriate in all cases. In particular,
it could be beneficial to set up a SilverStripe data-object as an interface layer to the databases of other
applications. This kind of configuration support is on the cards for development once we start looking more seriously
at providing avenues for clean integration between systems.
* Some developers have commented that the the database layer could be used to maintain the relational integrity of this
database structure. I don't know whether MySQL supports this or not, but in any case, this stuff would be available in
other database platforms if we chose to support them.
* We'd like to support more than just MySQL, however, there needs to be a pretty good reason for doing so since it will
become something that needs to be supported for the rest of SilverStripe's life and could easily become an albatross.