Professional Documents
Culture Documents
Databases Project
Design, implementation, and usage of
a Library db
Project coordinator
Assoc. Prof. Dr.
Christian Mancas
Bucharest
201x
Student:
Table of Contents
1. Business Analysis
1.0 Description of the sub-universe of discourse
1.1 Entity-Relationship Diagrams
1.2 Associated Restrictions List
2. Mathematical Scheme
2.0 Initial Mathematical Scheme
2.1 First refinement algorithm: Sets, Functions, and Constraints
Design Assistance
2.1.1 Sets
2.1.2 Functions
2.1.3 Constraints
2.2 Second refinement algorithm: Keys Discovery Assistance
2.3 Third refinement algorithm: E-RD Cycles Analysis
2.4 Final Mathematical Scheme
3. Relational Scheme and Associated Non-relational Constraints List
3.1 Relational db scheme
3.2 Non-relational constraints list
4. Database Implementation
4.0 Technology choice
4.1 Access db
4.2 Oracle db
5. Non-relational Constraints Implementation
5.1 Access Solutions
5.2 Oracle Solutions
6. Database Usage
6.1 Access Queries and Reports
6.2 Oracle Views and Stored Procedures
Conclusion
References
1. Business Analysis
1.0
The db should store data on books (title, writing year, first author, co-authors, and their order),
people (authors and/or library subscribers) e-mail addresses and first and last names, as well as
books copies borrows by subscribers (borrow, due, and actual return dates).
Books are published by publishing houses, possibly in several editions even by same publishers
(in different years). Each edition may contain several volumes, each having a number, a title, a
price, and an ISBN code. Volumes may contain several books.
The library owns several copies (uniquely identified by an inventory code) of any volume and may
lend several copies for any borrow; not all borrowed copies should be returned at a same date;
maximum lending period is 300 days.
Last names, books titles, first authors, publisher names, editions publishers, first books, and titles,
as well as volumes numbers and prices, copies inventory codes, borrows subscribers, dates, and
due return dates are compulsory; for subscribers, first names and e-mail addresses are compulsory
too.
People are uniquely identified by their first and last names, plus e-mail address, books by their
first author, title, and writing year, publishers by their names, editions by their first book, publisher,
title, and year, volumes by corresponding edition and volume number.
There may be at most:
-
1.1
Entity-Relationship Diagrams
Fname
LName
PERSONS
BTitle
BOOKS
PERSONS
BYear
CO-AUTHORS
BOOKS
PosInList
PUBLISHERS
ETitle
PubName
EDITIONS
ISBN
Number
BOOKS
EYear
Title
VOLUMES
VOLUMES_CONTENTS
BookPos
InvNo
COPIES
BORROWS
BorrowDate
Price
VOLUMES
COPIES
BORROWS_LISTS
DueReturnDate
BORROWS
ActualReturnDate
FirstAuthor
PERSONS
Subscriber
BOOKS
CO-AUTHORS
BORROWS
VOLUMES_CONTENTS
FirstBook
BORROWS_LISTS
Volume
Publisher
COPIES
PUBLISHERS
VOLUMES
Edition
EDITIONS
1.2
1. PERSONS (The set of books (co-)authors and subscribers of interest to the library.)
a. Cardinality: max(card(PERSONS)) = 1,000,000
(RP0)
b. Data ranges:
FName: ASCII(128)
(RP1)
LName: ASCII(64)
(RP2)
e-mail:
ASCII(255)
(RP3)
c. Compulsory data: LName
(RP4)
d. Unicity: e-mail FName LName (there may not
be two persons having same first and last name,
as well as same e-mail address)
(RP5)
e. Other types restrictions:
FName and e-mail should be compulsory for subscribers(RP6)
2. BOOKS (The set of written works of interest to the library.)
a. Cardinality: max(card(BOOKS)) = 1,000,000
(RB0)
b. Data ranges:
BTitle:
ASCII(255)
(RB1)
BYear:
[-2500, current year]
(RB2)
c. Compulsory data: BTitle, FirstAuthor
(RB3)
d. Unicity: FirstAuthor BTitle BYear (no author writes
4
(RB4)
7. VOLUMES_CONTENTS = (BOOKS, VOLUMES) (The set of pairs <b, v> storing the fact
that book b is (also) included in volume v.)
a. Cardinality: max(card(VOLUMES_ CONTENTS)) = 4,000,000
(RVC0)
b. Data ranges: BookPos: [1, 16] (bs position in vs table
of contents)
(RVC1)
c. Compulsory data: Book, Volume, BookPos
(RVC2)
d. Unicity: Volume Book (no book should be included
more than once in any volume)
(RVC3)
e. Other types restrictions:
For any edition, its first book should be the first one
published in its first volume.
(RVC4)
No edition may contain same book more than once.
(RVC5)
8. COPIES (The set of editions volumes copies that the
library possessed.)
a. Cardinality: max(card(COPIES)) = 32,000,000
b. Data ranges: InvNo: ASCII(32)
c. Compulsory data: InvNo, Volume
d. Unicity: InvNo: (by definition, inventory numbers are
unique for any copy)
9. BORROWS (The set of editions volumes copies borrows
by subscribers.)
a. Cardinality: max(card(BORROWS)) =
100,000,000,000
b. Data ranges: BorrowDate: [6/1/2011, SysDate()]
(assuming, for example, that first borrow date of
interest is June 1st, 2011)
c. Compulsory data: BorrowDate, Subscriber
d. Unicity: BorrowDate Subscriber (no subscriber may
simultaneously borrow several times)
(RC0)
(RC1)
(RC2)
(RC3)
(RBR0)
(RBR1)
(RBR2)
(RBR3)
2. Mathematical Scheme
2.0
By applying the algorithm for translating E-RDDs and restriction lists to mathematical schemes,
the following initial scheme results:
PERSONS
x NAT(6), total
FName ASCII(128)
LName ASCII(64), total
e-mail ASCII(255)
CP5: e-mail FName LName key
BOOKS
x NAT(6), total
BTitle ASCII(255), total
BYear [-2500, Year(SysDate())]
FirstAuthor : BOOKS PERSONS, total
CB4: FirstAuthor BTitle BYear key
CO-AUTHORS = (PERSONS, BOOKS)
x NAT(7), total
PosInList [2, 16], total
PUBLISHERS
x NAT(4), total
PubName ASCII(128), total
EDITIONS
x NAT(6), total
7
2.1
Here are the results of applying the design assistance algorithm for:
2.1.1 Sets
a.1 No set is semantically overloaded (so no structural refinements are needed from this point of
view). Please review chapter 2, where this sub-universe modeling is discussed too contrastively,
as compared to several poorer solutions!
a.2 No set is a subset of another set (so no inclusion constraints need to be added to the scheme).
8
a.3 No association-type set has arity greater than two (so none has to be replaced by its equivalent
entity-type set and explicit structural keys and functions corresponding to its canonical Cartesian
projections).
a.4 All binary associations are non-functional:
-
CO-AUTHORS is not functional, because there are persons that wrote several books, as
well as books that were written by several persons.
VOLUMES_CONTENTS is not functional, because there are volumes that contain several
books, as well as books that span across several volumes.
BORROWS_LISTS is not functional, because there are borrows including several copies,
as well as copies borrowed several times.
a.6 No association is homogeneous (so that we need not investigate reflexivity, irreflexivity,
symmetry, anti-symmetry, etc.).
2.1.2 Functions
Edition is onto, because for any edition there should be at least one corresponding volume.
Consequently, the following constraint has to be added to this db scheme:
Edition: VOLUMES EDITIONS, total, onto
Obviously, FName, LastName, e-mail, BTitle, PubName, ETitle, ISBN, VTitle, and InvNo
are not, as not all possible ASCII character combinations (of maximum 255/128/64/32/16
characters) should be first or last person, publisher, or ISBN actual values;
just as no calendar dates (between June 1st 2011 and up to today or next year) or years
(between -2500 and the current one) should (so BYear, EYear, BorrowDate,
DueReturnDate, and ActualReturnDate are not onto either);
just like no naturals (between 1/2 and 16/255) or rationals (between 0 and 99,999,999.99)
should (so PosInList, VNo, VPrice, and BookPos are not onto either).
FirstAuthor is not either, as not only that not all subscribers are authors too (in fact, most
of them are not), but not even all authors are first authors.
Publisher and FirstBook are not either, as it is not compulsory that all possible
publishers/books be editing (to the current db instance knowledge) / edited, respectively.
Volume is not either, as there might be volumes (in the current db instance) for which there
are no copies.
Subscriber is not either, as not all known (to the db instance) persons should have borrowed
books from the library (e.g. Homer, Shakespeare, etc.).
c.1 There are six not formalized constraints; here are their corresponding formalizations:
- RP6: FName and e-mail should be compulsory for subscribers.
CP6: (bBORROWS)(FName(Subscriber(b)) NULLS
11
e-mail(Subscriber(b)) NULLS)
- RVC4: For any edition, its first book should be the first one published in its first volume.
CVC4: (eEDITIONS)(vcVOLUMES_CONTENTS)
(e = Edition(Volume(vc)) FirstBook(e) = Book(vc) BookPos(vc) = 1)
- RVC5: No edition may contain same book more than once.
CVC5: (eEDITIONS)(vc,vcVOLUMES_CONTENTS)
(Edition(Volume(vc)) = Edition(Volume(vc)) Book(vc) Book(vc))
- RBL5: No copy may be borrowed less than 0 days or more than 300 days.
CBL5: (blBORROWS_LISTS)
(0 DueReturnDate(bl) BorrowDate(Borrow(bl)) 300)
- RBL6: No copy may be simultaneously borrowed to more than one subscriber.
CBL6: (bl, blBORROWS_LISTS) (Copy(bl) = Copy(bl))
(ActualReturnDate(bl) NULLS BorrowDate(Borrow(bl) ActualReturnDate(bl)
ActualReturnDate(bl) NULLS BorrowDate(Borrow(bl) ActualReturnDate(bl))
- RBL7: No copy may be returned before it was borrowed and after 100 years since corresponding
borrow date.
CBL7: (blBORROWS_LISTS)
(0 ActualReturnDate(bl) BorrowDate(Borrow(bl)) 36,500)
c.2 There are no other constraints that apply in this sub-universe too, but are missing from this
model.
2.2
Applying the assistance algorithm for keys discovery yields the following:
PERSONS and BOOKS
n = 3, as there are three not one-to-one mappings defined on both of them (FName, LName, and
e-mail for PERSONS, and BTitle, BYear, and FirstAuthor for BOOKS), all being prime in
this context and forming a (semantic) key for each of these two object sets (according to
CP5 and CB4, respectively) no other (semantic) keys may exist for either of these sets.
PUBLISHERS
n = 0 no other semantic key exist.
COPIES
n = 1 (nothing to do, as according to b.2 above, Volume is not one-to-one) no other semantic
key exist.
BORROWS
n = 2 (nothing to do, as according to CBR3 above, BorrowDate Subscriber is minimally one-toone) no other semantic key exist.
12
CO-AUTHORS
n = 3, as there are three not one-to-one mappings defined on it, all of them being prime: the two
canonical Cartesian projections Author and Book, plus PosInList. Obviously, K = {Author
Book}, as CO-AUTHORS is a well-defined binary association (see restriction RCA3).
i = 2:
- Author PosInList key? No, because several authors (and even same ones) may occupy a same
position in different co-author lists.
- Book PosInList key? YES, because in any position of any co-author list only one co-author
may appear.
Consequently, K = {Author Book, Book PosInList}.
EDITIONS
n = 4, as there are four not one-to-one mappings defined on it, all being prime: ETitle, Publisher,
FirstBook, and EYear. According to CE4, K = {Publisher FirstBook EYear}, as this
product is minimally one-to-one.
i=2
- ETitle Publisher key? No, because even a same publisher may publish several editions, even
of a same book (although not necessarily), having same title.
- ETitle FirstBook key? No, because even a same publisher may publish several editions, even
of a same book (although not necessarily), having same title and first book.
- ETitle EYear key? No, because even a same publisher may publish several editions (of different
books, generally) in a same year.
i=3
- ETitle Publisher FirstBook key? No, because even a same publisher may publish several
editions, even of a same book (although not necessarily), having same title and same first
book (in different years).
- ETitle FirstBook EYear key? No, because even a same publisher may publish several editions
(of different books) having same first book, in a same year.
- ETitle EYear Publisher key? No, because even a same publisher may publish several editions
(of different books, generally) in a same year, having same title.
Consequently, EDITIONS does not have any other (semantic) key.
VOLUMES
n = 3, as there are four not one-to-one mappings defined on it: VPrice, VTitle, VNo, and Edition,
but, obviously, VPrice is not prime: prices of volumes might never contribute to their
unique identification in this context. According to RV4, K = {ISBN}.
13
i=2
- VTitle VNo key? No, because even a same publisher may publish several editions including
volumes having same title and number.
- VTitle Edition key? YES, because no edition may contain several volumes having same
title.
- VNo Edition key? YES, because no edition may contain several volumes having same
number.
Consequently, K = {ISBN, VTitle Edition, VNo Edition}.
VOLUMES_CONTENTS
n = 3, as there are three not one-to-one mappings defined on it, all of them being prime: the two
canonical Cartesian projections Volume and Book, plus BookPos. Obviously, K = {Volume
Book}, as VOLUMES_CONTENTS is a well-defined binary association (see restriction
RVC3).
i = 2:
- Book BookPos key? No, because same book may occupy a same position in different volumes
(of different editions).
- Volume BookPos key? YES, because in any position of any volume only one book may
appear.
Consequently, K = {Volume Book, Volume BookPos}.
BORROWS_LISTS
n = 4, as there are four not one-to-one mappings defined on it, all of them being prime: the two
canonical Cartesian projections Copy and Borrow, plus DueReturnDate and
ActualReturnDate. Obviously, K = {Copy Borrow}, as BORROWS_LISTS is a welldefined binary association (see restriction RBL4).
i = 2:
- Borrow DueReturnDate key? No, because there may be for a same borrow several books that
need to be returned at a same date.
- Borrow ActualReturnDate key? No, because there may be for a same borrow several books that
are returned at a same date.
- Copy DueReturnDate key? No, because, for example, a same copy may be borrowed several
times within a same day for only some hours (i.e 0 days).1
Note that, obviously, if DueReturnDate is implemented as a time stamp (i.e. also storing the corresponding time, not
only the date), then this product is a key, but obviously, this should not happen as it does not make that much sense to
also ask for a time deadline in this context.
14
- Copy ActualReturnDate key? No, because, for example, a same copy may be borrowed several
times within a same day for only some hours (i.e 0 days) and actually being returned the
same day at least twice.2
- DueReturnDate ActualReturnDate key? No, because there may be, even for a same borrow,
several books that are both returned at a same date and due to be returned at a same date.
i = 3:
- Borrow DueReturnDate ActualReturnDate key? No, because there may be for a same borrow
several books that need to be returned at a same date and are returned at a same date.
- Copy DueReturnDate ActualReturnDate key? No, because, for example, a same copy may be
borrowed several times within a same day for only some hours (i.e 0 days) and actually
being returned the same day at least twice.
Consequently, BORROWS_LISTS does not have any other (semantic) key.
2.3
By applying the initial step of the algorithm for E-RD cycles analysis, the following 6 cycles are
discovered in the structural E-RD shown in figure A.1.1, out of which 3 are of the commutative
type and other 3 are of the generalized commutative type (see figures A.1.2 to A.1.7 below):
2.3.1 First commutative-type cycle
FirstAuthor
PERSONS
BOOKS
CO-AUTHORS
Figure A.1.2 First commutative-type cycle from A.1.1
Obviously, the corresponding commutativity question is: Coauthor ?= FirstAuthor Book (should,
for any book, any coauthor be its first author?); trivially, the answer is no (as there may be several
coauthors for a book, but there is only one first coauthor for each book, and first authors should
appear only once in the coauthors lists, on the corresponding first position).
Dually, the corresponding anti-commutativity question is: (x CO-AUTHORS) (Coauthor(x) ?
FirstAuthor Book(x)) (should, for any book, any coauthor be distinct than its first author?);
obviously, the answer is yes (as first authors should appear only once in the coauthors lists, on
the corresponding first position). Consequently, the following constraint should be added to the
db scheme:
Note that, obviously, similar to DueReturnDate above, if ActualReturnDate is implemented as a time stamp (i.e. also
storing the corresponding time, not only the date, which would make sense), then this product is a key.
15
PERSONS
Subscriber
BOOKS
CO-AUTHORS
BORROWS
BORROWS_LISTS
VOLUMES_CONTENTS
Volume
VOLUMES
COPIES
Figure A.1.3 First generalized commutative-type cycle from A.1.1
This cycle has three sources (CO-AUTHORS, VOLUMES_CONTENTS, and BORROWS_ LISTS)
and three destinations (PERSONS, BOOKS, and VOLUMES).
Let us consider any elements from the three source nodes: co from CO-AUTHORS, vc from VOLUMES_CONTENTS, and bl from BORROWS_ LISTS; the corresponding three equality questions
(associated to the destination nodes) are the following:
1. Author(co) ?= Subscriber(Borrow(bl)) (are there cases when co-authors of books should
also be borrowers?)
2. Book(co) ?= Book(vc)) (are there cases when co-authored books should also be published
in edition volumes?)
3. Volume(vc) ?= Volume(Copy(bl)) (are there cases when published in edition volumes
should also have borrowed copies?).
Corresponding answers are the following:
1. No: co-authors may be borrowers too, but this is never mandatory.
2. No: on one hand, co-authored (just like any other) books may not be published; on the
other, published volumes need not to be co-authored.
3. On one hand, no: published volumes need not even to be in the librarys possession; on the
other, YES: all borrowed copies have to have been previously published.
Consequently, at a first glance, the following constraint has to be added to the db too:
CBL8:(blBORROWS_LISTS)(vVOLUMES)(Volume(Copy(bl)) = v).
Thinking deeper, this constraint is implied by the following stronger one:
16
This cycle has two sources (VOLUMES_CONTENTS and BORROWS_ LISTS), as well as two
destinations (PERSONS and VOLUMES).
FirstAuthor
PERSONS
BOOKS
Subscriber
BORROWS
BORROWS_LISTS
VOLUMES_CONTENTS
Volume
VOLUMES
COPIES
Figure A.1.4 Second generalized commutative-type cycle from A.1.1
Let us consider any elements from the two source nodes: vc from VOLUMES CONTENTS and bl
from BORROWS_ LISTS; the corresponding two equality questions (associated to the destination
nodes) are the following:
1. FirstAuthor(Book(vc)) ?= Subscriber(Borrow(bl)) (are there cases when first authors of
books should also be borrowers?)
2. Volume(vc) ?= Volume(Copy(bl)) (are there cases when published in edition volumes
should also have borrowed copies?).
Corresponding answers are the following:
1. No: first authors may be borrowers too, but this is never mandatory.
2. On one hand, no: published volumes need not even to be in the librarys possession; on the
other, YES: all borrowed copies have to have been previously published.
Consequently, as per 2.3.2 above, no additional constraint should be added to the db scheme.
17
BOOKS
VOLUMES_CONTENTS
FirstBook
VOLUMES
Edition
EDITIONS
Figure A.1.5 Second commutative-type cycle from A.1.1
Obviously, there is one source (VOLUMES_CONTENTS), one destination (BOOKS), and the
corresponding commutativity question is: Book ?= FirstBook Edition Volume (should, for any
volume, any included book be its first one?); trivially, the answer is no (as there may be several
books for a volume, but there is only one such first book per volume).
Dually, the corresponding anti-commutativity question is: ( x VOLUMES_CONTENTS)
(Book(x) ? FirstBook Edition Volume(x)) (should, for any volume, any included book be
distinct from its first one?); obviously, the answer is no, as the first book is always equal to itself,
so no supplementary constraint should be added to the db scheme in connection with this cycle
(which is an uninteresting one).
2.3.5 Third generalized commutative-type cycle
This cycle has two sources (CO-AUTHORS and BORROWS_ LISTS), as well as two destinations
(PERSONS and BOOKS).
Let us consider any elements from the two source nodes: ca from CO-AUTHORS and bl from
BORROWS_ LISTS; the corresponding two equality questions (associated to the destination nodes)
are the following:
1. Author(ca) ?= Subscriber(Borrow(bl)) (are there cases when co-authors of books should
also be borrowers?)
2. Book(ca) ?= FirstBook(Edition(Volume(Copy(bl))) (are there cases when co-authored
books should also have borrowed copies of volumes of their editions?).
Corresponding answers are the following:
1. No: co-authors may be borrowers too, but this is never mandatory (also see 2.3.2 above).
18
2. On one hand, no: co-authored books need not even to be in the librarys possession; on the
other, no again: not all borrowed copies have to have been co-authored (some might only
have one author).
PERSONS
Subscriber
BOOKS
CO-AUTHORS
BORROWS
FirstBook
BORROWS_LISTS
Volume
VOLUMES
Edition
COPIES
EDITIONS
Obviously, there is one source (BORROWS_LISTS), one destination (PERSONS), and the
corresponding commutativity question is: Subscriber Borrow ?= FirstAuthor FirstBook
Edition Volume Copy (should subscribers borrowing copies be first authors of first books of
the editions to which that volume copies belongs?); trivially, the answer is no (as any subscriber
may borrow books without being either the first or any other co-other of the corresponding book).
Dually, the corresponding anti-commutativity question is: (x BORROWS_LISTS) (Subscriber
Borrow(x) ? FirstAuthor FirstBook Edition Volume Copy(x)) (should subscribers
borrowing copies never be first authors of first books of the editions to which that volume copies
belongs?); obviously, the answer is no (as any first author of a book may borrow that book too),
so no supplementary constraint should be added to the db scheme in connection with this cycle
(which is an uninteresting one too).
19
FirstAuthor
PERSONS
BOOKS
Subscriber
BORROWS
FirstBook
BORROWS_LISTS
Volume
VOLUMES
Edition
COPIES
EDITIONS
Figure A.1.7 Third commutative-type cycle from A.1.1
2.4
By merging all above refinements with the initial scheme from section 2.0 above, the following
final mathematical scheme results:
PERSONS
x NAT(6), total
FName ASCII(128)
LName ASCII(64), total
e-mail ASCII(255)
CP5: e-mail FName LName key
BOOKS
x NAT(6), total
BTitle ASCII(255), total
BYear [-2500, Year(SysDate())]
FirstAuthor : BOOKS PERSONS, total
CB4: FirstAuthor BTitle BYear key
CO-AUTHORS = (PERSONS, BOOKS)
x NAT(7), total
PosInList [2, 16], total
CAK2: Book PosInList key
PUBLISHERS
x NAT(4), total
PubName ASCII(128), total
EDITIONS
x NAT(6), total
20
21
CVC5: (eEDITIONS)(vc,vcVOLUMES_CONTENTS)
(Edition(Volume(vc)) = Edition(Volume(vc)) Book(vc) Book(vc))
CBL5: (blBORROWS_LISTS)
(0 DueReturnDate(bl) BorrowDate(Borrow(bl)) 300)
CBL6: (bl, blBORROWS_LISTS) (Copy(bl) = Copy(bl))
(ActualReturnDate(bl) NULLS BorrowDate(Borrow(bl) ActualReturnDate(bl)
ActualReturnDate(bl) NULLS BorrowDate(Borrow(bl) ActualReturnDate(bl))
CBL7: (blBORROWS_LISTS)
(0 ActualReturnDate(bl) BorrowDate(Borrow(bl)) 36,500)
ACC1: (xCO-AUTHORS) (Coauthor(x) FirstAuthor Book(x))
Note that, as compared to the initial one, 11 more constraints (out of which there are four keys and
seven non-relational ones) have been added to this final one, namely: CAK2; Edition : VOLUMES
EDITIONS, onto; VK1; VK2; VCK2; CVC4; CVC5; CBL5; CBL6; CBL7; and ACC1.
Relational db scheme
By applying the algorithm for translating mathematical schemes into relational ones and nonrelational constraint lists, the following output is obtained (with an example instance having at
least two tuples per table):
PERSONS (x, e-mail FName LName)
x
FName
LName
NAT(6)
ASCII(128)
ASCII(64)
ASCII(255)
NOT NULL
NOT NULL
Homer
William
Shakespeare
Peter
Buneman
Serge
Abiteboul
Dan
Suciu
22
opb@inf.ed.ac.uk
suciu@cs.washington.edu
FirstAuthor
BTitle
BYear
NAT(6)
Im(PERSONS.x)
ASCII(255)
[-2500,
Year(SysDate())]
NOT NULL
NOT NULL
NOT NULL
Odyssey
-700
As You Like It
1600
1999
Book
Person
PosInList
NAT(7)
Im(BOOKS.x)
Im(PERSONS.x)
[2, 16]
NOT NULL
NOT NULL
NOT NULL
NOT NULL
PubName
NAT(4)
ASCII(128)
NOT NULL
NOT NULL
Springer Verlag
Morgan Kaufmann
Penguin Books
23
Publisher
FirstBook
ETitle
EYear
NAT(6)
Im(PUBLISHERS.x)
Im(BOOKS.x)
ASCII(255)
[-2500,
Year(SysDate())]
NOT NULL
NOT NULL
NOT NULL
NOT NULL
The Odyssey
translated by
Robert Fagles
2012
As You Like It
2011
Data on the
Web: From
Relations to
Semistructured
Data and XML
1999
Edition
VNo
VTitle
ISBN
Price
NAT(7)
Im(EDITIONS.x)
[1,
255]
ASCII(255)
ASCII(16)
CURRENCY(8)
NOT
NULL
NOT
NULL
NOT
NULL
0-670-82162-4
$12.95
9781613821114
$9.99
9781558606227
$74.95
NOT NULL
24
Volume
Book
BookPos
NAT(7)
Im(VOLUMES.x)
Im(BOOKS.x)
[1, 255]
NOT NULL
NOT NULL
NOT NULL
NOT NULL
Subscriber
BorrowDate
NAT(11)
Im(PERSONS.x)
[6/1/2011, SysDate()]
NOT NULL
NOT NULL
NOT NULL
10/29/2012
InvNo
Volume
NAT(8)
ASCII(32)
Im(VOLUMES.x)
NOT NULL
NOT NULL
NOT NULL
H-O-1
H-O-2
S-AYLI-1
ABS-DW-1
ABS-DW-2
25
Borrow
Copy
DueReturnDate
ActualReturnDate
NAT(12)
Im(BORROWS.x)
Im(COPIES.x)
[6/1/2011,
SysDate() + 300]
[6/1/2011,
SysDate()]
NOT NULL
NOT NULL
NOT NULL
NOT NULL
11/29/2012
12/29/2012
3.1
11/23/2012
CP6:
(bBORROWS)(FName(Subscriber(b)) NULLS
e-mail(Subscriber(b)) NULLS)
CVC4:
(eEDITIONS)(vcVOLUMES_CONTENTS)
(e = Edition(Volume(vc)) FirstBook(e) = Book(vc) BookPos(vc) = 1)
CVC5:
(eEDITIONS)(vc,vcVOLUMES_CONTENTS)
(Edition(Volume(vc)) = Edition(Volume(vc)) Book(vc) Book(vc))
CBL5:
(blBORROWS_LISTS)
(0 DueReturnDate(bl) BorrowDate(Borrow(bl)) 300)
CBL6:
(blBORROWS_LISTS)
(0 ActualReturnDate(bl) BorrowDate(Borrow(bl)) 36,500)
26
ACC1:
4. Database Implementation
4.0
Technology choice
being the only RDBMS installed on the faculty labs PCs, we did our DB labs in Access;
I have a copy of MS Office 2010, including Access 2010, installed on my PC;
Access is a fine choice for small and medium (up to 2 GB) dbs;
any RDBMS is just a tool: you should exploit it at maximum, do not use its non-sense
facilities, and concentrate on the correctness and optimality of your solution.
being the favorite RDBMS used in western universities DB labs, the DB Labs Notes by
Prof. Christian Mancas and Drd. Alina Dicu also include Oracle solutions, in parallel with
the Access ones;
I have a freely downloadable copy of Oracle Xy installed on my PC;
Oracle is a fine choice for medium and large dbs;
any RDBMS is just a tool: you should exploit it at maximum, do not use its non-sense
facilities, and concentrate on the correctness and optimality of your solution.
4.1
Access db
By applying the algorithm for translating rdb schemes into Access 2010 dbs, the following db was
obtained (note that a Boolean Author? column was added to PERSONS, for easing both nonrelational constraint enforcement and users interaction with the db):
4.1.0
27
28
4.1.1
Tables Relationships
4.1.2.1 PERSONS
Foreign keys BOOKS.FirstAuthor and CO_AUTHORS.Co-Author are using the following query:
SELECT x, IIf(IsNull([FName]),"",[FName] & " ") & [LName] &
IIf(IsNull([e-mail]),""," " & [e-mail])
FROM PERSONS
WHERE [Author?]
ORDER BY IIf(IsNull([FName]),"",[FName] & " ") & [LName] &
IIf(IsNull([e-mail]),""," " & [e-mail]);
4.1.2.2 BOOKS
29
4.1.2.3 PUBLISHERS
4.1.2.4 EDITIONS
4.1.2.5 VOLUMES
4.1.2.6 COPIES
Unfortunately, Access SQL does not provide means for enforcing either (co-)domain (range) or
tuple (check) constraints. Fortunately, both of them can be enforced through its GUI3 by using
validation rules (and associated validation texts).
Figure A.1.9 shows the result of enforcing restriction RB2, the co-domain of BYear : BOOKS
[-2500, current year].
Figure A.1.10 shows the result of enforcing restriction RBR1, the co-domain of BorrowDate :
BORROWS [6/1/2011, SysDate()].
Figure A.1.11 shows the result of enforcing restriction RBL1, the co-domain of DueReturnDate :
BORROWS_LISTS [6/1/2011, SysDate() + 300].
Figure A.1.12 shows the result of enforcing restriction RBL2, the co-domain of ActualReturnDate
: BORROWS_LISTS [6/1/2011, SysDate() + 900].
Figure A.1.13 shows the result of enforcing restriction RCA1, the co-domain of PosInList : COAUTHORS [1, 16].
They can also be manipulated programmatically, through VBA, DAO, and ADO.
31
Figure A.1.10 Enforcing restriction RBR1 and adding default value to BorrowDate
32
33
Figure A.1.13 Enforcing restriction RCA1 and adding default value to PosInList
Figure A.1.14 shows the result of enforcing restriction RE2, the co-domain of EYear : EDITIONS
[-2500, current year].
Figure A.1.14 Enforcing restriction RE2 and adding EYears default value
Figure A.1.15 shows the result of enforcing restriction RV4, the co-domain of VNo : VOLUMES
[1, 255].
34
Figure A.1.15 Enforcing restriction RV3 and adding VNos default value
Figure A.1.16 shows the result of enforcing restriction RVC1, the co-domain of BookPos :
VOLUMES_CONTENTS [1, 16].
Figure A.1.16 Enforcing restriction RVC1 and adding BookPos default value
There are no tuple (check) constraints in this db; figure A.1.17 shows the properties of a table,
where, through its Validation rule (and associated text) such constraints may be enforced.
35
Comments describing sets (tables) semantics are stored in the tables Description property (see
figure A.1.17). Those on functions (columns), in the homonym one of columns (fields, see figures
A.1.9 to A.1.16).
4.1.3.2 Adding default values
Access too provides a Default Value property for functions (columns, fields), which should always
be used when appropriate to spare users repeatedely entering same most frequent values.
Figures A.1.10 and A.1.13 to A.1.16 show the default values added to this db scheme. No other
default values are appropriate.
4.2
Oracle db
36
Ontoness is very easy to enforce: in this case, for example, each time a new edition is inserted, a
corresponding (first) volume should automatically be inserted too and, dually, each time deletion
of the last remaining volume of an edition is successfully committed, the corresponding edition
should be automatically deleted too.
Consequently, this constraint has to be enforced both in the Form_EDITIONS class, by using the
Form_AfterUpdate event (so that the new edition be already saved in the corresponding table) and
in the Form_VOLUMES class, by using the Form_AfterDelConfirm event (so that the last volume
be actually deleted from the corresponding table).
Note that automatically adding a first volume for each new edition, as well as of the first book of
this first volume in its content (see constraint CVC4 below) is also an ergonomic feature of the
application.
Also note that volumes cannot be deleted unless their content is previously deleted too.4 Not only
as the the first book of the first volume of any edition is automatically added, but especially for
ergonomical reasons, the application is also automatically deleting volume contents of any deletable volume, if users agree with it.
Note too that for deleting an edition left without any volume there are two possible solutions:
a tougher one, consisting in deletion of any edition having no volumes (for which no
edition key is necessary)
a softer one, consisting in deleting only the edition just left without any volume (for
which its id should be previously stored in a variable, as, after successful deletion of its last
volume, it cannot be anymore retrieved from the db)
Although it is a little bit more complicated, we chose the second approach mainly because,
anyhow, in order to establish whether or not a volume is deletable and then to also automatically
delete its content, programming of the Form_Delete method is required.
Finally, note that, for ergonomical reasons, after successful automatical deletions and insertions of
both volumes and editions, all involved forms and combo-boxes are requeried, in order for users
not having to close and re-open them for refreshing their data sources.
Here is, first, the code of class Form_VOLUMES:
'Form_VOLUMES class
Option Compare Database
Option Explicit
Private currEdition As Long
37
'*****************************************
Private Sub Form_Delete(Cancel As Integer)
'*****************************************
'Initializes global variable currEdition
'that is then used by Form_AfterDelConfirm.
'Moreover, prevents deletion when there are copies of the
'volume and deletes corresponding volume content if there
'are no copies of the volume and the user agrees with it, 'in order for
deletion to succeed.
On Error GoTo err_point
If vbCancel = MsgBox("Are you sure you want to delete " _
& "the current volume?", _
vbQuestion + vbOKCancel + vbDefaultButton2, _
"Please confirm or cancel your request...") Then
Cancel = True
Else
If Not IsNull(DLookup("x", "COPIES", "Volume=" & Me!x)) Then
Cancel = True
MsgBox "Request denied!", vbCritical, _
"There are copies of this volume..."
Else
If vbCancel = MsgBox("Are you sure you want to also " _
& "delete the content of this volume?", _
vbQuestion + vbOKCancel + vbDefaultButton2, _
"Please confirm or cancel your request...") Then
Cancel = True
MsgBox "Request denied!", vbCritical, _
"To delete volumes, their content must be " _
& "deleted too..."
Else
currEdition = Me!Edition
DoCmd.RunSQL "DELETE FROM VOLUMES_CONTENTS WHERE " _
& "Volume=" & Me!x
End If
End If
End If
Exit Sub
err_point: MsgBox Err.Source & " -> " & Err.Description, _
vbCritical, _
"Error in method Form_VOLUMES.Form_Delete..."
Cancel = True
End Sub
'**********************************************************
Private Sub Form_BeforeDelConfirm(Cancel As Integer,
Response As Integer)
'**********************************************************
'prevents Access from displaying its standard deletion 'confirmation message
Response = acDataErrContinue
End Sub
'**************************************************
Private Sub Form_AfterDelConfirm(Status As Integer)
'**************************************************
38
Secondly, here is the code of class Form_EDITIONS (obviously, not all of it enforces this
constraint, but, as during its enforcement the values of the variables v, b, and p are needed to,
corresponding code could not be understood without their definitions and initializations):
'Form_EDITIONS class
Option Compare Database
Option Explicit
Dim v, b, p As Long
Dim switchPos As Boolean
'*************************
Private Sub Form_Current()
'*************************
On Error GoTo err_point
switchPos = False
Exit Sub
err_point: MsgBox Err.Source & " -> " & Err.Description, _
vbCritical, "Error in method Form_EDITIONS.Form_Current..."
End Sub
'****************************************************
Private Sub FirstBook_BeforeUpdate(Cancel As Integer)
'****************************************************
'enforces constraints CVC4 (for any edition, its first book should be
'the first one published in its first volume) and CVC5
'(no edition should include a book more than once)
Dim w, x As Variant
39
40
41
5.1.2 CP6
(bBORROWS)(FName(Subscriber(b)) NULLS
e-mail(Subscriber(b)) NULLS) (FName and e-mail should be compulsory for subscribers.)
Obviously, enforcing this constraint needs not VBA code, as it can be simply done by adding a
corresponding filter to the SELECT statement of the Subscriber combo-box from BORROWS (also
see 4.1.2.1 above):
SELECT x, [e-mail] & " " & [FName] & " " & [LName]
AS [e-mail First and Last Names]
FROM PERSONS
WHERE [e-mail] Is Not Null AND FName Is Not Null
ORDER BY [e-mail] & " " & [FName] & " " & [LName];
5.1.3 CVC4
(eEDITIONS)(vcVOLUMES_CONTENTS)
(e = Edition(Volume(vc)) FirstBook(e) = Book(vc) BookPos(vc) = 1) (For any edition, its
first book should be the first one published in its first volume.)
As weve already seen, this constraint is enforced by methods FirstBook_ BeforeUpdate and
Form_AfterUpdate of class Form_EDITIONS (see 5.1.1 above).
5.1.4 CVC5
(eEDITIONS)(vc,vcVOLUMES_CONTENTS)
(Edition(Volume(vc)) = Edition(Volume(vc)) Book(vc) Book(vc))
(No edition may contain same book more than once.)
As weve already seen, this constraint is enforced by method FirstBook_ BeforeUpdate of class
Form_EDITIONS (see 5.1.1 above).
5.1.5 CBL5
(blBORROWS_LISTS)
(0 DueReturnDate(bl) BorrowDate(Borrow(bl)) 300) (No copy may be borrowed less
than 0 days or more than 300 days.)
Obviously, this constraint is best enforceable by the DueReturnDate_BeforeUpdate method of
class Form_ BORROWS_LISTS (Note that the corresponding form should never be used alone, but
only as a sub-form of BORROWS: otherwise, on blank lines Me!Borrow could not be always defined!):
'********************************************************
Private Sub DueReturnDate_BeforeUpdate(Cancel As Integer)
'********************************************************
'enforces constraint CBL5: no copy may be borrowed less
42
5.1.6 CBL6
5.1.7 CBL7
(blBORROWS_LISTS)
(0 ActualReturnDate(bl) BorrowDate(Borrow(bl)) 36,500)
(No copy may be returned before it was borrowed and after 100 years since corresponding borrow
date.)
Obviously, this constraint is best enforceable by the ActualReturnDate_ BeforeUpdate method of
class Form_ BORROWS_LISTS:
'**********************************************************
Private Sub ActualReturnDate_BeforeUpdate(Cancel As
Integer)
'**********************************************************
'enforces constraint CBL7: no copy may be returned before
44
5.1.8 ACC1
45
6. Database Usage
6.1
6.1.1 Queries
6.1.1.1 Overdue borrows
Compute the set of all copies that should have been returned at least k (natural) days ago, in the
descending order of the overdue period and then ascending on borrowers e-mail addresses, last,
and first names, and, finally, copies inventory numbers.
Solution:
Obviously, data on overdue copies is stored in table BORROWS_LISTS: any copy having a null in
the ActualReturnDate is not yet returned and by subtracting from the current date the
DueReturnDate one and comparing the result to k the requested set is easily computable.
Of course that from the Copy foreign key the corresponding InvNo may be obtained through a join
with table COPIES and that from the Borrow foreign key the corresponding e-mail, FName, and
LName may be obtained through a join with tables BORROWS and then with table PERSONS (on
foreign key Subscriber).
Consequently, the needed query is the following:
46
Compute the set of borrowers that were late with at least k (natural) days in returning, at least for
n (natural) borrows, and at least m copies per borrow, in descending order of the sum of number
of late returning copies per borrow, then of the number of borrows, and then ascending on e-mail
addresses, last, and first names.
Solution:
Obviously, all copies that are not yet returned and are overdue already with at least k days (that is
exactly the set computed by the above 6.1.1.1 problem) are satisfying the conditions of this
problem. Consequently, this set may be computed by the following query:
SELECT DateDiff("d",[DueReturnDate],Date()) AS OverdueDays,
Borrow, Copy
FROM BORROWS_LISTS
WHERE DateDiff("d",[DueReturnDate],Date())>=[k]
AND ActualReturnDate Is Null;
Moreover, copies that were returned (that is their ActualReturnDate is not null) may have also
been returned with at least k days later than due; this subset is computable by the following query:
47
The union of these two subsets (save it as OverdueCopies) is the base set for computing the final
result:
SELECT DateDiff("d",[DueReturnDate],Date()) AS OverdueDays,
Borrow, Copy
FROM BORROWS_LISTS
WHERE DateDiff("d",[DueReturnDate],Date())>=[k]
AND ActualReturnDate Is Null
UNION
SELECT DateDiff("d",[DueReturnDate],Date()) AS OverdueDays,
Borrow, Copy
FROM BORROWS_LISTS
WHERE ActualReturnDate Is Not Null AND
ActualReturnDate >= DueReturnDate AND
DateDiff("d", DueReturnDate, ActualReturnDate)>=[k];
Next step is computable directly from the above computed set, by grouping on borrows (save it as
OverdueBorrowsAndCopyNo): borrows containing at least m overdue copies; the corresponding
query is the following (where OverdueCopies is the name of the above query):
OverdueBorrowsAndCopyNo:
SELECT Borrow, Count(Copy) AS OverdueCopiesNo
FROM OverdueCopies
GROUP BY Borrow
HAVING Count(Copy)>=[m];
For computing the number of borrows per subscriber and selecting only those subscribers that
have had at least n borrows, the needed query is:
SELECT Subscriber, Count(x) AS BorrowsNo
FROM BORROWS
GROUP BY Subscriber
HAVING Count(x)>=[n];
For further selecting from this set only those borrows that are computed by
OverdueBorrowsAndCopyNo, a join with it is necessary:
SELECT Subscriber, Count(x) AS BorrowsNo,
Sum(OverdueCopiesNo) AS SumOfOverdueCopiesNo
FROM BORROWS INNER JOIN OverdueBorrowsAndCopyNo
ON BORROWS.x = OverdueBorrowsAndCopyNo.Borrow
GROUP BY Subscriber
HAVING Count(x)>=[n];
48
The final result is obtainable from this one (save it as WorseBorrowers0) by replacing subscriber
with corresponding e-mail address, first, and last name (through a join with PERSONS) and by
ordering it in the requested order:
WorseBorrowers:
SELECT SumOfOverdueCopiesNo, BorrowsNo, [e-mail],
FName, LName
FROM WorseBorrowers0 INNER JOIN PERSONS
ON WorseBorrowers0.Subscriber = PERSONS.x
ORDER BY SumOfOverdueCopiesNo DESC, BorrowsNo DESC,
[e-mail], LName, FName;
Design and develop a report with the following data: subscribers e-mail addresses, first, and last
names, borrow, due, and actual return dates, number of overdue days, publisher, editions year and
title, volumes number, ISBN, and title, copies inventory number, volumes first books title, and
their first authors first and last names;
Solution:
The corresponding subjacent query is the following:
SELECT PERSONS.[e-mail], PERSONS.FName, PERSONS.LName,
BorrowDate, DueReturnDate, ActualReturnDate,
IIf(IsNull([ActualReturnDate]),
IIf(Date()>[DueReturnDate],
DateDiff("d",[DueReturnDate],Date()),0),
IIf([ActualReturnDate]>[DueReturnDate],
DateDiff("d",[DueReturnDate],[ActualReturnDate]),
0)) AS OverdueDays, PUBLISHERS.PubName AS Publisher,
EDITIONS.EYear, EDITIONS.ETitle, VOLUMES.VNo, VOLUMES.ISBN,
VOLUMES.VTitle, COPIES.InvNo, BOOKS.BTitle, AUTHORS.FName AS AuthFName,
AUTHORS.LName AS AuthLName
FROM (((EDITIONS INNER JOIN PUBLISHERS
ON EDITIONS.Publisher = PUBLISHERS.x)
INNER JOIN VOLUMES
ON EDITIONS.x = VOLUMES.Edition) INNER JOIN
49
Sums of overdue days are computed for both editions, publishers, borrows, subscribers, and
overall.
Figure A.1.21 shows the corresponding report design view; figures A.1.22 and A.1.23 present the
first and last part, respectively, of the results obtained by running this report in preview mode.
50
6.2
51
7. Conclusion
I have chosen the subuniverse of a Library, for which I designed and implemented a db meant to
be the foundation of a db software application for the management of books, subscribers, and
borrowing.
First, I have applied the algorithm for assisting the business analysis of this subuniverse, with
which I have obtained a corresponding informal description of it, a set of entity-relationship
diagrams, and a list of associated restrictions.
After applying the algorithm for translating entity-relationship diagrams and restriction lists into
mathematic schemes, I have refined the obtained mathematical scheme by applying the following
algorithms:
assistance of sets, functions, and constraints design
assistance of keys discovery
analysis of (structural) entity-relationship diagram cycles.
Next, Ive applied the algorithm for translating mathematical schemes into relational ones and nonrelational constraint lists and, finally, the ones for translating relational schemes into MS Access
2010 dbs and for enforcing non-relational constraints in MS Access 2010,
Finally, I have populated the obtained db with plausible demo data, I have designed and developed
two parameterized queries and a report, which would very much help librarians to extract the most
interesting data and information from this db, and I fully documented the whole process, from the
business analysis and design stages, up the implementation and usage ones.
52
8. Bibliography
1. Mancas, C. & Dicu, A. I. Databases Lab Notes, 2014, Bucharest Polytechnic University.
2. Mancas, C. Databases Lecture Notes, 2014, Bucharest Polytechnic University.
3. Mancas, C. Conceptual Data Modeling and Database Design: A Fully Algorithmic Approach, Volume I: The Shortest Advisable Path, 2015, Apple Academic Press, NJ.
4. Microsoft Corp. Access 2010 Help.
5. IT Services. Microsoft Access 2010 An Essential Guide (Level 1), 2011, The University of
Reading
(freely
downloadable
from
http://www.reading.ac.uk/web/files/its/AccessEssen2010.pdf).
6. IT Services. Microsoft Access 2010 An Intermediate Guide (Level 2), 2011, The University
of
Reading
(freely
downloadable
from
http://www.reading.ac.uk/web/files/its/AccessInter2010.pdf).
7. McDonald, M. Access 2010: The Missing Manual, 2010, OReilly Media (freely
downloadable from http://it-ebooks.info/book/104/).
53