❖ Mapping ER to SQL |
We have explored mapping ER designs to relational schemas
SQL schemas are essentially more detailed versions of relational schemas
The mapping is much the same, except that
❖ Reminder: SQL/Relational Model vs ER Model |
Correspondences between SQL/relational and ER data models:
❖ Mapping ER to SQL |
Some conventions that we use in mapping ER to SQL
tableTABLEprimary keytexttable_id❖ Mapping Strong Entities |
An entity set E with atomic attributes a1, a2, ... an
maps to
A table R with attributes (columns) a1, a2, ... an
Example:
Note: the key is preserved in the mapping.
❖ Mapping N:M Relationships (cont) |
create table Customers (
custNo serial primary key,
name text not null,
address text -- don't need to know customer's address
);
create table Accounts (
acctNo char(5) check (acctNo ~ '[A-Z]-[0-9]{3}'),
title text not null, -- acctNos are like 'A-123'
balance float default 0.0,
primary key (acctNo)
);
create table Owns (
customer_id integer references Customers(custNo),
account_id char(5) references Accounts(acctNo),
last_accessed timestamp,
primary key (customer_id, account_id)
);
❖ Mapping 1:N Relationships (cont) |
create table Branches (
branchNo serial primary key,
address text not null,
assets currency
);
create table Customers (
custNo serial primary key,
name text not null,
address text,
hasHome integer not null, -- total participation
joined date not null,
foreign key (hasHome) references Branches(branchNo)
);
hasHomenot null
❖ Mapping 1:1 Relationships (cont) |
create table Branches (
branchNo serial primary key,
address text not null,
assets currency -- a new branch
); -- may have no accounts
create table Managers (
empNo serial primary key,
name text not null,
salary currency not null, -- when first employed,
-- must have a salary
manages integer not null, -- total participation
foreign key (manages) references Branches(branchNo)
);
If both entities have total participation, cannot express this in SQL
except by putting a (redundant) not null
❖ Mapping n-way Relationships |
Example:
A customer accesses one of their accounts at a specific ATM
❖ Mapping n-way Relationships (cont) |
create table Customers (
custNo serial primary key, ...
);
create table Accounts (
acctNo char(5) ... primary key, ...
);
create table ATMs (
atmID serial primary key,
cash currency check (cash >= 0),
location text not null
);
create table Withdrawal (
customer_id integer references Customers(custNo),
account_id char(5) references Accounts(acctNo),
atm_id integer references ATMs(atmID),
amount currency not null,
when timestamp default now(),
primary key (customer_id,account_id,atm_id)
);
❖ Mapping Composite Attributes |
Composite attributes are mapped by concatenation or flattening.
Example:
❖ Mapping Composite Attributes (cont) |
-- Version 1: concatenated create table People ( ssn integer primary key, name text not null, address text not null ); -- Version 2: flattened create table People ( ssn integer primary key, given text not null, family text, number integer not null, street text not null, suburb text not null, pcode char(4) not null check (pcode ~ '[0-9]{4}') );
address(number::text||' '||street||', '||suburb||' '||pcode)
Searching: suburb = 'Coogee'address like '%Coogee%'
Sorting: order by family
❖ Mapping Multi-valued Attributes (MVAs) |
MVAs are mapped by a new table linking values to their entity.
Example:
❖ Mapping Multi-valued Attributes (MVAs) (cont) |
create table People (
ssn integer primary key,
name text not null,
birthday date
);
create table FavColour (
person_id integer references People(ssn),
colour text,
primary key (person_id,colour)
);
Note that colournot null
❖ Mapping Subclasses |
Three different approaches to mapping subclasses to tables:
❖ Mapping Subclasses (cont) |
create table People (
ssn integer primary key,
name text not null,
address text
);
create table Employees (
person_id integer primary key,
salary currency not null,
position text not null,
foreign key (person_id) references People(ssn)
);
create table Managers (
employee_id integer primary key,
bonus currency,
foreign key (employee_id)
references Employees(person_id)
);
❖ Mapping Subclasses (cont) |
create table People (
ssn integer primary key,
name text not null,
address text
);
create table Employees (
ssn integer primary key,
name text not null,
address text
salary currency not null,
position text not null,
foreign key (snn) references People(ssn)
);
create table Managers (
ssn integer primary key,
name text not null,
address text
salary currency not null,
position text not null,
bonus currency,
foreign key (snn) references People(ssn)
);
❖ Mapping Subclasses (cont) |
create table People (
ssn integer primary key,
ptype char(1) not null
check (ptype in ('P','E','M')),
name text not null,
address text
salary currency,
position text,
bonus currency,
constraint subclasses check
((ptype = 'P' and salary is null
and position is null and bonus is null)
or
(ptype = 'E' and salary is not null
and position is not null and bonus is null)
or
(ptype = 'M' and salary is not null
and position is not null and bonus is not null))
);
❖ Mapping Subclasses (cont) |
Example:
Every employee is either permanent or casual, but not both.
❖ Mapping Subclasses (cont) |
ER-style mapping to SQL schema:
create table Employees (
empID serial primary key,
name text not null,
address text not null
);
create table Permanents (
employee_id integer primary key,
salary currency not null,
foreign key (employee_id) references Employees(empID)
);
create table Casuals (
employee_id integer primary key,
pay_rate currency not null,
foreign key (employee_id) references Employees(empID)
);
Does not capture either participation or disjoint-ness constraints!
Would need to program a solution to this e.g web-form that requires user to enter both Employee and subclass info
Produced: 22 Sep 2020