<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Bookcold&#039;s Blog &#187; ORM</title>
	<atom:link href="http://bookcold.com/tag/orm/feed" rel="self" type="application/rss+xml" />
	<link>http://bookcold.com</link>
	<description>Just for pleasure</description>
	<lastBuildDate>Sun, 29 Aug 2010 06:39:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Mapping Objects to Relational Databases: O/R Mapping In Detail   By Scott W. Ambler</title>
		<link>http://bookcold.com/2009/11/99</link>
		<comments>http://bookcold.com/2009/11/99#comments</comments>
		<pubDate>Fri, 20 Nov 2009 13:25:32 +0000</pubDate>
		<dc:creator>bookcold</dc:creator>
				<category><![CDATA[程序设计]]></category>
		<category><![CDATA[ORM]]></category>

		<guid isPermaLink="false">http://bookcold.com/?p=99</guid>
		<description><![CDATA[ Most modern business application development projects use object technology such as Java or C# to build the applation software and relational databases to store the data.  This isn’t to say that you don’t have other options, there are many applications built with procedural languages such as COBOL and many systems will use object [...]]]></description>
			<content:encoded><![CDATA[<table border="0" width="100%">
<tbody>
<tr>
<td>Most modern business application development projects use object technology such as Java or C# to build the applation software and 		<a href="http://www.agiledata.org/essays/relationalDatabases.html">relational databases</a> to store the data.  This isn’t to say that you don’t have other options, there are many applications built with procedural languages such as COBOL and many systems will use object databases or XML databases to store data.  However, because object and relational technologies are by far the norm that’s what I assume you’re working with in this article.  If you’re working with different storage technologies then many of the  concepts are still applicable, albeit with modification (don’t worry,  <a href="http://www.agiledata.org/essays/advancedXML.html">Realistic XML</a> overviews mapping issues pertaining to objects and XML).</td>
<td width="4"><script type="text/javascript"></script> <script type="text/javascript">// <![CDATA[
   google_protectAndRun("ads_core.google_render_ad", google_handleError, google_render_ad);
// ]]&gt;</script></p>
<p align="left">
</td>
</tr>
</tbody>
</table>
<p>Unfortunately we need to deal with the <a href="http://www.agiledata.org/essays/impedanceMismatch.html">object  relational (O/R) impedance mismatch</a>, and to do so you need to understand two things: the process of mapping objects to relational databases and how to implement those mappings.  in this article the term “mapping” will be used to refer to how objects and their relationships are mapped to the tables and relationships between them in a database.  As you’ll soon find out it isn’t quite as straightforward as it sounds although it isn’t too bad either.<br />
<span id="more-99"></span></p>
<h3>Table of Contents</h3>
<ol>
<li>Basic mapping concepts
<ul>
<li>Shadow information</li>
<li>Mapping meta data</li>
<li>How mapping fits into the overall process</li>
</ul>
</li>
<li>Mapping inheritance structures
<ul>
<li>Map hierarchy to a single table</li>
<li>Map each concrete class to its own table</li>
<li>Map each class to its own table</li>
<li>Map classes to a generic table structure</li>
<li>Mapping multiple inheritance</li>
<li>Comparing the strategies</li>
</ul>
</li>
<li>Mapping object relationships
<ul>
<li>Types of relationships</li>
<li>How object relationships are         implemented</li>
<li>How RDB relationships are         implemented</li>
<li>Relationship mappings
<ul>
<li>One-to-one relationships</li>
<li>One-to-many relationships</li>
<li>Many-to-many relationships</li>
</ul>
</li>
<li>Mapping ordered collections</li>
<li>Mapping recursive         relationships</li>
</ul>
</li>
<li>Mapping class-scope properties</li>
<li>Performance tuning
<ul>
<li>Tuning your mappings</li>
<li>Lazy reads</li>
</ul>
</li>
<li>Implementation impact on your objects</li>
<li>Implications for Model Driven Architecture (MDA)</li>
<li>Patternizing what you have learned</li>
</ol>
<h3><a>1. Basic Concepts</a></h3>
<p><a>When learning how to map objects to relational databases the place to start is with the data attributes of a class.  An attribute will map to zero or more columns in a relational database.  Remember, not all attributes are persistent, some are used for temporary calculations.  For example, a <em>Student</em> object may have an <em>averageMark</em> attribute that is needed within your application but isn’t saved to the database because it is calculated by the application.  Because some attributes of an objects are objects in their own right, a <em>Customer</em> object has an <em>Address</em> object as an attribute – this really reflects an association between the two classes that would likely need to be mapped, and the attributes of the <em>Address</em> class itself will need to be mapped.  The important thing is that this is a recursive definition: At some point the attribute will be mapped to zero or more columns.</a></p>
<p><a>The easiest mapping you will ever have is a property mapping of a single attribute to a single column.  It is even simpler when the each have the same basic types, e.g. they’re both dates, the attribute is a string and the column is a char, or the attribute is a number and the column is a float.</a></p>
<table border="1" width="100%">
<tbody>
<tr>
<td width="100%" bgcolor="#c0c0c0">
<h3>Mapping Terminology</h3>
<p><strong>Mapping (v)</strong>.        The act of determining how objects and their relationships are       persisted in permanent data storage, in this case relational databases.</p>
<p><strong>Mapping (n)</strong>. The definition of how an       object’s property or a relationship is persisted in permanent storage.</p>
<p><strong>Property</strong>.        A data attribute, either implemented as a physical attribute such       as the string <em>firstName</em> or as a virtual attribute implemented via       an operation such as <em>getTotal()</em> which returns the total of an       order.</p>
<p><strong>Property mapping</strong>.        A mapping that describes how to persist an object’s property.</p>
<p><strong>Relationship mapping</strong>.        A mapping that describes how to persist a relationship       (association, aggregation, or composition) between two or more objects.</td>
</tr>
</tbody>
</table>
<p><a>It can make it easier to think that classes map to tables, and in a way they do, but not always directly.   Except for very simple databases you will never have a one-to-one mapping of classes to tables, something you will see later in this article with regards to </a><a href="http://www.agiledata.org/essays/mappingObjects.html#MappingInheritance">inheritance mapping</a>.  However, a common theme that you will see throughout this article is that a one class to one table mapping is preferable for your initial mapping (<a href="http://www.agiledata.org/essays/mappingObjects.html#PerformanceTuning">performance tuning</a> may motivate you to refactor your mappings).</p>
<p>For now, let’s keep things simple.  <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure1SimpleMappingExample">Figure 1</a> depicts two models, a UML class diagram and a physical data model which follows the <a href="http://www.agiledata.org/essays/umlDataModelingProfile.html">UML data modeling profile</a>.  Both diagrams depict a portion of a simple schema for an order system.  You can see how the attributes of the classes could be mapped to the columns of the database.  For example, it appears that the <em>dateFulfilled</em> attribute of the <em>Order</em> class maps to the <em>DataFulfilled</em> column of the <em>Order</em> table and that the <em>numberOrdered</em> attribute of the <em>OrderItem</em> class maps to the <em>NumberOrdered</em> column of the <em>OrderItem</em> table.</p>
<p><strong>Figure 1. Simple mapping example.</strong></p>
<p align="center">
<p>Note that these initial property mappings were easy to determine for several reasons.  First, similar naming standards were used in both models, an aspect of <a href="http://www.agiledata.org/essays/agileModeling.html">Agile Modeling (AM)’s</a> <a href="http://www.agilemodeling.com/practices.htm#ApplyModelingStandards">Apply Modeling Standards practice</a>.  Second, it is very likely that the same people created both models.  When people work in separate teams it is quite common for their solutions to vary, even when the teams do a very good job, because they make different design decisions along the way.  Third, one model very likely drove the development of the other model.  In <a href="http://www.agiledata.org/essays/differentStrategies.html">Different Projects Require Different Strategies</a> I argued that when you are building a new system that your  <a href="http://www.agiledata.org/essays/drivingForces.html">object schema should drive the development of your database schema</a>.</p>
<p>The easiest mapping you will ever have is a property mapping of a single attribute to a single column.  It is even simpler when the each have the same basic types, e.g. they’re both dates, the attribute is a string and the column is a char, or the attribute is a number and the column is a float.</p>
<p>Even though the two schemas depicted in  <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure1SimpleMappingExample">Figure 1</a> are very similar there are differences.  These differences mean that the mapping isn’t going to be perfect.  The differences between the two schemas are:</p>
<ul>
<li>There are several attributes for tax in the object     schema yet only one in the data schema.      The three attributes for tax in the <em>Order</em> class presumably     should be added up and stored in the <em>tax</em> column of the <em>Order</em> table when the object is saved.  When     the object is read into memory, however, the three attributes would need to     be calculated (or a lazy initialization approach would need to be taken and     each attribute would be calculated when it is first accessed).      A schema difference such as this is a good indication that the     database schema needs to be refactored to split the tax column into three.</li>
<li>The data schema indicates  	<a href="http://www.agiledata.org/essays/keys.html">keys</a> whereas the object     schema does not.  Rows in tables     are uniquely identified by  	<a href="http://www.agiledata.org/essays/keys.html">primary keys</a> and relationships between rows are     maintained through the use of foreign keys.      Relationships to objects, on the other hand, are implemented via     references to those objects not through foreign keys.  The implication is that in order to fully persist the objects     and their relationships that the objects need to know about the key values     used in the database to identify them.      This additional information is called “<a href="http://www.agiledata.org/essays/mappingObjects.html#ShadowData">shadow     information</a>”.</li>
<li>Different types are used in each schema. The <em>subTotalBeforeTax</em> attribute of <em>Order</em> is of the type <em>Currency</em> whereas the <em>SubTotalBeforeTax</em> column of the <em>Order</em> table is a float.      When you implement this mapping you will need to be able to convert     back and forth between these two representations without loss of     information.</li>
</ul>
<h3>1.1 Shadow Information</h3>
<p>Shadow information is any data that objects need to maintain, above and beyond their normal domain data, to persist themselves.  This typically includes primary key information, particularly when the primary key is a surrogate key that has no business meaning, <a href="http://www.agiledata.org/essays/concurrencyControl.html">concurrency control</a> markings such as timestamps or incremental counters, and versioning numbers.  For example, in  <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure1SimpleMappingExample">Figure 1</a> you see that the <em>Order</em> table has an <em>OrderID</em> column used as a primary key and a <em>LastUpdate</em> column that is used for optimistic concurrency control that the <em>Order</em> class does not have.  To persist an order object properly the Order class would need to implement shadow attributes that maintain these values.</p>
<p><a href="http://www.agiledata.org/essays/mappingObjects.html#Figure2IncludingShadowInformation">Figure 2</a> shows a detailed design class model for the <em>Order</em> and <em>OrderItem</em> classes.  There are several changes from <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure1SimpleMappingExample">Figure 1</a>.  First, the new diagram shows the shadow attributes that the classes require to properly persist themselves.  Shadow attributes have an implementation visibility, there is a space in front of the name instead of a minus sign, and are assigned the stereotype &lt;&lt;persistence&gt;&gt; (this is not a UML standard).  Second, it shows the scaffolding attributes required to implement the relationship the two classes.  Scaffolding attributes, such as the <em>orderItems</em> vector in <em>Order</em>, also have an implementation visibility.  Third, a <em>getTotalTax()</em> operation was added to the <em>Order</em> class to calculate the value required for the <em>tax</em> column of the <em>Order</em> table.  This is why I use the term property mapping instead of attribute mapping – what you really want to do is map the properties of a class, which sometimes are implemented as simple attributes and other times as one or more operations, to the columns of a database.</p>
<p><strong>Figure 2. Including &#8220;shadow information&#8221; on a class diagram.</strong></p>
<p align="center">
<p>One type of shadow information that I have not discussed yet is a boolean flag to indicate whether an object currently exists in the database.  The problem is that when you save data to a relational database you need to use a SQL update statement if the object was previously retrieved from the database and a SQL insert statement if the data does not already exist.  A common practice is for each class to implement an <em>isPersistent</em> boolean flag, not shown in <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure2IncludingShadowInformation">Figure 2</a>, that is set to true when the data is read in from the database and set to false when the object is newly created.</p>
<p>It is a common <a href="http://www.modelingstyle.info/classDiagram.html">style convention</a> in the UML community to not show shadow information, such as keys and concurrency markings, on class diagrams.  Similarly, the common convention is to not model scaffolding code either. The idea is that everyone knows you need to do this sort of thing, so why waste your time modeling the obvious?</p>
<p>Shadow information doesn’t necessarily need to be implemented by the business objects, although your application will need to take care of it somehow.  For example, with  <a href="http://www.ambysoft.com/books/masteringEJB.html">Enterprise JavaBeans (EJBs)</a> you store primary key information outside of EJBs in primary key classes, the individual object references a corresponding primary key object.  The Java Data Object (JDO) approach goes one step further and implement shadow information in the JDOs and not the business objects.</p>
<h3>1.2 Mapping Meta Data</h3>
<p><a href="http://www.agiledata.org/essays/mappingObjects.html#Figure3MetaData">Figure 3</a> depicts the meta data representing the property mappings required to persist the <em>Order</em> and <em>OrderItem</em> classes of <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure2IncludingShadowInformation">Figure 2</a>.  Meta data is information about data.  <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure3MetaData">Figure 3</a> is important for several reasons.  First, we need some way to represent mappings.  We could put two schemas side by side, as you see in  <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure1SimpleMappingExample">Figure 1</a>, and then draw lines between them but that gets complicated very quickly.  Another option is a tabular representation that you see in  <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure3MetaData">Figure 3</a>.  Second, the concept of mapping meta data is critical to the functioning of <a href="http://www.agiledata.org/essays/implementationStrategies.html#StrategyPersistenceFrameworks">persistence frameworks</a> which are a <a href="http://www.agiledata.org/essays/implementationStrategies.html">database encapsulation strategy</a> that can enable agile database techniques.</p>
<p><strong>Figure 3. Meta data representing the property maps.</strong></p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="338" valign="top"><strong>Property </strong></td>
<td width="360" valign="top"><strong>Column </strong></td>
</tr>
<tr>
<td width="338" valign="top">Order.orderID</td>
<td width="360" valign="top">Order.OrderID</td>
</tr>
<tr>
<td width="338" valign="top">Order.dateOrdered</td>
<td width="360" valign="top">Order.DateOrdered</td>
</tr>
<tr>
<td width="338" valign="top">Order.dateFulfilled</td>
<td width="360" valign="top">Order.DateFulfilled</td>
</tr>
<tr>
<td width="338" valign="top">Order.getTotalTax()</td>
<td width="360" valign="top">Order.Tax</td>
</tr>
<tr>
<td width="338" valign="top">Order.subtotalBeforeTax</td>
<td width="360" valign="top">Order.SubtotalBeforeTax</td>
</tr>
<tr>
<td width="338" valign="top">Order.shipTo.personID</td>
<td width="360" valign="top">Order.ShipToContactID</td>
</tr>
<tr>
<td width="338" valign="top">Order.billTo.personID</td>
<td width="360" valign="top">Order.BillToContactID</td>
</tr>
<tr>
<td width="338" valign="top">Order.lastUpdate</td>
<td width="360" valign="top">Order.LastUpdate</td>
</tr>
<tr>
<td width="338" valign="top">OrderItem.ordered</td>
<td width="360" valign="top">OrderItem.OrderID</td>
</tr>
<tr>
<td width="338" valign="top">Order.orderItems.position(orderItem)</td>
<td width="360" valign="top">OrderItem.ItemSequence</td>
</tr>
<tr>
<td width="338" valign="top">OrderItem.item.number</td>
<td width="360" valign="top">OrderItem.ItemNo</td>
</tr>
<tr>
<td width="338" valign="top">OrderItem.numberOrdered</td>
<td width="360" valign="top">OrderItem.NumberOrdered</td>
</tr>
<tr>
<td width="338" valign="top">OrderItem.lastUpdate</td>
<td width="360" valign="top">OrderItem.LastUpdate</td>
</tr>
</tbody>
</table>
<p>The naming convention that I’m using is reasonably straightforward: <em>Order</em>.<em>dateOrdered</em> refers to the <em>dateOrdered</em> attribute of the <em>Order</em> class.  Similarly <em>Order.DateOrdered</em> refers to the <em>DateOrdered</em> column of the <em>Order</em> table.  <em>Order.getTotalTax()</em> refers to the <em>getTotalTax()</em> operation of <em>Order</em> and <em>Order.billTo.personID</em> is the <em>personID</em> attribute of the <em>Person</em> object referenced by the <em>Order.billTo</em> attribute.  Likely the most difficult property to understand is <em>Order.orderItems.position(orderItem)</em> which refers to the position within the <em>Order.orderItems</em> vector of the instance of <em>OrderItem</em> that is being saved.</p>
<p><a href="http://www.agiledata.org/essays/mappingObjects.html#Figure3MetaData">Figure 3</a> hints at an important part  of the O/R <a href="http://www.agiledata.org/essays/impedanceMismatch.html">impedance mismatch</a> between object technology and relational technology.  Classes implement both behavior and data whereas relational database tables just implement data.  The end result is that when you’re mapping the properties of classes into a relational database you end up mapping operations such as <em>getTotalTax()</em> and <em>position()</em> to columns.  Although it didn’t happen in this example, you often need to map two operations that represent a single property to a column – one operation to set the value, e.g. <em>setFirstName()</em>, and one operation to retrieve the value, e.g. <em>getFirstName()</em>.  These operations are typically called setters and getters respectively, or sometimes mutators and accessors.</p>
<p>Whenever a key column is mapped to a property of a class, such as the mapping between <em>OrderItem.ItemSequence</em> and <em>Order.orderItems.position(orderItem)</em>, this is really part of the effort of relationship mapping, discussed later in  this article.  This is because keys implement relationships in relational databases.</p>
<h3>1.3 How Mapping Fits Into The Overall Process</h3>
<p>See the essay <a href="http://www.agiledata.org/essays/evolutionaryDevelopment.html">Evolutionary Development</a>.</p>
<h3>2. Mapping Inheritance Structures</h3>
<p>Relational databases do not natively support inheritance, forcing you to map the inheritance structures within your object schema to your data schema.  Although there is  somewhat of a backlash against inheritance within the object community, due in  most part to the fragile base class problem, my experience is that this problem  is mostly due to poor encapsulation practices among object developers than with  the concept of inheritance.  What I’m saying is that the fact you need to do a little bit of work to map an inheritance hierarchy into a relational database shouldn’t dissuade you from using inheritance where appropriate.</p>
<p>The concept of inheritance throws in several interesting twists when saving objects into a relational DB.  How do you organize the inherited attributes within your data model?  In this section you’ll see that there are three primary solutions for mapping inheritance into a relational database, and a fourth supplementary technique that goes beyond inheritance mapping.  These techniques are:</p>
<ul>
<li><a href="http://www.agiledata.org/essays/mappingObjects.html#MapHierarchyToTable">Map the entire class hierarchy to a single table </a></li>
<li><a href="http://www.agiledata.org/essays/mappingObjects.html#MapConcreteClassToTable">Map each concrete class to its own table</a></li>
<li><a href="http://www.agiledata.org/essays/mappingObjects.html#MapEachClassToTable">Map each class to its own table</a></li>
<li><a href="http://www.agiledata.org/essays/mappingObjects.html#MapToGenericStructure">Map the classes into a generic     table structure</a></li>
</ul>
<p>To explore each technique I will discuss how to map the two versions of the class hierarchy presented in <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure4ClassHierarchy"> Figure 4</a>.  The first version depicts three classes – <em>Person</em>, an abstact class, and two concrete classes, <em>Employee</em> and <em>Customer</em>.  You know that <em>Person</em> is abstract because its name is shown in italics.  In older versions of the UML the constraint “{abstract}” would have been used instead.  The second version of the hierarchy adds a fourth concrete class to the hierarchy, <em>Executive</em>.  The idea is that you have implemented the first class hierarchy and are now presented with a new requirement to support giving executives, but not non-executive employees, fixed annual bonuses.  The <em>Executive</em> class was added to support this new functionality.</p>
<p>For the sake of simplicity I have not modeled all of the attributes of the classes, nor have I modeled their full signatures, nor have I modeled any of the operations.  This diagram is just barely good enough for my purpose, in other words it is an agile model.  Furthermore these hierarchies could be approved by applying the  <a href="http://www.amazon.com/exec/obidos/ASIN/0201895420/ambysoftinc">Party analysis pattern</a> or the <a href="http://www.ambysoft.com/books/buildingObjectApplications.html">Business Entity</a> analysis pattern.  I haven’t done this because I need a simple example to explain mapping inheritance hierarchies, not to explain the effective application of analysis patterns – I always follow  <a href="http://www.agiledata.org/essays/agileModeling.html"> AM’s</a> <a href="http://www.agilemodeling.com/principles.htm#ModelWithAPurpose">Model With A Purpose principle</a>.</p>
<p><strong>Figure 4.  Two versions of a simple class hierarchy.</strong></p>
<table border="1" width="100%" bgcolor="#ffffcc">
<tbody>
<tr>
<td width="100%">Inheritance can also be a problem when it’s misapplied       – for example, the hierarchy in <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure4ClassHierarchy">Figure 4</a> could be better modeled via       the Party (<a href="http://www.amazon.com/exec/obidos/ASIN/0932633293/ambysoftinc">Hay       1996</a>,  <a href="http://www.amazon.com/exec/obidos/ASIN/0201895420/ambysoftinc">Fowler       1997</a>) or the Business Entity (<a href="http://www.ambysoft.com/books/buildingObjectApplications.html">Ambler       1997</a>) patterns.  For       example, if someone can be both a customer and an employee you would have       to objects in memory for them, which may be problematic for your       application.  I’ve chosen       this example because I needed a simple, easy to understand class hierarchy       to map.</td>
</tr>
</tbody>
</table>
<h3>2.1 Map Hierarchy To A Single Table</h3>
<p>Following this strategy you store all the attributes of the classes in one table.   <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure5MappingToSingleTable">Figure 5</a> depicts the data model for the class hierarchies of  <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure4ClassHierarchy">Figure 4</a> when this approach is taken.  The attributes of each the classes are stored in the table <em>Person</em>, a good table naming strategy is to use the name of the hierarchy’s root class, in a very straightforward manner.</p>
<p><strong>Figure 5. Mapping to a single table.</strong></p>
<p align="center">
<p>Two columns have been added to the table – <em>PersonPOID</em> and <em>PersonType</em>.  The first column is the primary key for the table, you know this because of the &lt;&lt;PK&gt;&gt; stereotype, and the second is a code indicating whether the person is a customer, an employee, or perhaps both.  <em>PersonPOID</em> is a persistent object identifier (POID), often simply called an object identifier (OID), which is a surrogate key.  I could have used the optional stereotype of &lt;&lt;Surrogate&gt;&gt; to indicate this but chose not to as POID implies this, therefore indicating the stereotype would only serve to complicate the diagram (follow the <a href="http://www.agilemodeling.com/practices.htm#DepictModelsSimply">AM practice Depict Models Simply</a>).   <a href="http://www.agiledata.org/essays/dataModeling101.html">Data Modeling 101</a> discusses <a href="http://www.agiledata.org/essays/dataModeling101.html#AssignKeys">surrogate keys</a> in greater detail.</p>
<p>The <em>PersonType</em> column is required to identify the type of object that can be instantiated from a given row.  For example the value of <em>E</em> would indicate the person is an employee, <em>C</em> would indicate customer, and <em>B</em> would indicate both.  Although this approach is straightforward it tends to break down as the number of types and combinations begin to grow.  For example, when you add the concept of executives you need to add a code value, perhaps <em>X</em>, to represent this.  Now the value of <em>B</em>, representing both, is sort of goofy.  Furthermore you might have combinations involving executives now, for example it seems reasonable that someone can be both an executive and a customer so you’d need a code for this.   When you discover that combinations are possible you should consider applying the <em><a href="http://www.agiledata.org/essays/databaseRefactoringCatalog.html#ReplaceTypeCodeWithBooleans">Replace Type Code With Booleans</a></em> database refactoring, as you see in  <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure6RefactoredSingleTableApproach">Figure 6</a>.</p>
<p>For the sake of simplicity I did not include columns for concurrency control, such as the time stamp column included in the tables of  <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure2IncludingShadowInformation">Figure 2</a>, nor did I include columns for data versioning.</p>
<p><strong>Figure 6. A refactored approach.</strong></p>
<p align="center">
<h3>2.2 Map Each Concrete Class To Its Own Table</h3>
<p>With this approach a table is created for each concrete class, each table including both the attributes implemented by the class and its inherited attributes.   <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure7MappingConcreteToTable">Figure 7</a> depicts the physical data model for the class hierarchy of  <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure4ClassHierarchy">Figure 4</a> when this approach is taken.  There are tables corresponding to each of the <em>Customer</em> and <em>Employee</em> classes because they are concrete, objects are instantiated from them, but not <em>Person</em> because it is abstract.  Each table was assigned its own primary key, <em>customerPOID</em> and <em>employeePOID</em> respectively.  To support the addition of <em>Executive</em> all I needed to do was add a corresponding table with all of the attributes required by executive objects.</p>
<p><strong>Figure 7. Mapping concrete classes to tables.</strong></p>
<p align="center">
<h3>2.3 Map Each Class To Its Own Table</h3>
<p>Following this strategy you create one table per class, with one column per business attributes and any necessary identification information (as well as other columns required for concurrency control and versioning).  <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure8MappingEachToTable">Figure 8</a> depicts the physical data model for the class hierarchy of <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure4ClassHierarchy">Figure 4</a> when each class is mapped to a single table.  The data for the <em>Customer</em> class is stored in two tables, <em>Customer</em> and <em>Person</em>, therefore to retrieve this data you would need to join the two tables (or do two separate reads, one to each table).</p>
<p>The application of keys is interesting.  Notice how <em>personPOID</em> is used as the primary key for all of the tables. For the <em>Customer</em>, <em>Employee</em>, and <em>Executive</em> tables the <em>personPOID</em> is both a primary key and a foreign key.  In the case of <em>Customer</em>, <em>personPOID</em> is its primary key and a foreign key used to maintain the relationship to the <em>Person</em> table.  This is indicated by application of two stereotypes, &lt;&lt;PK&gt;&gt; and &lt;&lt;FK&gt;&gt;.  In older versions of the <a href="http://www.agilemodeling.com/essays/realisticUML.html">UML</a> it wasn’t permissible to assign several stereotypes to a single model element but this restriction was lifted in UML version 1.4.</p>
<p><strong>Figure 8.  Mapping each class to its own table.</strong></p>
<p align="center">
<p>A common modification that you may want to consider is the addition of a type column, or boolean columns as the case may be, in the <em>Person</em> table to indicate the applicable subtypes of the person.  Although this is additional overhead it makes some types of queries easier.  The addition of views is also an option in many cases, an approach that I prefer over the addition of type or boolean columns because they are easier to maintain.</p>
<h3>2.4 Map Classes To A Generic Table Structure</h3>
<p>A fourth option for mapping inheritance structures into a relational database is to take a generic, sometimes called meta-data driven approach, to mapping your classes.  This approach isn’t specific to inheritance structures, it supports all forms of mapping.  In <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure9GenericDataSchema">Figure 9</a> you see a data schema for storing the value of attributes and for traversing inheritance structures.  The schema isn’t complete, it could be extended to map associations for example, but it’s sufficient for our purposes.  The value of a single attribute is stored in the <em>Value</em> table, therefore to store an object with ten business attributes there would be ten records, one for each attribute.  The <em>Value.ObjectPOID</em> column stores the unique identifier for the specific object (this approach assumes a common key strategy across all objects, when this isn’t the case you’ll need to extend this table appropriately).  The <em>AttributeType</em> table contains rows for basic data types such as data, string, money, integer and so on.  This information is required to convert the value of the object attribute into the varchar stored in <em>Value.Value</em>.</p>
<p><strong>Figure 9. A generic data schema for storing objects.</strong></p>
<p align="center">
<p>Let’s work through an example of mapping a single class to this schema.  To store the <em>OrderItem</em> class in <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure2IncludingShadowInformation">Figure 2</a> there would be three records in the <em>Value</em> table.  One to store the value for the number of items ordered, one to store the value of the <em>OrderPOID</em> that this order item is part of, and one to store the value of the <em>ItemPOID</em> that describes the order item.  You may decide to have a fourth row to store the value of the <em>lastUpdated</em> shadow attribute if you’re taking an optimistic locking approach to <a href="http://www.agiledata.org/essays/concurrencyControl.html">concurrency control</a>. The <em>Class</em> table would include a row for the <em>OrderItem</em> class and the <em>Attribute</em> table would include one row for each attribute stored in the database (in this case either 3 or 4 rows).</p>
<p>Now let’s map the inheritance structure between <em>Person</em> and <em>Customer</em>, shown in <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure4ClassHierarchy">Figure 4</a>, into this schema.  The <em>Inheritance</em> table is the key to inheritance mapping.  Each class would be represented by a row in the <em>Class</em> table.  There would also be a row in the <em>Inheritance</em> table, the value of <em>Inheritance.SuperClassPOID</em> would refer to the row in <em>Class</em> representing <em>Person</em> and <em>Inheritance.SubClassPOID</em> would refer to the row in <em>Class</em> representing <em>Customer</em>. To map the rest of the hierarchy you require one row in <em>Inheritance</em> for each inheritance relationship.</p>
<h3>2.5 Mapping Multiple Inheritance</h3>
<p>Until this point I have focused on mapping single inheritance hierarchies, single inheritance occurs when a subclass such as <em>Customer</em> inherits directly from a single parent class such as <em>Person</em>.  Multiple inheritance occurs when a subclass has two or more direct superclasses, such as <em>Dragon</em> directly inheriting from both <em>Bird</em> and <em>Lizard</em> in <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure10MappingMultipleInheritance">Figure 10</a>.  Multiple inheritance is generally seen as a questionable feature of an object-oriented language, since 1990 I have only seen one domain problem where multiple inheritance made sense, and as a result most languages choose not to support it.  However, languages such as C++ and Eiffel do support it so you may find yourself in a situation where you need to map a multiple inheritance hierarchy to a relational database.</p>
<p><a href="http://www.agiledata.org/essays/mappingObjects.html#Figure10MappingMultipleInheritance">Figure 10</a> shows the three data schemas that would result from applying each of the three inheritance mapping strategies.  As you can see mapping multiple inheritance is fairly straightforward, there aren’t any surprises in <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure10MappingMultipleInheritance">Figure 10</a>.  The greatest challenge in my experience is to identify a reasonable table name when mapping the hierarchy into a single table, in this case <em>Creature</em> made the most sense.</p>
<p><strong>Figure 10. Mapping multiple inheritance.</strong></p>
<p align="center">
<h3>2.6 Comparing The Strategies</h3>
<p>None of these mapping strategies are ideal for all situations, as you can see in <a href="http://www.agiledata.org/essays/mappingObjects.html#Table1ComparingInheritanceMapping">Table 1</a>.  My experience is that the easiest strategy to work with is to have one table per hierarchy at first, then if you need to refactor your schema according.  Sometimes I’ll start by applying the one table per class strategy whenever my team is motivated to work with a “pure design approach”.  I stay away from using one table per concrete class because it typically results in the need to copy data back and forth between tables, forcing me to refactor it reasonably early in the life of the project anyway. I rarely use the generic schema approach because it simply doesn’t scale very well.</p>
<p>It is important to understand that you can combine the first three strategies – one table per hierarchy, one table per concrete class, and one table per class – in any given application.  You can even combine these strategies in a single, large hierarchy.</p>
<p><strong>Table 1. Comparing the inheritance mapping strategies.</strong></p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="129" valign="top"><strong>Strategy </strong></td>
<td width="248" valign="top"><strong>Advantages </strong></td>
<td width="267" valign="top"><strong>Disadvantages </strong></td>
<td width="215" valign="top"><strong>When to Use </strong></td>
</tr>
<tr>
<td width="129" valign="top"><a href="http://www.agiledata.org/essays/mappingObjects.html#MapHierarchyToTable">One table per       hierarchy</a></td>
<td width="248" valign="top">Simple approach.</p>
<p>Easy to add new classes, you just need to add new       columns for the additional data.</p>
<p>Supports polymorphism by simply changing the type of       the row.</p>
<p>Data access is fast because the data is in one table.</p>
<p>Ad-hoc  <a href="http://www.agiledata.org/essays/reporting.html">reporting</a> is very easy because all of the data is found in one table.</td>
<td width="267" valign="top">Coupling within the class hierarchy is increased       because all classes are directly coupled to the same table.  A change in one class can affect the table which can then       affect the other classes in the hierarchy.</p>
<p>Space potentially wasted in the database.</p>
<p>Indicating the type becomes complex when significant       overlap between types exists.</p>
<p>Table can grow quickly for large hierarchies.</td>
<td width="215" valign="top">This is a good strategy for simple and/or shallow       class hierarchies where there is little or no overlap between the types       within the hierarchy.</td>
</tr>
<tr>
<td width="129" valign="top"><a href="http://www.agiledata.org/essays/mappingObjects.html#MapEachClassToTable">One table per concrete       class</a></td>
<td width="248" valign="top">Easy to do ad-hoc  <a href="http://www.agiledata.org/essays/reporting.html">reporting</a> as all the data you need about a single class is stored in only one table.</p>
<p>Good performance to access a single object’s data.</td>
<td width="267" valign="top">When you modify a class you need to modify its table       and the table of any of its subclasses.        For example if you were to add height and weight to the <em>Person</em> class you would need to add columns to the <em>Customer</em>, <em>Employee</em>,       and <em>Executive</em> tables.</p>
<p>Whenever an object changes its role, perhaps you hire       one of your customers, you need to copy the data into the appropriate       table and assign it a new POID value (or perhaps you could reuse the       existing POID value).</p>
<p>It is difficult to support multiple roles and still       maintain data integrity.  For       example, where would you store the name of someone who is both a customer       and an employee?</td>
<td width="215" valign="top">When changing types and/or overlap between types is       rare.</td>
</tr>
<tr>
<td width="129" valign="top"><a href="http://www.agiledata.org/essays/mappingObjects.html#MapEachClassToTable">One table per class</a></td>
<td width="248" valign="top">Easy to understand because of the one-to-one mapping.</p>
<p>Supports polymorphism very well as you merely have       records in the appropriate tables for each type.</p>
<p>Very easy to modify superclasses and add new       subclasses as you merely need to modify/add one table.</p>
<p>Data size grows in direct proportion to growth in the       number of objects.</td>
<td width="267" valign="top">There are many tables in the database, one for every       class (plus tables to maintain relationships).</p>
<p>Potentially takes longer to read and write data using       this technique because you need to access multiple tables.        This problem can be alleviated if you organize your database       intelligently by putting each table within a class hierarchy on different       physical disk-drive platters (this assumes that the disk-drive heads all       operate independently).</p>
<p>Ad-hoc  <a href="http://www.agiledata.org/essays/reporting.html">reporting</a> on your database is difficult, unless you add views to simulate the       desired tables.</td>
<td width="215" valign="top">When there is significant overlap between types or       when changing types is common.</td>
</tr>
<tr>
<td width="129" valign="top"><a href="http://www.agiledata.org/essays/mappingObjects.html#MapToGenericStructure">Generic schema</a></td>
<td width="248" valign="top">Works very well when database access is encapsulated       by a robust  <a href="http://www.agiledata.org/essays/implementationStrategies.html#StrategyPersistenceFrameworks">persistence       framework</a>.</p>
<p>It can be extended to provide meta data to support a       wide range of mappings, including relationship mappings.  In short, it is the start at a mapping meta data engine.</p>
<p>It is incredibly flexible, enabling you to quickly       change the way that you store objects because you merely need to update       the meta data stored in the <em>Class</em>, <em>Inheritance</em>, <em>Attribute</em>,       and <em>AttributeType</em> tables accordingly.</td>
<td width="267" valign="top">Very advanced technique that can be difficult to       implement at first.</p>
<p>It only works for small amounts of data because you       need to access many database rows to build a single object.</p>
<p>You will likely want to build a small administration       application to maintain the meta data.</p>
<p><a href="http://www.agiledata.org/essays/reporting.html">Reporting</a> against this data can be very difficult due to the need to access several       rows to obtain the data for a single object.</td>
<td width="215" valign="top">For complex applications that work with small amounts       of data, or for applications where you data access isn’t very common or       you can pre-load data into caches.</td>
</tr>
</tbody>
</table>
<h3>3. Mapping Object Relationships</h3>
<p>In addition to property and inheritance mapping you need to understand the art of relationship mapping.  There are three types of object relationships that you need to map: association, aggregation, and composition.  For now, I’m going to treat these three types of relationship the same – they are mapped the same way although there are interesting nuances when it comes to <a href="http://www.agiledata.org/essays/referentialIntegrity.html">referential integrity</a>.</p>
<h3>3.1 Types of Relationships</h3>
<p>There are two categories of object relationships that you need to be concerned with when mapping.  The first category is based on multiplicity and it includes three types:</p>
<ul>
<li><strong>One-to-one relationships</strong>.  This is a relationship where the maximums of each of its     multiplicities is one, an example of which is <em>holds</em> relationship     between <em>Employee</em> and <em>Position</em> in  	<a href="http://www.agiledata.org/essays/mappingObjects.html#Figure11ObjectRelationships">Figure     11</a>.  An employee holds one and only one position and a position     may be held by one employee (some positions go unfilled).</li>
<li><strong>One-to-many relationships</strong>. Also known as a     many-to-one relationship, this occurs when the maximum of one multiplicity     is one and the other is greater than one.      An example is the <em>works in</em> relationship between <em>Employee</em> and <em>Division</em>.  An     employee works in one division and any given division has one or more     employees working in it.</li>
<li><strong>Many-to-many relationships</strong>. This is a     relationship where the maximum of both multiplicities is greater than one,     an example of which is the <em>assigned</em> relationship between <em>Employee</em> and <em>Task</em>.  An employee is     assigned one or more tasks and each task is assigned to zero or more     employees.</li>
</ul>
<p>The second category is based on directionality and it contains two types, uni-directional relationships and bi-directional relationships.</p>
<ul>
<li><strong>Uni-directional relationships</strong>.      A uni-directional relationship when an object knows about the     object(s) it is related to but the other object(s) do not know of the     original object.  An example of     which is the <em>holds</em> relationship between <em>Employee</em> and <em>Position</em> in <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure11ObjectRelationships">Figure 11</a>, indicated by the     line with an open arrowhead on it.  <em>Employee</em> objects know about the position that they hold, but <em>Position</em> objects     do not know which employee holds it (there was no requirement to do so).      As you will soon see, uni-directional relationships are easier to     implement than bi-directional relationships.</li>
<li><strong>Bi-directional relationships</strong>.      A bi-directional relationship exists when the objects on both end of     the relationship know of each other, an example of which is the <em>works in</em> relationship between <em>Employee</em> and <em>Division</em>.      <em>Employee</em> objects know what division they work in and <em>Division</em> objects know what employees work in them.</li>
</ul>
<p><strong>Figure 11. Relationships between objects.</strong></p>
<p align="center">
<p>It is possible to have all six combinations of relationship in object schemas.  However one aspect of the <a href="http://www.agiledata.org/essays/impedanceMismatch.html">impedance mismatch</a> between object technology and relational technology is that relational technology does not support the concept of uni-directional relationships – in relational databases all associations are bi-directional  (relationships are implemented via foreign keys, which can be joined/traversed  in either direction).</p>
<h3>3.2  How Object Relationships Are Implemented</h3>
<p>Relationships in object schemas are implemented by a combination of references to objects and operations.  When the multiplicity is one (e.g. 0..1 or 1) the relationship is implemented with a reference to an object, a getter operation, and a setter operation.  For example in <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure11ObjectRelationships">Figure 11</a> the fact that an employee works in a single division is implemented by the <em>Employee</em> class via the combination of the attribute <em>division</em>, the <em>getDivision()</em> operation which returns the value of <em>division</em>, and the <em>setDivision()</em> operation which sets the value of the <em>division</em> attribute. The attribute(s) and operations required to implement a relationship are often referred to as scaffolding.</p>
<p>When the multiplicity is many (e.g. N, 0..*, 1..*) the relationship is implemented via a collection attribute, such as an <em>Array</em> or a <em>HashSet</em> in Java, and operations to manipulate that array.  For example the <em>Division</em> class implements a <em>HashSet</em> attribute named <em>employees</em>, <em>getEmployees()</em> to get the value, <em>setEmployees()</em> to set the value, <em>addEmployee()</em> to add an employee into the <em>HashSet</em>, and <em>removeEmployee()</em> to remove an employee from the <em>HashSet</em>.</p>
<p>When a relationship is uni-directional the code is implemented only by the object that knows about the other object(s).  For example, in the uni-directional relationship between <em>Employee</em> and <em>Position</em> only the <em>Employee</em> class implements the association.  Bi-directional associations, on the other hand, are implemented by both classes, as you can see with the many-to-many relationship between <em>Employee</em> and <em>Task</em>.</p>
<h3>3.3 How Relational Database Relationships Are Implemented</h3>
<p>Relationships in relational databases are maintained through the use of foreign keys.  A foreign key is a data attribute(s) that appears in one table that may be part of or is coincidental with the key of another table.  With a one-to-one relationship the foreign key needs to be implemented by one of the tables.  In  <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure12RDBRelationships">Figure 12</a> you see that the <em>Position</em> table includes <em>EmployeePOID</em>, a foreign key to the <em>Employee</em> table, to implement the association.  I could easily have implemented a <em>PositionPOID</em> column in <em>Employee</em> instead.</p>
<p><strong>Figure 12. Relationships in a relational database.</strong></p>
<p align="center">
<p>To implement a one-to-many relationship you implement a foreign key from the “one table” to the “many table”.  For example <em>Employee</em> includes a <em>DivisionPOID</em> column to implement the <em>works in</em> relationship to <em>Division</em>.  You could also choose to overbuild your database schema and implement a one-to-many relationship via an associative table, effectively making it a many-to-many relationship.</p>
<p>There are two ways to implement many-to-many associations in a relational database.  The first one is to implement in each table the foreign key column(s) to the other table several times.  For example to implement the many-to-many relationship between <em>Employee</em> and <em>Task</em> you could have five <em>TaskPOID</em> columns in <em>Employee</em> and the <em>Task</em> table could include seven <em>EmployeePOID</em> columns.  Unfortunately you run into a problem with this approach when you assign more than five tasks to an employee or more than seven employees to a single task.  A better approach is to implement what is called an associative table, an example of which is <em>EmployeeTask</em> in <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure12RDBRelationships">Figure 12</a>, which includes the combination of the primary keys of the tables that it associates.  With this approach you could have fifty people assigned to the same task, or twenty tasks assigned to the same person, and it wouldn’t matter.  The basic &#8220;trick&#8221; is that the many-to-many relationship is converted into two one-to-many relationships, both of which involve the associative table.</p>
<p>Because foreign keys are used to join tables, all relationships in a relational database are effectively bi-directional.  This is why it doesn’t matter in which table you implement a one-to-one relationship, the code to join the two tables is virtually the same.  For example, with the existing schema in <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure12RDBRelationships">Figure 12</a> the SQL code to join across the holds relationship would be</p>
<table border="1" width="53%">
<tbody>
<tr>
<td width="100%">SELECT * FROM Position, Employee</p>
<p>WHERE Position.EmployeePOID = Employee.EmployeePOID</td>
</tr>
</tbody>
</table>
<p>Had the foreign key been implemented in the Employee table the SQL code would be</p>
<table border="1" width="53%">
<tbody>
<tr>
<td width="100%">SELECT * FROM Position, Employee</p>
<p>WHERE Position.PositionPOID = Employee.PositionPOID</td>
</tr>
</tbody>
</table>
<p>A consistent key strategy within your database can greatly simplify your relationship mapping efforts.  The first step is to prefer single-column keys.  The next step is to use a globally unique surrogate key, perhaps following the <a href="http://www.agiledata.org/essays/dataModeling101.html#AssignKeys">GUID or HIGH-LOW</a> strategies, so you are always mapping to the same type of key column.</p>
<p>Now that we understand how to implement relationships in each technology, let’s see how you map them.  I will describe the mappings from the point of view of mapping the object relationships into the relational database.  An interesting thing to remember is that in some cases you have design choices to make.  Once again beware of the “magic CASE tool button” that supposedly automates everything for you.</p>
<h3>3.4 Relationship Mappings</h3>
<p>A general rule of thumb with relationship mapping is that you should keep the multiplicities the same.  Therefore a <a href="http://www.agiledata.org/essays/mappingObjects.html#OneToOneMappings"> one-to-one</a> object relationship maps to a one-to-one data relationship, a <a href="http://www.agiledata.org/essays/mappingObjects.html#OneToManyMappings"> one-to-many</a> maps to a one-to-many, and a <a href="http://www.agiledata.org/essays/mappingObjects.html#ManyToManyMappings"> many-to-many</a> maps to a many-to-many.  The fact is that this doesn’t have to be the case, you can implement a one-to-one object relationship with to a one-to-many or even a many-to-many data relationship.  This is because a one-to-one data relationship is a subset of a one-to-many data relationship and a one-to-many relationship is a subset of a many-to-many relationship.</p>
<p><a href="http://www.agiledata.org/essays/mappingObjects.html#Figure13PropertyMappings">Figure 13</a> depicts the property mappings between the object schema of  <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure11ObjectRelationships">Figure 11</a> and the data schema of <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure12RDBRelationships">Figure 12</a>. Note how I have only had to map the business properties and the shadow information of the objects, but not scaffolding attributes such as <em>Employee.position</em> and <em>Employee.tasks</em>. These scaffolding attributes are represented via the shadow information that is mapped into the database.  When the relationship is read into memory the values of stored in the primary key columns will be stored in the corresponding shadow attributes within the objects.  At the same time the relationship that the primary key columns represent will be defined between the corresponding objects by setting the appropriate values in their scaffolding attributes.</p>
<p><strong>Figure 13. Property mappings.</strong></p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="338" valign="top"><strong>Property </strong></td>
<td width="360" valign="top"><strong>Column </strong></td>
</tr>
<tr>
<td width="338" valign="top">Position.title</td>
<td width="360" valign="top">Position.Title</td>
</tr>
<tr>
<td width="338" valign="top">Position.positionPOID</td>
<td width="360" valign="top">Position.PositionPOID</td>
</tr>
<tr>
<td width="338" valign="top">Employee.name</td>
<td width="360" valign="top">Employee.Name</td>
</tr>
<tr>
<td width="338" valign="top">Employee.employeePOID</td>
<td width="360" valign="top">Employee.EmployeePOID</td>
</tr>
<tr>
<td width="338" valign="top">Employee.employeePOID</td>
<td width="360" valign="top">EmployeeTask.EmployeePOID</td>
</tr>
<tr>
<td width="338" valign="top">Division.name</td>
<td width="360" valign="top">Division.Name</td>
</tr>
<tr>
<td width="338" valign="top">Division.divisionPOID</td>
<td width="360" valign="top">Division.DivisionPOID</td>
</tr>
<tr>
<td width="338" valign="top">Task.description</td>
<td width="360" valign="top">Task.Description</td>
</tr>
<tr>
<td width="338" valign="top">Task.taskPOID</td>
<td width="360" valign="top">Task.TaskPOID</td>
</tr>
<tr>
<td width="338" valign="top">Task.taskPOID</td>
<td width="360" valign="top">EmployeeTask.TaskPOID</td>
</tr>
</tbody>
</table>
<h3>3.4.1 One-To-One Mappings</h3>
<p>Consider the one-to-one object relationship between <em>Employee</em> and <em>Position</em>.  Let’s assume that whenever a <em>Position</em> or an <em>Employee</em> object is read into memory that the application will automatically traverse the <em>holds</em> relationship and automatically read in the corresponding object.  The other option would be to manually traverse the relationship in the code, taking a lazy read approach where the other object is read at the time it is required by the application.  The trade-offs of these two approaches are discussed in <a href="http://www.agiledata.org/essays/referentialIntegrity.html#LazyReads">Implementing Referential Integrity</a>.   <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure14MappingRelationships">Figure 14</a> shows how the object relationships are mapped.</p>
<p><strong>Figure 14. Mapping the relationships.</strong></p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="122" valign="top"><strong>Object Relationship </strong></td>
<td width="113" valign="top"><strong>From </strong></td>
<td width="60" valign="top"><strong>To </strong></td>
<td width="98" valign="top"><strong>Cardinality </strong></td>
<td width="129" valign="top"><strong>Automatic Read </strong></td>
<td width="191" valign="top"><strong>Column(s) </strong></td>
<td width="147" valign="top"><strong>Scaffolding Property </strong></td>
</tr>
<tr>
<td width="122" valign="top">holds</td>
<td width="113" valign="top">Employee</td>
<td width="60" valign="top">Position</td>
<td width="98" valign="top">One</td>
<td width="129" valign="top">Yes</td>
<td width="191" valign="top">Position.EmployeePOID</td>
<td width="147" valign="top">Employee.position</td>
</tr>
<tr>
<td width="122" valign="top">held by</td>
<td width="113" valign="top">Position</td>
<td width="60" valign="top">Employee</td>
<td width="98" valign="top">One</td>
<td width="129" valign="top">Yes</td>
<td width="191" valign="top">Position.EmployeePOID</td>
<td width="147" valign="top">Employee.position</td>
</tr>
<tr>
<td width="122" valign="top">works in</td>
<td width="113" valign="top">Employee</td>
<td width="60" valign="top">Division</td>
<td width="98" valign="top">One</td>
<td width="129" valign="top">Yes</td>
<td width="191" valign="top">Employee.DivisionPOID</td>
<td width="147" valign="top">Employee.division</td>
</tr>
<tr>
<td width="122" valign="top">has working in it</td>
<td width="113" valign="top">Division</td>
<td width="60" valign="top">Employee</td>
<td width="98" valign="top">Many</td>
<td width="129" valign="top">No</td>
<td width="191" valign="top">Employee.DivisionPOID</td>
<td width="147" valign="top">Division.employees</td>
</tr>
<tr>
<td width="122" valign="top">assigned</td>
<td width="113" valign="top">Employee</td>
<td width="60" valign="top">Task</td>
<td width="98" valign="top">Many</td>
<td width="129" valign="top">No</td>
<td width="191" valign="top">Employee.EmployeePOID</p>
<p>EmployeeTask.EmployeePOID</td>
<td width="147" valign="top">Employee.tasks</td>
</tr>
<tr>
<td width="122" valign="top">assigned to</td>
<td width="113" valign="top">Task</td>
<td width="60" valign="top">Employee</td>
<td width="98" valign="top">Many</td>
<td width="129" valign="top">No</td>
<td width="191" valign="top">Task.TaskPOID</p>
<p>EmployeeTask.TaskPOID</td>
<td width="147" valign="top">Task.employees</td>
</tr>
</tbody>
</table>
<p>Let’s work through the logic of retrieving a single <em>Position</em> object one step at a time:</p>
<ol>
<li>The <em>Position</em> object is read into memory.</li>
<li>The <em>holds</em> relationship is automatically     traversed.</li>
<li>The value held by the <em>Position.EmployeePOID</em> column is used to identify the single employee that needs to be read into     memory.</li>
<li>The <em>Employee</em> table is searched for a record with     that value of <em>EmployeePOID</em>.</li>
<li>The <em>Employee</em> object (if any) is read in and     instantiated.</li>
<li>The value of the <em>Employee.position</em> attribute is     set to reference the <em>Position</em> object.</li>
</ol>
<p>Now let’s work through the logic of retrieving a single <em>Employee</em> object one step at a time:</p>
<ol>
<li>The <em>Employee</em> object is read into memory.</li>
<li>The <em>holds</em> relationship is automatically     traversed.</li>
<li>The value held by the <em>Employee.EmployeePOID</em> column is used to identify the single position that needs to be read into     memory.</li>
<li>The <em>Position</em> table is searched for a row with     that value of <em>EmployeePOID</em>.</li>
<li>The <em>Position</em> object is read in and instantiated.</li>
<li>The value of the <em>Employee.position</em> attribute is     set to reference the <em>Position</em> object.</li>
</ol>
<p>Now let’s consider how the objects would be saved to the database.  Because the relationship is to be automatically traversed, and to maintain referential integrity, a <a href="http://www.agiledata.org/essays/referentialIntegrity.html#Transactions">transaction</a> is created.  The next step is to add update statements for each object to the transaction.  Each update statement includes both the business attributes and the key values mapped in <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure13PropertyMappings">Figure 13</a>.  Because relationships are implemented via foreign keys, and because those values are being updated, the relationship is effectively being persisted.  The transaction is submitted to the database and run (see <a href="http://www.agiledata.org/essays/transactionControl.html">Introduction  to Transaction Control</a> for details).</p>
<p>There is one annoyance with the way the holds relationship has been mapped into the database.  Although the direction of this relationship is from <em>Employee</em> to <em>Position</em> within the object schema, it’s been implemented from <em>Position</em> to <em>Employee</em> in the database.  This isn’t a big deal, but it is annoying.  In the data schema you can implement the foreign key in either table and it wouldn’t make a difference, so from a data point of view when everything else is equal you could toss a coin.  Had there been a potential requirement for the holds relationship to turn into a one-to-many relationship, something that a  <a href="http://www.agilemodeling.com/artifacts/changeCase.htm">change case</a> would indicate, then you would be motivated to implement the foreign key to reflect this potential requirement.  For example, the existing data model would support an employee holding many positions.  However, had the object schema been taken into account, and if there were no future requirements motivating you to model it other wise, it would have been cleaner to implement the foreign key in the <em>Employee</em> table instead.</p>
<h3>3.4.2 One-To-Many Mappings</h3>
<p>Now let’s consider the <em>works in</em> relationship between <em>Employee</em> and <em>Division</em> in  <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure11ObjectRelationships">Figure 11</a>.  This is a one-to-many relationship – an employee works in one division and a single division has many employees working in it.  As you can see in <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure13PropertyMappings">Figure 13</a> an interesting thing about this relationship is that it should be automatically traversed from <em>Employee</em> to <em>Division</em>, something often referred to as a cascading read, but not in the other direction.  Cascading saves and cascading deletes are also possible, something covered in the discussion of <a href="http://www.agiledata.org/essays/referentialIntegrity.html">referential integrity</a>.</p>
<p>When an employee is read into memory the relationship is automatically traversed to read in the division that they work in.  Because you don’t want several copies of the same division, for example if you have ten employee objects that all work for the IT division you want them to refer to the same IT division object in memory.  The implication is that you will need to implement a strategy for doing this, one option is to implement a cache that ensures only one copy of an object exists in memory or to simply have the <em>Division</em> class implement it’s own collection of instances in memory (effectively a mini-cache).  If the application needs to it will read the <em>Division</em> object into memory, then it will set the value of <em>Employee.division</em> to reference the appropriate <em>Division</em> object.  Similarly the <em>Division.addEmployee()</em> operation will be invoked to add the employee object into its collection.</p>
<p>Saving the relationship works in the same way as it does for one-to-one relationships – when the objects are saved so are their primary and foreign key values so therefore the relationship is automatically saved.</p>
<p>Every example in this article uses foreign keys, such as <em>Employee.DivisionPOID</em>, pointing to the primary keys of other tables, in this case <em>Division.DivisionPOID</em>.   This doesn’t have to be the case, sometimes a foreign key can refer to an alternate key.  For example, if the <em>Employee</em> table of <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure12RDBRelationships">Figure 12</a> were to include a <em>SocialSecurityNumber</em> column then that would be an alternate key for that table (assuming all employees are American citizens).  If this where the case you would have the option to replace the <em>Position.EmployeePOID</em> column with <em>Position.SocialSecurityNumber</em>.</p>
<h3>3.4.3 Many-To-Many Mappings</h3>
<p>To implement many-to-many relationships you need the concept of an associative table, a data entity whose sole purpose is to maintain the relationship between two or more tables in a relational database. In  <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure11ObjectRelationships">Figure 11</a> there is a many-to-many relationship between <em>Employee</em> and <em>Task</em>.  In the data schema of <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure12RDBRelationships">Figure 12</a> I needed to introduce the associative table <em>EmployeeTask</em> to implement a many-to-many relationship the <em>Employee</em> and <em>Task</em> tables.  In relational databases the attributes contained in an associative table are traditionally the combination of the keys in the tables involved in the relationship, in the case <em>EmployeePOID</em> and <em>TaskPOID</em>.  The name of an associative table is typically either the combination of the names of the tables that it associates or the name of the association that it implements. In this case I chose <em>EmployeeTask</em> over <em>Assigned</em>.</p>
<p>Notice the multiplicities in  <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure11ObjectRelationships">Figure 11</a>.  The rule is that the multiplicities &#8220;cross over&#8221; once the associative table is introduced, as indicated in <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure12RDBRelationships">Figure 12</a>.  A multiplicity of 1 is always introduced on the outside edges of the relationship within the data schema to preserve overall multiplicity of the original relationship.  The original relationship indicated that an employee is assigned to one or more tasks and that a task has zero or more employees assigned to it. In the data schema you see that this is still true even with the associative table in place to maintain the relationship.</p>
<p>Assume that an employee object is in memory and we need a list of all the tasks they have been assigned.  The steps that the application would need to go through are:</p>
<ol>
<li>Create a SQL Select statement that joins the <em>EmployeeTask</em> and <em>Task</em> tables together, choosing all <em>EmployeeTask</em> records     with the an <em>EmployeePOID</em> value the same as the employee we are     putting the task list together.</li>
<li>The Select statement is run against the database.</li>
<li>The data records representing these tasks are marshaled     into <em>Task</em> objects.  Part     of this effort includes checking to see if the <em>Task</em> object is already     in memory.  If it is then we may     choose to refresh the object with the new data values (this is a <a href="http://www.agiledata.org/essays/concurrencyControl.html">concurrency</a> issue).</li>
<li>The <em>Employee.addTask()</em> operation is invoked for     each <em>Task</em> object to build the collection up.</li>
</ol>
<p>A similar process would have been followed to read in the employees involved in a given task.  To save the relationship, still from the point of view of the <em>Employee</em> object, the steps would be:</p>
<ol>
<li>Start a transaction.</li>
<li>Add Update statements for any task objects that have     changed.</li>
<li>Add Insert statements for the <em>Task</em> table for any     new tasks that you have created.</li>
<li>Add Insert statements for the <em>EmployeeTask</em> table     for the new tasks.</li>
<li>Add Delete statements for the <em>Task</em> table any     tasks that have been deleted.  This     may not be necessary if the individual object deletions have already     occurred.</li>
<li>Add Delete statements for the <em>EmployeeTask</em> table     for any tasks that have been deleted, a step that may not be needed if the     individual deletions have already occurred.</li>
<li>Add Delete statements for the <em>EmployeeTask</em> table     for any tasks that are no longer assigned to the employee.</li>
<li>Run the transaction.</li>
</ol>
<p>Many-to-many relationships are interesting because of the addition of the associative table.  Two business classes are being mapped to three data tables to support this relationship, so there is extra work to do as a result.</p>
<h3>3.5 Mapping Ordered Collections</h3>
<p><a href="http://www.agiledata.org/essays/mappingObjects.html#Figure1SimpleMappingExample">Figure 1</a> depicted a classic <em>Order</em> and <em>OrderItem</em> model with an aggregation association between the two classes.  An interesting twist is the {ordered} constraint placed on the relationship – users care about the order in which items appear on an order.  When mapping this to a relational database you need to add an addition column to track this information.  The database schema, also depicted in <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure1SimpleMappingExample">Figure 1</a>, includes the column <em>OrderItem.ItemSequence</em> to persist this information.  Although this mapping seems straightforward on the surface, there are several issues that you need take into consideration.  These issues become apparent when you consider basic persistence functionality for the aggregate:</p>
<ul>
<li><strong>Read the data in the proper sequence</strong>.      The scaffolding attribute that implements this relationship must be a     collection that enables sequential ordering of references and it must be     able to grow as new <em>OrderItems</em> are added to the <em>Order</em>.      In <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure2IncludingShadowInformation">Figure 2</a> you see     that a Vector is used, a Java collection class that meets these     requirements.  As you read the     order and order items into memory the Vector must be filled in the proper     sequence.  If the values of the <em>OrderItem.ItemSequence </em>column start from 1 and increase by 1 then you can simply use the value     of the column as the position to insert order items into the collection.       When this isn’t the case you must include an ORDER BY clause in the     SQL statement submitted to the database to ensure that the rows appear in     order in the result set.</li>
<li><strong>Don’t include the sequence number in the key</strong>.      You have an order with five order items in memory and they have been     saved into the database.  You now insert a new order item in between the second and     third order items, giving you a total of six order items.  With the current data schema of  	<a href="http://www.agiledata.org/essays/mappingObjects.html#Figure1SimpleMappingExample">Figure     1</a> you have to renumber the sequence numbers for every order item that     appears after the new order item and then write out all them even though     nothing has changed other than the sequence number in the other order items.      Because the sequence number is part of the primary key of the <em>OrderItem</em> table this could be problematic if other tables, not shown in  	<a href="http://www.agiledata.org/essays/mappingObjects.html#Figure1SimpleMappingExample">Figure     1</a>, refer to rows in <em>OrderItem</em> via foreign keys that include <em>ItemSequence</em>.      A better approach is shown in <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure15OrderedCollection">Figure     15</a> where the <em>OrderItemID</em> column is used as the primary key.</li>
<li><strong>When do you update sequence numbers after     rearranging the order items?</strong> Whenever     you rearrange order items on an order, perhaps you moved the fourth order     item to be the second one on the order, you need to update the sequence     numbers within the database.  You     may decide to cache these changes in memory until you decide to write out     the entire order, although this runs the risk that the proper sequence     won’t be saved in the event of a power outage.</li>
<li><strong>Do you update sequence numbers after deleting an     order item?</strong> If you delete     the fifth of six order items do you want to update the sequence number for     what is now the fifth item or do you want to leave it as it.      The sequence numbers still work – the values are 1, 2, 3, 4, 6 –     but you can no longer use them as the position indicators within your     collection without leaving a hole in the fifth position.</li>
<li><strong>Consider sequence number gaps greater than one.</strong> Instead of assigning sequence numbers along the lines of 1, 2, 3, …     instead assign numbers such as 10, 20, 30 and so on.      That way you don’t need to update the values of the <em>OrderItem.ItemSequence</em> column every time you rearrange order items because you can assign a     sequence number of 15 when you move something between 10 and 20. You will     need to change the values every so often, for example after several     rearrangements you may find yourself in the position of trying to insert     something between 17 and 18.  Larger gaps help to avoid this (e.g. 50, 100, 150, …) but     you’ll never completely avoid this problem.</li>
</ul>
<p><strong>Figure 15. Improved data schema for persisting Order and OrderItem. </strong></p>
<p align="center">
<h3>3.6 Mapping Recursive Relationships</h3>
<p>A recursive relationship, also called reflexive relationships (<a href="http://www.amazon.com/exec/obidos/ASIN/0201702525/ambysoftinc">Reed 2002</a>; <a href="http://www.amazon.com/exec/obidos/ASIN/0130925691/ambysoftinc">Larman 2002</a>), is one where the same entity (class, data entity, table, …) is involved with both ends of the relationship.  For example the <em>manages</em> relationship in  <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure16RecursiveRelationships">Figure 16</a> is recursive, representing the concept that an employee may manage several other employees.  The aggregate relationship that the <em>Team</em> class has with itself is recursive – a team may be a part of one or more other teams.</p>
<p><a href="http://www.agiledata.org/essays/mappingObjects.html#Figure16RecursiveRelationships">Figure 16</a> depicts a class model that includes two recursive relationships and the resulting data model that it would be mapped to.  For the sake of simplicity the class model includes only the classes and their relationships and the data model includes only the keys.  The <a href="http://www.agiledata.org/essays/mappingObjects.html#ManyToManyMappings">many-to-many</a> recursive aggregation is mapped to the Subteams associative table in the same way that you would map a normal many-to-many relationship – the only difference is that both columns are foreign keys into the same table.  Similarly the <a href="http://www.agiledata.org/essays/mappingObjects.html#OneToManyMappings">one-to-many</a> <em>manages</em> association is mapped in the same way that you would map a normal one-to-many relationship, the <em>ManagerEmployeePOID</em> column refers to another row in the <em>Employee</em> table where the manager’s data is stored.</p>
<p><strong>Figure 16. Mapping recursive relationships.</strong></p>
<p align="center">
<h3>4. Mapping Class-Scope  Properties</h3>
<p>Sometimes a class will implement a property that is applicable to all of its instances and not just single instances.  The <em>Customer</em> class of <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure17ClassScopeAttributes">Figure 17</a> implements <em>nextCustomerNumber</em>, a class attribute (you know this because it’s underlined) which stores the value of the next customer number to be assigned to a new customer object.  Because there is one value for this attribute for the class, not one value per object, we need to map it in a different manner.  <a href="http://www.agiledata.org/essays/mappingObjects.html#Table2ClassScopeProperties">Table 2</a> summarizes the four basic strategies for mapping class scope properties.</p>
<p><strong>Figure 17. Mapping class scope attributes.</strong></p>
<p align="center">
<p><strong>Table 2. Strategies for mapping class scope properties.</strong></p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="222" valign="top"><strong>Strategy </strong></td>
<td width="222" valign="top"><strong>Example </strong></td>
<td width="198" valign="top"><strong>Advantages </strong></td>
<td width="216" valign="top"><strong>Disadvantages </strong></td>
</tr>
<tr>
<td width="222" valign="top">Single Column, Single-Row Table</td>
<td width="222" valign="top">The <em>CustomerNumber</em> table of  		 <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure17ClassScopeAttributes">Figure 17</a> implements this strategy.</td>
<td width="198" valign="top">Simple</p>
<p>Fast access</td>
<td width="216" valign="top">Could result in many small tables</td>
</tr>
<tr>
<td width="222" valign="top">Multi-Column, Single-Row Table for a Single Class</td>
<td width="222" valign="top">If <em>Customer</em> implemented a second class scope       attribute then a <em>CustomerValues</em> table could be introduced with one       column for each attribute.</td>
<td width="198" valign="top">Simple</p>
<p>Fast access</td>
<td width="216" valign="top">Could result in many small tables, although fewer       than the single column approach</td>
</tr>
<tr>
<td width="222" valign="top">Multi-Column, Single-Row Table for all Classes</td>
<td width="222" valign="top">The topmost version of the <em>ClassVariables</em> table in  <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure17ClassScopeAttributes">Figure 17</a>.        This table contains one column for each class attribute within your       application, so if the <em>Employee</em> class had a <em>nextEmployeeNumber</em> class attribute then there would be a column for this as well.</td>
<td width="198" valign="top">Minimal number of tables introduced to your data       schema.</td>
<td width="216" valign="top">Potential for concurrency problems if many classes       need to access the data at once.  One       solution is to introduce a <em>ClassConstants</em> table, as shown in   		<a href="http://www.agiledata.org/essays/mappingObjects.html#Figure17ClassScopeAttributes">Figure 17</a>, to separate attributes that are read only from those that can be       updated.</td>
</tr>
<tr>
<td width="222" valign="top">Multi-Row Generic Schema for all Classes</td>
<td width="222" valign="top">The bottommost version of the <em>ClassVariables</em> and <em>ClassConstants</em> tables of   		<a href="http://www.agiledata.org/essays/mappingObjects.html#Figure17ClassScopeAttributes">Figure 17</a>.  The table contains       one row for each class scope property in your system.</td>
<td width="198" valign="top">Minimal number of tables introduced to your data       schema.</p>
<p>Reduces concurrency problems (assuming your database       supports row-based locking).</td>
<td width="216" valign="top">Need to convert between types (e.g. <em>CustomerNumber</em> is an integer but is stored as character data).</p>
<p>The data schema is coupled to the names of your       classes and their class scope properties.        You could avoid this with an even more generic schema along the       lines of  <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure9GenericDataSchema">Figure 9</a>.</td>
</tr>
</tbody>
</table>
<h3>5. Performance Tuning</h3>
<p>One of the most valuable services that an Agile DBA can perform on a development team is performance tuning.  A very good book is <em><a href="http://www.amazon.com/exec/obidos/ASIN/1558607536/ambysoftinc">Database Tuning</a></em> by Shasha and Bonnet (2003).  When working with structured technology most of the performance tuning effort was database-oriented, generally falling into one of two categories:</p>
<ol>
<li><strong>Database performance tuning</strong>.      This effort focuses on changing the database schema itself, often by <a href="http://www.agiledata.org/essays/dataModeling101.html#Denormalize">denormalizing</a> portions of it.  Other     techniques include changing the types of key columns, for example an index     is typically more effective when it is based on numeric columns instead of     character columns; reducing the number of columns that make up a composite     key; or introducing indices on a table to support common joins.</li>
<li><strong>Data access performance tuning</strong>. This effort     focuses on improving the way that data is accessed.      Common techniques include the introduction of stored procedures to     “crunch” data in the database server to reduce the result set     transmitted across the network; reworking SQL queries to reflect database     features; clustering data to reflect common access needs; and caching data     within your application to reduce the number of accesses.   	In fact, although I haven&#8217;t presented an example in this article, a common  	strategy is to map an attribute of a class to a stored function.  For  	example, you could map the  <em>Customer.totalPortfolio</em> to the <em> calculateCustomerPortfolio()</em> stored procedure.  Granted, this may  	introduce performance problems itself (do you really want this stored  	function to be invoked each time you read in a customer object?) and instead  	you might want to map <em>Customer.totalPortfolio</em> attribute to the <em> Customer.TotalPortfolio</em> column which would be calculated via a trigger  	(or in batch).</li>
</ol>
<p>Neither of these needs go away with object technology, although as <a href="http://www.agiledata.org/essays/mappingObjects.html#Figure18PerformanceTuningOpportunities">Figure 18</a> implies the situation is a little more complicated.  An important thing to remember is that your object schema also has structure to it, therefore changes to your object schema can affect the database access code that is generated based on the mappings to your database.  For example, assume that the <em>Employee</em> class has a <em>homePhoneNumber</em> attribute.  A new feature requires you to implement phone number specific behavior (e.g. your application can call people at home).  You decide to refactor <em>homePhoneNumber</em> into its class, and example of <a href="http://www.agiledata.org/essays/objectOrientation101.html#3ONF">third normal object form (3ONF)</a>, and therefore update your mappings to reflect this change.  Performance degrades as a result of this change, motivating you to change either your mappings which the data access paths or the database schema itself.  The implication is that a change to your object source code could motivate a change to your database schema.  Sometimes the reverse happens as well.  This is perfectly fine, because as an agile software developer you are  used to working in an evolutionary manner.</p>
<p><strong>Figure 18. Performance tuning opportunities.</strong></p>
<p align="center">
<p>There are two main additions to performance tuning that you need to be aware of: <a href="http://www.agiledata.org/essays/mappingObjects.html#TuningYourMappings">mapping tuning</a> and object schema tuning.  Mapping tuning is described below.  When it comes to object schema tuning most changes to your schema will be covered by common <a href="http://www.amazon.com/exec/obidos/ASIN/0201485672/ambysoftinc">refactorings</a>.  However, a technique called <a href="http://www.agiledata.org/essays/mappingObjects.html#LazyReads">lazy reading</a> can help dramatically.</p>
<h3>5.1 Tuning Your Mappings</h3>
<p>Throughout this article you have seen that there is more than one way to map object schemas to data schemas – there are four ways to map <a href="http://www.agiledata.org/essays/mappingObjects.html#MappingInheritance">inheritance structures</a>, two ways to map a <a href="http://www.agiledata.org/essays/mappingObjects.html#OneToOneMappings">one-to-one relationship</a> (depending on where you put the foreign key), and four ways to map <a href="http://www.agiledata.org/essays/mappingObjects.html#MappingClassScope">class-scope properties</a>.  Because you have mapping choices, and because each mapping choice has its advantages and disadvantages, there are opportunities to improve the data access performance of your application by changing your choice of mapping.  Perhaps you implemented the <a href="http://www.agiledata.org/essays/mappingObjects.html#MapEachClassToTable">one table per class</a> approach to mapping inheritance only to discover that it’s too slow, motivating you to refactor it to use the <a href="http://www.agiledata.org/essays/mappingObjects.html#MapHierarchyToTable">one table per hierarchy</a> approach.</p>
<p>It is important to understand that whenever you change a mapping strategy that it will require you to change either your object schema, your data schema, or both.</p>
<h3>5.2 Lazy Reads</h3>
<p>An important performance consideration is whether the attribute should be automatically read in when the object is retrieved.  When an attribute is very large, for example the picture of a person could be 100k whereas the rest of the attributes are less than 1k, and rarely accessed you may want to consider taking a lazy read approach.  The basic idea is that instead of automatically bringing the attribute across the network when the object is read you instead retrieve it only when the attribute is actually needed.  This can be accomplished by a getter method, an operation whose purpose is to provide the value of a single attribute, that checks to see if the attribute has been initialized and if not retrieves it from the database at that point.</p>
<p>Other common uses for lazy read is <a href="http://www.agiledata.org/essays/reporting.html">reporting</a> and for retrieving objects as the results of <a href="http://www.agiledata.org/essays/findingObjects.html">searches</a> where you only need a small subset of the data of an object.</p>
<h3>6. Implementation Impact On Your Objects</h3>
<p>The  <a href="http://www.agiledata.org/essays/impedanceMismatch.html">O/R impedance mismatch</a> forces you to map your object schema to your data schema. To implement these mappings you will need to add code to your business objects, code that impacts your application.  These impacts are the primary fodder for the argument that object purists make against using object and relational technology together.  Although I wish the situation were different, the reality is that we’re using object and relational technology together and very likely will for many years to come.  Like it or not we need to accept this fact.</p>
<p>I think that there is significant value in summarizing how mapping impacts your objects.  Some of this material you have seen in this article and some you will see in other chapters.  The impacts on your code include the need to:</p>
<ul>
<li>Maintain <a href="http://www.agiledata.org/essays/mappingObjects.html#ShadowData">shadow information</a>.</li>
<li><a href="http://www.agiledata.org/essays/databaseRefactoring.html#Refactoring">Refactor</a> it to improve overall performance.</li>
<li>Work with <a href="http://www.agiledata.org/essays/legacyDatabases.html">legacy     data</a>.  It is common to work     with legacy databases and that there are often significant data quality,     design, and architectural problems associated with them.      The implication is that you often need to map your objects to legacy     databases and that your objects may need to implement integration and data     cleansing code to do so.</li>
<li><a href="http://www.agiledata.org/essays/implementationStrategies.html">Encapsulate     database access</a>. Your strategy for encapsulating database access     determines how you will implement your mappings.      Your objects will be impacted by your chosen strategy, anywhere from     including embedded SQL code to implementing a common interface that a     persistence framework requires.</li>
<li>Implement <a href="http://www.agiledata.org/essays/concurrencyControl.html">concurrency     control</a>. Because most applications are multi-user, and because most     databases are accessed by several applications, you run the risk that two     different processes will try to modify the same data simultaneously.      Therefore your objects need to implement concurrency control     strategies that overcome these challenges.</li>
<li><a href="http://www.agiledata.org/essays/findingObjects.html">Retrieve     objects from a relational database</a>.  You     will want to work with collections of the same types of objects at once,     perhaps you want to list all of the employees in a single division.</li>
<li><a href="http://www.agiledata.org/essays/referentialIntegrity.html">Implement     referential integrity</a>.  There are several strategies for implementing referential     integrity between objects and within databases.  Although referential integrity is a business issue, and     therefore should be implemented within your business objects, the reality is     that many if not all referential integrity rules are implemented in the     database instead.</li>
<li><a href="http://www.agiledata.org/essays/accessControl.html">Implement     security access control</a>.  Different people have different access to information.      As a result you need to implement security access control logic     within your objects and your database.</li>
<li><a href="http://www.agiledata.org/essays/reporting.html">Implement     reporting</a>.  Do your business     objects implement basic reporting functionality or do you leave this effort     solely to reporting tools that go directly against your database.      Or do you use a combination.</li>
<li><a href="http://www.agiledata.org/essays/advancedTechniques.html">Implement     object caches</a>.  Object     caches can be used to improve application performance and to ensure that     objects are unique within memory.</li>
</ul>
<h3>7. Implications for Model Driven Architecture (MDA)</h3>
<p>The <a href="http://www.agilemodeling.com/essays/agileMDA.htm">Model-Driven Architecture (MDA)</a> defines an approach to modeling that separates the specification of system functionality from the specification of its implementation on a specific technology platform.  In short, it defines guidelines for structuring specifications expressed as models.  The MDA promotes an approach where the same model specifying system functionality can be realized on multiple platforms through auxiliary mapping standards, or through point mappings to specific platforms.  It also supports the concept of explicitly relating the models of different applications, enabling integration, interoperability and supporting system evolution as platform technologies come and go.</p>
<p>Although the MDA is based on the Unified Modeling Language (UML), and the <a href="http://www.agiledata.org/essays/umlDataModelingProfile.html">UML does not yet officially support a data model</a>, my expectation is that object to relational mapping will prove to be one of the most important features that MDA-compliant CASE tools will support.   My hope is that the members of the OMG find a way to overcome the <a href="http://www.agiledata.org/essays/impedanceMismatch.html#CulturalImpedanceMismatch">cultural impedance mismatch</a> and start to work with data professionals to bring issues such as UML data modeling and object-to-relational mapping into account.  Time will tell.</p>
<h3>8. Patternizing What You Have Learned</h3>
<p>In this article you learned the basics of mapping objects to relational databases (RDBs), including some basic implementation techniques that will be expanded on in following chapters.  You saw that there are several strategies for mapping inheritance structures to RDBs and that mapping object relationships into RDBs is straightforward once you understand the differences between the two technologies.  Techniques for mapping both instance attributes and class attributes were presented, providing you with strategies to complete map a class’s attributes into an RDB.</p>
<p>This article included some methodology discussions that described how mapping is one task in the iterative and incremental approach that is typical of agile software development.  A related concept is that it is a fundamental mistake to allow your existing database schemas or <a href="http://www.agiledata.org/essays/drivingForces.html">data models to drive the development of your object models</a>.  Look at them, treat them as constraints, but don’t let them negatively impact your design if you can avoid it.</p>
<p>Throughout this article I have described mapping techniques in common prose, some authors choose to write patterns instead.  The first such effort was the  <a href="http://www.amazon.com/exec/obidos/ASIN/0201895277/ambysoftinc">Crossing Chasms pattern language</a> and the latest effort is captured in the book <a href="http://www.amazon.com/exec/obidos/ASIN/0321127420/ambysoftinc">Patterns of Enterprise Application Architecture</a>.  <a href="http://www.agiledata.org/essays/mappingObjects.html#Table3MappingPatterns">Table 3</a> summarizes the critical material presented in this article as patterns, using the names suggested by other authors wherever possible.</p>
<p><strong>Table 3. Mapping patterns.</strong></p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="159" valign="top"><strong>Pattern </strong></td>
<td width="699" valign="top"><strong>Description </strong></td>
</tr>
<tr>
<td width="159" valign="top"><a href="http://www.agiledata.org/essays/mappingObjects.html#MapEachClassToTable">Class Table       Inheritance</a></td>
<td width="699" valign="top">Map each individual class within an inheritance       hierarchy to its own table.</td>
</tr>
<tr>
<td width="159" valign="top"><a href="http://www.agiledata.org/essays/mappingObjects.html#MapConcreteClassToTable">Concrete Table       Inheritance</a></td>
<td width="699" valign="top">Map the concrete classes of an inheritance hierarchy       to its own table.</td>
</tr>
<tr>
<td width="159" valign="top"><a href="http://www.agiledata.org/essays/mappingObjects.html#ImplementingRDBRelationships">Foreign Key       Mapping</a></td>
<td width="699" valign="top">A relationship between objects is implemented in a       relational database as foreign keys in tables.</td>
</tr>
<tr>
<td width="159" valign="top"><a href="http://www.agiledata.org/essays/mappingObjects.html#ShadowData">Identity Field</a></td>
<td width="699" valign="top">Maintain the primary key of an object as an       attribute.  This is an example       of Shadow Information.</td>
</tr>
<tr>
<td width="159" valign="top"><a href="http://www.agiledata.org/essays/mappingObjects.html#LazyReads">Lazy Initialization</a></td>
<td width="699" valign="top">Read a high-overhead attribute, such as a picture,       into memory when you first access it, not when you initially read the       object into memory.</td>
</tr>
<tr>
<td width="159" valign="top"><a href="http://www.agiledata.org/essays/mappingObjects.html#LazyReads">Lazy Read</a></td>
<td width="699" valign="top">Read an object into memory only when you require it.</td>
</tr>
<tr>
<td width="159" valign="top"><a href="http://www.agiledata.org/essays/mappingObjects.html#ObjectsDriveData">Legacy Data Constraint</a></td>
<td width="699" valign="top">Legacy data sources are a constraint on your object       schema but they should not drive its definition.</td>
</tr>
<tr>
<td width="159" valign="top"><a href="http://www.agiledata.org/essays/mappingObjects.html#BasicConcepts">Map Similar Types</a></td>
<td width="699" valign="top">Use similar types in your classes and tables.        For example it is easier to map an integer to an numeric column       than it is to map it to a character-based column.</td>
</tr>
<tr>
<td width="159" valign="top"><a href="http://www.agiledata.org/essays/mappingObjects.html#BasicConcepts">Map Simple Property to       Single Column</a></td>
<td width="699" valign="top">Prefer to map the property of an object, such as the       total of an order or the first name of an employee, to a single database       column.</td>
</tr>
<tr>
<td width="159" valign="top"><a href="http://www.agiledata.org/essays/mappingObjects.html#PerformanceTuning">Mapping-Based       Performance Tuning</a></td>
<td width="699" valign="top">To improve overall data access performance you can       change your object schema, your data schema, or the mappings in between       the two.</td>
</tr>
<tr>
<td width="159" valign="top"><a href="http://www.agiledata.org/essays/mappingObjects.html#MappingRecursiveAssociations">Recursive       Relationships Are Nothing Special</a></td>
<td width="699" valign="top">Map a recursive relationship exactly the same way       that you would map a non-recursive relationship.</td>
</tr>
<tr>
<td width="159" valign="top"><a href="http://www.agiledata.org/essays/mappingObjects.html#BasicConcepts">Representing Objects as       Tables</a></td>
<td width="699" valign="top">Prefer to map a single class to a single table but be       prepared to evolve your design based to improve performance.</td>
</tr>
<tr>
<td width="159" valign="top"><a href="http://www.agiledata.org/essays/mappingObjects.html#MappingClassScope">Separate Tables for       Class-Scope Properties</a></td>
<td width="699" valign="top">Introduce separate tables to store class scope       properties.</td>
</tr>
<tr>
<td width="159" valign="top"><a href="http://www.agiledata.org/essays/mappingObjects.html#ShadowData">Shadow Information </a></td>
<td width="699" valign="top">Classes will need to maintain attributes to store the       values of database keys (see Identity Field) and concurrency columns to       persist themselves.</td>
</tr>
<tr>
<td width="159" valign="top"><a href="http://www.agiledata.org/essays/mappingObjects.html#ImplementingRDBRelationships">Single Column       Surrogate Keys</a></td>
<td width="699" valign="top">The easiest key strategy that you can adopt within       your database is to give all tables a single column, surrogate key that       has a globally unique value.</td>
</tr>
<tr>
<td width="159" valign="top"><a href="http://www.agiledata.org/essays/mappingObjects.html#MapHierarchyToTable">Single Table       Inheritance</a></td>
<td width="699" valign="top">Map all the classes of an inheritance hierarchy to a       single table.</td>
</tr>
<tr>
<td width="159" valign="top"><a href="http://www.agiledata.org/essays/mappingObjects.html#ObjectsDriveData">Table Design Time</a></td>
<td width="699" valign="top">Let your object schema form the basis from which you       develop your data schema but be prepared to iterate your design in an       evolutionary manner.</td>
</tr>
<tr>
<td width="159" valign="top"><a href="http://www.agiledata.org/essays/mappingObjects.html#OneToOneMappings">Uni-directional Key       Choice</a></td>
<td width="699" valign="top">When a one-to-one unidirectional association exists       from class A to class B, put the foreign key that maintains the       relationship in the table corresponding to class A.</td>
</tr>
</tbody>
</table>
<h3>9. References and Suggested Online Readings</h3>
<ul>
<li>At  <a href="http://www.ambysoft.com/essays/mappingObjects.html"> www.ambysoft.com/essays/mappingObjects.html</a> I maintain a list of links to mapping white papers posted on the web.</li>
<li><a href="http://www.agiledata.org/essays/adopting.html">Adopting  	Agile/Evolutionary Database Techniques</a></li>
<li><a href="http://www.agiledata.org/essays/bestPractices.html">Agile Database  	Best Practices</a></li>
<li> <a href="http://www.agiledata.org/essays/agileDataModeling.html">Agile/Evolutionary  	Data Modeling</a></li>
<li> <a href="http://www.agiledata.org/essays/keys.html">Choosing a Primary  	Key: Natural or Composite?</a></li>
<li> <a href="http://www2.computer.org/portal/web/csdl/doi/10.1109/DBKDA.2009.11" target="_blank"> A Classification of Object-Relational Impedance Mismatch</a> (Ireland, Bowers, Newton &amp; Waugh)</li>
<li> <a href="http://www.agiledata.org/essays/culturalImpedanceMismatch.html">The  Cultural Impedance Mismatch Between Data Professionals and Application  Developers</a></li>
<li> <a href="http://www.agiledata.org/essays/dataNormalization.html"> Introduction to Data 			Normalization</a></li>
<li><a href="http://www.agiledata.org/essays/mappingObjects.html">Mapping     Objects to Relational Databases</a></li>
<li><a href="http://www.agiledata.org/essays/relationalTheory.html">On  	Relational Theory</a></li>
<li><a href="http://www.ambysoft.com/surveys/">Survey Results (Agile and  			Data Management)</a></li>
<li> <a href="http://www.ddj.com/dept/architect/196500031?cid=Ambysoft">When  	is Enough Modeling Enough?</a></li>
<li> <a href="http://www.agiledata.org/essays/drivingForces.html">Why Data Models Don&#8217;t Drive Object Models (And Vice Versa)</a></li>
</ul>
<p>原文链接：</p>
<p><a href="http://www.agiledata.org/essays/mappingObjects.html">http://www.agiledata.org/essays/mappingObjects.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://bookcold.com/2009/11/99/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->