1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
|
# Practice Exam
## 1
A real estate company uses a database to store information about customers, property, and contracts.
The following relations are used in the database:
Customer:
* Customer number (unique)
* name
* mailing address
* Balance
* lawyer name
* Discount
Contract:
* Customer number (unique)
* Agent number (unique)
* Property_ID (one per contract)
* Date of contract
* Property addresses
* Property value
* Type
* Number of rooms
* Land size
* Built size
* Tax value
The following functional dependencies apply:
* customer_no -> name
* customer_no -> mail_address
* customer_no -> balance
* customer_no -> lawyer_name
* customer_no -> discount
* {customer_no, Agent_no} -> propert_id
* {customer_no, Agent_no} -> date_contract
* property_id -> property_address
* property_id -> value
* property_id -> type
* property_id -> number_rooms
* property_id -> land_size
* property_id -> built_size
* property_id -> tax_value
Transform these relations into 3NF (please use only the attributes described above, and do not add any new attributes).
Normal forms:
1. 0 multi-valued attributes
2. 0 functional dependencies
3. 0 transitive dependencies
Before:
```text
* Customers(_id_, name, mail_address, balance, lawyer_name, discount)
* Contract(_id_, customer_id, agent_id, date_of_contract, property_address, property_value, type, number_of_rooms, land_size, built_size, tax_value)
```
After:
```text
* customers(_id_, name, mail_address, balance, lawyer_name, discount)
* contracts(_id_, _customer_id_, _agent_id_, _property_id_, date_of_contract)
* properties(_id_, address, value, type, number_of_rooms, land_size, built_size, tax_value)
```
## 2
Draw a class diagram for the following situation.
* An airline company has a number of planes.
* The attributes of a plane include plane_id (unique), name, and vendor.
* The airline company serves many destinations.
* The attributes of a destination include destination_id (unique), name, and flight_date.
* Each plane flies to one or more destinations;
* or it may be used as back-up;
* or it may be under maintenance, and therefore will not fly to any destination.
* For each plane undergoing maintenance, the company records the name of the technician and the type of maintenance performed.
* A destination may be served by one or more planes.
* Each plane’s service charges vary by the number of destinations the plane serves.
* The airline company maintains records of the service charges for each plane when it flies to a certain destination.
* At the end of each year, the airline company applies a depreciation percentage to each plane.
* The airline company calculates each plane’s percent depreciation based on the amount of service charges and the total hours of flying for that plane.
```text
planes(_id_, name, vendor)
destinations(_id_, name, flight_date)
maintenance(_id_, technician_id, plane_id, type)
```
```text
-----------
| Planes |
-----------
| + id |
| + name |
| + vendor |<---------------------
-----------| |
| + calculateServiceChargeForFlightTo(destination) |
----------- |
| |
has_many |
| |
V |
----------------- |
| maintenance | |
----------------- |
| id | A
| technician_id | |
| plane_id |-- belongs to --|
| type | |
----------------- |
| | |
----------------- |
| |
belongs_to |
| |
V |
----------------- |
| technician | |
----------------- |
| id | |
----------------- |
| | |
----------------- |
|
--------------- |
| destination | |
--------------- A
| id | |
| name | ---belongs to ---|
| plane_id | |
| flight_date | |
--------------- |
| | |
--------------- |
A |
| |
belongs_to |
| |
------------------ |
| service charge | A
------------------ |
| id | |
| plane_id | -- belongs to |
| destination_id |
------------------
| |
------------------
```
## 3
Consider the following three relations:
```text
Manager(name, address, specialization, salary)
Employee(name, address, rank, salary)
Project (proj_num, emp_name, manager_name, duration)
```
Write the SQL queries corresponding to the following questions.
a. Find the number of different employees who are assigned to projects.
```sql
SELECT count(distinct(e.name))
FROM Employee e
WHERE e.name IN (SELECT DISTINCT(emp_name) FROM PROJECT);
```
or
```sql
SELECT count(distinct(e.name))
FROM Employee e
INNER JOIN Project p on p.emp_name = e.name;
```
b. Find the managers' average salary.
```sql
SELECT AVG(m.salary)
FROM Manager m;
```
c. List the name and number of projects supervised by each manager.
```sql
SELECT p.manager_name, count(p.proj_numb)
FROM Project p
GROUP BY p.manager_name;
```
d. Show the names and salaries of managers who supervise employees of rank "beginner" in ascending
order of salary (use a subquery).
```sql
SELECT m.name, m.salary
FROM Manager m
WHERE m.name in (
SELECT p.manager_name
FROM Project p
INNER JOIN Employee e on e.name = p.emp_name
WHERE e.rank = 'beginner'
)
ORDER BY m.salary ASC;
```
or
```sql
SELECT m.name, m.salary
FROM Manager m
WHERE m.name in (
SELECT p.manager_name
FROM Project p
WHERE p.emp_name IN (
SELECT e.name
FROM Employee e where e.rank = 'beginner'
)
)
ORDER BY m.salary ASC;
```
e. Show the names and salaries of managers who supervise employees of rank "beginner" in
descending order of salary (do not use a subquery).
```sql
SELECT m.name, m.salary
FROM Manager m
INNER JOIN Project p on p.manager_name = m.name
INNER JOIN Employee e on e.name = p.emp_name
WHERE e.rank = 'beginner'
ORDER BY m.salary ASC;
```
f. Show the names and salaries of supervisors who supervise more than 20 employees.
```sql
SELECT m.name, m.salary
FROM Manager m
WHERE m.name IN (
SELECT p.manager_name
FROM Project p
GROUP BY p.manager_name
HAVING COUNT(p.manager_name) > 20
):
```
## 4
Consider the following database.
```text
TRAVEL-AGENT (name, age, salary)
CUSTOMER (name, departure_city, destination, journey_class)
TRANSACTION (number, cust_name, travel_agent_name, amount_paid)
```
a. Write a SQL query to display the names of all travel agents who arranged trips for customer "John Smith".
```sql
SELECT ta.name
FROM "Travel-Agent" ta
WHERE ta.name IN (
SELECT DISTINCT(travel_agent_name)
FROM TRANSACTION t
WHERE t.cust_name = 'John Smith'
);
```
b. Define indexes on selected attributes to speed up your query. Justify your selections.
```sql
CREATE INDEX ON "Travel-Agent" (name); -- Joining on travel_agent.name
CREATE INDEX ON Transaction (cust_name); -- filtering by cust_name
```
## 5
Suggest an appropriate recovery technique for each of the following situations.
a. You were working from home and updating a database at work when the transaction was aborted.
Rollback the transaction and try again.
b. A customer service representative entered an incorrect data price for a customer transaction.
Several weeks after the accounting department has processed the transaction,
the customer returned and discovered the mistake.
Add a new compensating transaction to fix the mistake.
## 6
Contrast two-tier architecture with three-tier architecture.
Two tier architectures
```text
|--------|
| Server | * storage logic
|--------|
| Client | * processing logic
| | * presentation logic
|--------|
|--------|
| Server | * storage logic
| | * processing logic
|--------|
| Client | * presentation logic
|--------|
```
3 tier architecture
```text
|--------|
| db | * storage logic
|--------|
| app | * processing logic
|--------|
| client | * presentation logic
|--------|
```
## 7
a. Briefly contrast transient data with periodic data in data warehousing.
> Transient data: in which changes to existing records are written over previous records, thus destroying the previous data content.
> Periodic data: data that are never physically altered or deleted once they have been added to the store.
b. Briefly discuss the characteristics of a surrogate key, as used in a data warehouse or data mart.
Surrogate Key
Every key used to join the fact table with a dimension table should be a surrogate (system assigned) key.
Why?
* Business keys change, often slowly, over time and we need to remember old and new business key values for the same business object.
* Using a surrogate key also allows us to keep track of different non-key attribute values for the same product production key with several surrogate keys, each for the different package sizes.
* Surrogate keys are often simpler and shorter
* Surrogate keys can be of the same length and format for all keys
|