ソフトウェア工学特論 （８） 田中 譲
The easy composition of new pads will bring a rapid accumulation of a large number of different pads. • It will become seriously difficult for us to find an appropriate pad out of such an accumulation. • We will need a new technology for the management and the retrieval of pads. • In this chapter, we will consider how to manage and search a large set of pads, and how the required technologies are related to relational database and object-oriented database technologies.
Relational Databases, Object-Oriented Databases and Instance Bases • RDB • Each DB as a set of relations. • Each relation is a set of records called tuples • Each tuple in a relation can be uniquely identified by the value of a set of attributes. • One such minimal attribute set is specified as the primary key of the relation. • Relational database systems manage tuples in each relation by providing them with identifiers called tuple identifiers. • In each relation, a one-to-one correspondence holds between the primary key values and the tuple identifiers. • Relational database systems provide indices for some attributes in order to improve their search performance. • An index for an attribute of a relation maps each existing value of this attribute to a list of identifiers of those tuples that take this specified value for this specified attribute. In each relation, the attributes with indices are called indexed attributes.
Object-oriented database (OODB) • Each database is a set of classes. • A class in this model plays two roles. • First, it defines an object type. • Second, it represents a set of objects of the defined type. • Objects of the same type accept the same set of messages. • Objects in an OODB are uniquely identified by their object identifiers, and persistent in the sense that they continue to exist unless explicitly deleted. • Classes in OODBs correspond both to relations and to relation types in relational databases, while objects and the messages accepted by them respectively correspond to records and their attributes.
One of the most serious problems in OODBs is their performance. • OODBs allow us to write message sending sentences even for the specification of query conditions, which means that these messages are sent to all the objects in a target class in order to select those satisfying these conditions unless this message-sending can be a priori evaluated. • If a message to an object just returns a value and does not cause any other side effects, i.e., if it works as an attribute of this object, this message sending can be a priori evaluated. • If a message we use in query specifications works as an attribute, and if its return values can be indexed, then we can a priori provide an index file for this message to map each existing return value of this message to a list of object identifiers of those objects that return this specified value when receiving this message. • The provision of such an index file for every message that is used in the condition specification part of the queries can improve the performance of query processing to the performance level of relational databases.
OODBs are roughly classified into two categories, • structural OODBs and • behavioral OODBs. • In a structural OODB, all the messages used in the condition specification part of queries work as attributes. • Structural OODBs can provide each class with indices for all of the messages used in the condition specification part of the queries. • Their performance, therefore, is comparable to that of relational database systems. • Structural OODBs whose messages all work as attributes are sometimes called extended relational databases. • They are extended from relational databases by allowing attributes to take complex and/or composite values. • Examples of structural OODBs include Postgress  and UniSQL. . Postgress was later marketed as Illustra , which was then integrated with Informix.
Behavioral OODBs are those OODBs that are not structural. • Since these cannot take the advantage of the indexing technique, they inherently suffer in their search performance when applied to large databases. • For this reason, a behavioral OODB is sometimes considered as an extension of an object-oriented programming language through the introduction of object persistency. Such an extended language is called a DBPL (Database Programming Language). Such behavioral OODBs are called DBPL databases. • From a practical point of view, behavioral OODB systems, namely DBPL database systems, are only applicable to either small databases or to object-by-object retrieval systems that do not extensively use complicated set operations. • Examples of behavioral OODBs include ObjectStore  using an extension of C++, GemStone  using an extension of Smalltalk, ODMG model , Orion  with its model patterned on Smalltalk and Lisp, and O2 .
Object-oriented programming includes two different programming paradigms, • the refinement paradigm and • the composition paradigm. • In the refinement paradigm, we define objects starting from general objects and proceeding to more specific ones by adding new properties to the previously defined objects. • Objects are defined by their properties. A set of properties defines a type of objects. This is called an object class, or simply a class. • Each class is defined as a refinement of a previously defined class. • To distinguish objects from their classes, they are called instance objects. • In the refinement paradigm, each new instance object can be created only through sending a message new to some class.
In the composition paradigm on the other hand, a new instance object is defined by combining some existing instance objects. • Combined instance objects are functionally linked together to define a composite instance object. • While primitive objects may have their corresponding classes, composite ones have no corresponding classes. • This is quite different from the situation of the refinement paradigm. • The composition paradigm is extensively used especially in GUI toolkit systems. • Most object-oriented languages are based on the refinement paradigm with the programming capabilities of the composition paradigm.
Instance bases are also databases that are object-oriented. • They are, however, quite different from OODBs. • An OODB is a set of classes, i.e., a set of object sets, and based on the refinement paradigm of the object-oriented programming. • An instance base, on the other hand, is based on the composition paradigm of the object-oriented programming, and stores various composite objects. • The composition paradigm, together with the gradually widening exploitation of the componentware approach to software engineering, is rapidly increasing the importance of instance bases. • Instance bases in this sense, however, are not well developed nor even well studied yet with respect to their storage schemes and their search algorithms.
Management of Pads • What to store in the databases? • The storage of a composite pad only needs to store its exchange format representation; no other information needs to be stored in databases. • The exchange format representation of a composite pad includes two kinds of information. • One is the form information that describes what kinds and sizes of component pads are used, how they are geometrically pasted, and which slot is used in each connection between component pads. • The other is the state information of this pad. The state information needs to be sufficient to specify the current values of all of its internal variables whose values are not specified by its form information. • Composite pads with the same form information but with different states are said to share the same form. • Without loss of generality, we can assume that the state information has a record type, i.e., it can be represented as a list of attribute-value pairs for the ordered attribute set that is determined by each form.
Let P be a composite pad, F and S respectively its form and state information. To guarantee mutual convertibility between P and (F, S), we must provide procedures to compute the following three functions: f: PF, s: PS, and g: (F, S)P. • These functions satisfy P=g(f(P), s(P)).
Instead of using the function f, you may use another function f’ that maps the exchange format representation r(P) of P to the form information of P, i.e., f’(r(P))=f(P). • Furthermore, the function g can be replaced with a new function g’ defined as xy. r(g(f’(x), y)). • For any composite pad P’ sharing the same form with the pad P, it holds that g’(r(P’), s(P))=r(g(f(P), s(P))). • The function r and its inverse are both provided by the IntelligentPad kernel. • The function s can be also replaced with a new function s’ defined as s’(r(x))=s(x). • Instead of providing procedures to compute f, s, g, we can provide procedures for f’, s’, and g’.
Now we may consider two alternative ways of storing pads. • If we have to manage a large number of pads of a few different forms, we can keep the form information outside the databases; we only need to store the state information of pads in the databases. • Such a database is called a form base. • If the state information of a record type has only atomic and simple values for its attributes, we can use a relational database system to store these pads. • If some attributes allow variable length data, continuous data such as movies and sounds, or complex data such as compound documents and other relations, we can use an extended relational database system or a structural OODB system. • In this case, we can even deal with a composite pad storing other composite pads in some of its state attributes.
If we have to manage composite pads of a large number of different forms, we need database facilities not only to manage the states of pads but also to manage their different forms. • In such cases, there is no reason to separately manage the state and the form of each pad. • Such a database is termed a pad base. • Pad bases should be instance bases by their nature. • Because of the premature R&D of instance bases, pad bases require lots of pioneering studies and development efforts.
Behavioral OODBs, namely DBPL databases, have no direct relations with the management of pads. • IntelligentPad is such a system that tries to keep its users as far away as possible from writing programs by themselves. • It provides users with direct operations to compose new objects from existing ones. • Therefore, it is inherently a different approach from DBPL databases.
Database proxy pads • Any relational or object-oriented database system , when provided with its proxy pad DBPoxyPad(), can be easily integrated with other tools in the IntelligentPad environment. • Its proxy pad looks like a blank-sheet pad, and provides a list of slots including #query slot, #result slot, #currentRecord slot, #search slot, #insert slot, #delete slot, #nextCandidate slot, and #previousCandidate slot.
The slot #query receives an SQL or an object-oriented SQL query. • When the proxy pad receives ‘true’ in its #search slot, it sends the SQL query stored in #query slot to the database system to perform this search. • When a search result is sent back from the database, the proxy pad stores this list of records in its #result slot. • At the same time, it makes its internal variable ‘cursor’ point to the first record in the record list, and stores this record in #currentRecord slot. • When the proxy pad receives ‘true’ in its #nextCandidate slot or in its #previousCandidate slot, it respectively changes its variable ‘cursor’ to point to the next or to the previous record, and replaces the record in #currentRecord slot with this new record.
Form bases with a single form • Let us first consider a simple case where all pads share the same single form. • The database only stores their state information as records of a relation. • Database function can be brought into this environment by a database proxy pad DBProxyPad. • For the time being, let us assume that queries are textually specified. • Each retrieved record corresponds to a composite pad with this specified form. • To convert each record to the corresponding pad and vice versa, we need a special pad. We call this a PadGeneratorPad. • This conversion also requires the form information. We assume that, instead of this form information, this PadGeneratorPad is given an example composite pad of this form.
This PadGeneratorPad performs two conversions. • It can apply the function g’ to the given two inputs to obtain the exchange format representation of the corresponding composite pad. • The two inputs are • the exchange format representation of an example pad of this form, and • a record retrieved from the database. • It can also apply the function s’ to the exchange format representation of any composite pad of this form to obtain its state information that is stored in the database as its record.
The PadGeneratorPad has the following two slots, #padSlot and #padGeneratorSlot. • The slot #padSlot is used to input the exchange format representation of an example pad of this form. • This slot is connected to a SaverPad. • To register a form as the database form interface, you can just drag and drop an example pad of this form on this SaverPad.
When sent an update message from a DBProxyPad, this PadGeneratorPad reads the #currentRecord slot of the DBProxyPad to get the next candidate record as the state information of the next pad to output. • Using this information together with the exchange format representation stored in its #padSlot, the PadGeneratorPad generates the exchange format representation of the next pad to output, and stores this result in its #padGeneratorSlot. • When the generation is completed, the PadGeneratorPad issues an ‘update’ message to a LoaderPad connected to its #padGeneratorSlot. • The LoaderPad, when sent an ‘update’ message, deletes pads on itself if any, reads the #padGeneratorSlot of the PadGeneratorPad to obtain an exchange format representation, and generates the corresponding composite pad on itself.
When we click the button pad connected to the #nextCandidate slot of the DBProxyPad, a new record is set to the #currentRecord slot of the DBProxyPad, which then sends an ‘update’ message to the PadGeneratorPad to generate the next pad and to replace the previous pad with this new one.
Form bases with multiple forms • When we need to deal with multiple forms, we can extend the architecture discussed in the preceding section as follows. • First, we need a new pad to store the exchange format representations of multiple pads. We call this a PadListPad. • This pad has several slots including #padSlot, #indexSlot, #insertSlot, and #deleteSlot. It stores an ordered list of pads with index numbers. • A SaverLoaderPad is pasted on the PadListPad with its connection to the #padSlot. • Two ButtonPads are respectively connected to the #insertSlot and the #deleteSlot. • The #indexSlot holds the current index number.
If we drop a pad on the SaverLoaderPad, its exchange format representation is sent to the #padSlot of the PadListPad. • If we click the insert button, i.e., the ButtonPad connected to the #insertSlot, at this time, the exchange format representation of this new pad is inserted at the current index position in the stored list of pads. • When an index number is given through its #indexSlot or as a return value of its ‘gimme’ message sent to its parent pad, the PadListPad outputs the exchange format representation of the corresponding pad in the stored list to its parent pad by sending a ‘set’ message with this pad as the parameter value.
We paste this PadListPad on an extended PadGeneratorPad with its connection to the #padSlot. • An extended PadGeneratorPad has the same slots as the original. • It also reads a record from its parent pad. • Each record however is assumed to have an additional attribute whose value works as a form selector number. • The construction of such an output record format needs to be specified by each query.
The extended PadGeneratorPad reads such a record from the #currentRecord slot of the DBProxyPad, divides it to a form selector number and a pure record, and sends an ‘update’ message to the pad connected to its #padSlot. • The PadListPad, when it receives this ‘update’ message, sends a ‘gimme’ message to get the form selector number from the extended PadGeneratorPad, selects the corresponding exchange format representation, and sends this back to the extended PadGeneratorPad. • The remaining operations of the extended PadGeneratorPad are the same as the original ones. • Furthermore, we do not have to provide both versions of the PadGeneratorPad. • The extended version can replace the original one with some minor considerations.
Form interface to databases • The most typical form bases are those with a single form that works as a form interface to some relational database. • A database proxy pad DBProxyPad performs all the details necessary to access a database. • The whole set of pads available in IntelligentPad works as a form construction kit for the visual interface of this database. • A RecordPad is a blank-sheet pad. When it receives an ‘update’ message, it reads out a record-type value, i.e., an association list, from its parent pad and holds this record. Some versions of IntelligentPad call a RecordPad a DictionaryPad. • A RecordPad allows us to add an arbitrary number of special slots called attribute slots. For this function, it has a special slot #addSlot. When it is accessed by a ‘set’ message with a new slot name as its parameter, the ‘set’ procedure of this slot adds a new slot with this name to the list of attribute slots in this RecordPad.
A RecordPad has another special slot #removeSlot that is used to remove a specified slot from its list of attribute slots. • Each attribute slot, when requested to send back its value, reads out the stored record and gets the value of the attribute having the same name as this attribute-slot name. If the record does not have the same attribute name, this attribute slot returns the value ‘nil’. • When a record pad is pasted on the DBProxyPad with its connection to the #currentRecord slot of this proxy pad, it works as a base pad to define a form representation of each record that will be retrieved from the DBProxyPad.
Different from GUI forms, this form with a RecordPad as its base pad can be easily copied and sent to other users or to some tool pads. This copy holds the record that its original had when we made this copy. • In its typical use on a DBProxyPad, a RecordPad divides each retrieved record into a set of attribute-value pairs. Each attribute value is set to the slot with the same name as its attribute name. Depending on the value type of each attribute slot, you may connect a text viewer pad, an image viewer pad, a drawing viewer pad, or a video viewer pad to this slot.
You may arbitrarily design the layout of these viewer pads on the RecordPad. A DBProxyPad with a RecordPad pasted with some viewer pads is called a form-based DB viewer, or a form interface to a database. • Instead of pasting a RecordPad on a DBProxyPad, you may paste some type of relation viewer pads and connect it to the #result slot of the DBProxyPad. A relation viewer pad visually presents records in the relation. A table representation pad is an example of relation viewer pads.
For the setting of a query in the #query slot of a DBProxyPad, you can simply use a text-input pad TextInputPad. • Instead of using such a simple TextInputPad, you may use any composite pad to generate an SQL query. For example, you may consider a pad Q(#department, #comparator, #salary) that generates a parameterized SQL query Q(x,, y): select name, age, photo from Employee where department = x and salary y.
You may paste three TextInputPads on this pad with their connection to these three slots, and paste this composite pad on the proxy pad to connect itself to the #query slot of the proxy, i.e., DB ProxyPad() [#query: Q[#department: TextPad1, #comparator: TextPad2, #salary: TextPad3)]]. • This allows you to simply specify a department name, a comparison operator, and an amount of salary for the retrieval of employees' information.
A restriction on the DB proxy pad makes it represent a view relation. This requires one more slot named #view slot. This slot is used to store a view definition. • When a query is issued through the #query slot, this pad modifies this query with the view definition and sends the modified query to the database system. To avoid the view update problem, the translation of an update request on this view to a DB update request should be clearly defined in this pad.
Such a restricted DB proxy pad is called a DBViewPad. A text pad can be used to input a view definition sentence viewDefinition to the #view slot, i.e., DBViewPad()[#viewviewDefinition]. • This Pad works as a proxy pad to a database view with the view relation as its only one relation, i.e., DBViewPad()[#viewviewDefinition] = DBProxyPad(view).
QBE on form interface • In the preceding sections, we have been assuming that the #currentRecord slot of a DBProxyPad is a data slot. Actually, it is not. • Its access by a ‘gimme’ message invokes its ‘gimme’ procedure, which reads out the record pointed to by the cursor from the record list stored in the #result slot, and returns this record value. • Its access by a ‘set’ message, on the other hand, sets its parameter value to a special internal variable ‘input-record’ of the DBProxyPad. The record stored in this input-record variable is used to insert and delete records to and from the database.
These operations are successfully performed only when the following two conditions are satisfied; • (1) this record type is a projection of some relation R in the database, and • (2) this record completely specifies the value of the primary key of R. • When its #insert slot is set to ‘true’, a DBProxyPad tries to insert the record in the input-record variable into the database. • When its #delete slot is set to ‘true’, the DBProxyPad tries to delete the record of R identified by the record in the input-record variable.
The input-record variable is also used in search operations. In this case, each attribute value of the record in the input-record variable needs to be either ‘nil’ or a pair comprised of a comparison operator i and any value vi of this attribute. • The content of the input-record variable, in this case, specifies a condition C* defined as the conjunction of Ai.i.vi for all the attributes with non nil values. • Suppose that the query q stored in the #query slot of the DBProxyPad is q: select attribute list from relation list where C.
We define a new query q(C*) as q(C*): select attribute list from relation list where C and C*. • When its #search slot is set to ‘true’, the DBProxyPad reads out both the query q in its #query slot and the condition C* from its input-record variable, generates a new query q(C*), and sends this to the database to retrieve the result relation.
The input-record variable is initially set to a record with ‘nil’ for each of its attributes. • The insert and delete operations both reset the input-record variable to its initial value when they complete their execution. • The condition C* corresponding to this initial value is defined to be logically true.
This extension of the DBProxyPad allows us to construct a QBE(Query-By-Example) type form interface without making any more changes to the preceding discussion. • We use a RecordPad not only for the output display of the retrieved records but also for the QBE type specification of a query. • A RecordPad has a special slot called the #setRecord slot. When set to ‘true’, the ‘set’ procedure of this slot sends a ‘set’ message to its parent pad together with its #record slot value as the message parameter.
When connected to the #currentRecord slot of a DBProxyPad, a RecordPad with a ButtonPad connected to its #setRecord slot works as a QBE based input form. • When its button is clicked, it sends its record value, that actually specifies a query based on the QBE convention, to the input-record variable of the DBProxyPad, which, in turn, generates a modified query q(C*) from the query q specified by its #query slot.