Object relational mapping - Relations - Foreign key constraints - Introduction.php 1.83 KB
Newer Older
hansbrix's avatar
hansbrix committed
1 2 3 4 5
A foreign key constraint specifies that the values in a column (or a group of columns) must match the values appearing in some row of another table. In other words foreign key constraints maintain the referential integrity between two related tables.

Say you have the product table with the following definition:

<code type='php'>
lsmith's avatar
lsmith committed
6
class Product extends Doctrine_Record
hansbrix's avatar
hansbrix committed
7
{
lsmith's avatar
lsmith committed
8
    public function setTableDefinition()
hansbrix's avatar
hansbrix committed
9 10 11
    {
        $this->hasColumn('id', 'integer', null, 'primary');
        $this->hasColumn('name', 'string');
lsmith's avatar
lsmith committed
12
        $this->hasColumn('price', 'decimal', 18);
hansbrix's avatar
hansbrix committed
13 14 15 16 17 18 19 20 21
    }
}
</code>

Let's also assume you have a table storing orders of those products. We want to ensure that the order table only contains orders of products that actually exist. So we define a foreign key constraint in the orders table that references the products table:

<code type='php'>
class Order extends Doctrine_Record
{
lsmith's avatar
lsmith committed
22
    public function setTableDefinition()
hansbrix's avatar
hansbrix committed
23 24 25 26 27 28 29 30
    {
        $this->hasColumn('order_id', 'integer', null, 'primary');
        $this->hasColumn('product_id', 'integer');
        $this->hasColumn('quantity', 'integer');
    }
    public function setUp()
    {
        $this->hasOne('Product', 'Order.product_id');
lsmith's avatar
lsmith committed
31

hansbrix's avatar
hansbrix committed
32
        // foreign key columns should *always* have indexes
lsmith's avatar
lsmith committed
33

hansbrix's avatar
hansbrix committed
34 35 36 37 38
        $this->index('product_id', array('fields' => 'product_id'));
    }
}
</code>

lsmith's avatar
lsmith committed
39
When exported the class 'Order' would execute the following sql:
hansbrix's avatar
hansbrix committed
40 41 42 43 44 45 46 47 48 49

CREATE TABLE orders (
    order_id integer PRIMARY KEY,
    product_id integer REFERENCES products (id),
    quantity integer,
    INDEX product_id_idx (product_id)
)

Now it is impossible to create orders with product_no entries that do not appear in the products table.

lsmith's avatar
lsmith committed
50
We say that in this situation the orders table is the referencing table and the products table is the referenced table. Similarly, there are referencing and referenced columns.