Skip to content

Commit

Permalink
DOC Changing ClassName from Enum to Varchar
Browse files Browse the repository at this point in the history
  • Loading branch information
emteknetnz committed Sep 10, 2024
1 parent a148cb0 commit 98e36cb
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
23 changes: 23 additions & 0 deletions en/02_Developer_Guides/08_Performance/06_ORM.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,26 @@ SilverStripe\ORM\Connect\DBSchemaManager:
```

You can always manually trigger a check and repair (e.g. in a [`BuildTask`](api:SilverStripe/Dev/BuildTask)) by calling [`DB::check_and_repair_table()`](api:SilverStripe\ORM\DB::check_and_repair_table()). This ignores the above configuration.

## Changing `ClassName` column from enum to varchar {#classname-varchar}

On websites with very large database tables it can take a long time to run `dev/build`, which can be a problem when deploying changes to production. This is because the `ClassName` column is an `enum` type which requires an a `ALTER TABLE` query to be run affecting every row whenever there is a new valid value for the column.

For a very rough benchmark, running an `ALTER TABLE` query on a database table of 10 million records took 28.52 seconds on a mid-range 2023 laptop, though this time will vary depending on the database and hardware being used.

You may wish to change the `ClassName` column to a `varchar` type which remove the need to run `ALTER TABLE` whenever there is a new valid value. Enabling this will result in a trade-off where the size of the database will increase by approximately 7 MB per 100,000 rows.

> [!WARNING]
> There will also be a very slow initial `dev/build` as all of the `ClassName` columns are switched to `varchar`.

To enable this, add the following configuration:

```yml
SilverStripe\ORM\DataObject:
fixed_fields:
ClassName: DBClassNameVarchar
SilverStripe\ORM\FieldType\DBPolymorphicForeignKey:
composite_db:
Class: "DBClassNameVarchar('SilverStripe\\ORM\\DataObject', ['index' => false])"
```
19 changes: 19 additions & 0 deletions en/08_Changelogs/5.4.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,31 @@ title: 5.4.0 (unreleased)
## Overview

- [Features and enhancements](#features-and-enhancements)
- [Option to change `ClassName` column from enum to varchar](#classname-varchar)
- [Other new features](#other-new-features)
- [API changes](#api-changes)
- [Bug fixes](#bug-fixes)

## Features and enhancements

### Option to change `ClassName` column from enum to varchar {#classname-varchar}

On websites with very large database tables it can take a long time to run `dev/build`, which can be a problem when deploying changes to production. This is because the `ClassName` column is an `enum` type which requires an a `ALTER TABLE` query to be run affecting every row whenever there is a new valid value for the column. For a very rough benchmark, running an `ALTER TABLE` query on a database table of 10 million records took 28.52 seconds on a mid-range 2023 laptop, though this time will vary depending on the database and hardware being used.

This release introduces a new configuration option to change the `ClassName` column to a `varchar` type which removes the need to run `ALTER TABLE` whenever there is a new valid value.

Enabling this will result in a trade-off where the size of the database will increase by approximately 7 MB per 100,000 rows. There will also be a very slow initial `dev/build` as all of the `ClassName` columns are switched to `varchar`. To enable this, add the following configuration:

```yml
SilverStripe\ORM\DataObject:
fixed_fields:
ClassName: DBClassNameVarchar

SilverStripe\ORM\FieldType\DBPolymorphicForeignKey:
composite_db:
Class: "DBClassNameVarchar('SilverStripe\\ORM\\DataObject', ['index' => false])"
```
### Other new features
- (fill this is as features are added)
Expand Down

0 comments on commit 98e36cb

Please sign in to comment.