# Design: Database User Experience
**Author**: @worstell
<!-- Status of the document - draft, in-review, etc. - is conveyed via HackMD labels -->
## Declaring Databases
Databases are declared using discoverable file locations with a required hierarchy:
**Go**
```
db/
├── mysql/ # must be exactly "mysql" or "postgres"
│ └── mydb/ # database name
│ ├── schema/ # contains migration files
│ └── queries/ # contains query files
│ └── config.toml # additional configurations
```
**JVM**
```
src/main/resources/
└── db/
├── mysql/ # must be exactly "mysql" or "postgres"
│ └── mydb/ # database name
│ ├── schema/ # contains migration files
│ └── queries/ # contains query files
│ └── config.toml # additional configurations
```
A `schema` subdirectory must be present in order for the DB to be extracted to the schema (and consequently provisioned).
The DB can be created manually or via CLI:
```
ftl mysql new <module-name>.<db-name>
ftl postgres new <module-name>.<db-name>
```
The following:
```
ftl mysql migration new example.mydb
```
Will create the `db/postgres/mydb` directory containing an empty `schema` directory and `config.toml` file with no contents. This database will be provisioned at the next deploy.
Users can optionally supply additional configurations in the `config.toml`.
```toml
timeout = 60000
max_connections = 5
... other configs
```
Like declaring the DB itself, users can add or update DB configs either manully or via the CLI. Something like this:
```
ftl database configure <module-name>.<db-name> key,value
```
Where the following would produce the example above:
```
ftl database configure example.mydb timeout,60000
ftl database configure example.mydb max_connections,5
```
### Accessing Databases
Any queries in `.sql` files found in the `queries.sql` subdirectory are generated into type-safe SQL verbs.
We'll also generate a handle for raw queries using the runtime-native driver. If no queries directory is present, or if the queries directory is empty, this handle is the only means to communicate with the DB.
**Generated handle**:
```go!
type Mydb struct {}
type MydbHandle = ftl.DatabaseHandle[Mydb]
```
**Example user code:**
```go!
//ftl:verb
func RawQuery(ctx context.Context, db MydbHandle) error {
db.Get(ctx).Query("SELECT data FROM requests ORDER BY created_at;")
...
}
```