The serial
field modifier causes the primary key value to be generated
by the database (using an auto-number or sequence).
One challenge that this causes is the problem of seeding the database, since the primary key value is not known, and may not be the same value if run on different databases.
Let's consider our Customer and Address types. We have changed Customer to use `serial’
type Customer struct {
id int primaryKey serial
name string
relation addr Address one optional
} end
type Address struct {
id int primaryKey
relation cust Customer one
street string
city string
state string
} end
Inserting the customer is easy:
insert Customer { name: 'bob smith'}
But how to specify the address? There is no way to know what value for
id
the database generated.
//THE FOLLOWING IS NOT CORRECT!!
insert Address { id: 1, cust: ???, street: '101 Main St', city: 'Chicago', state: 'IL'} //this will fail
Synthetic IDs are values that exist in Delia memory only (not the database), and are used to establish a correspondence between two rows being inserted into the database.
Synthetic IDs can be enabled for a type using the configure
statement.
All subsequent insert
statements for that type can use the synthetic ID
as if it were a normal field.
Then the other side of the relation can be inserted, mentioning the synthetic ID value. Delia will extract the primary key that was generated and use it.
configure Customer.synthetic_id='synth_id'
insert Customer { name: 'bob smith', synth_id: 1000}
insert Address { id: 1, cust: 1000, street: '101 Main St', city: 'Chicago', state: 'IL'}
When synthetic ids are enabled, the performance of insert
statements for that type may be reduced, because Delia needs to extract the
generated primary keys.