• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/ap/gpl/timemachine/db-4.7.25.NC/docs/collections/tutorial/
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3<html xmlns="http://www.w3.org/1999/xhtml">
4  <head>
5    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6    <title>Chapter��3.��
7		Using Secondary Indices
8	</title>
9    <link rel="stylesheet" href="gettingStarted.css" type="text/css" />
10    <meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
11    <link rel="home" href="index.html" title="Berkeley DB Collections Tutorial" />
12    <link rel="up" href="index.html" title="Berkeley DB Collections Tutorial" />
13    <link rel="previous" href="handlingexceptions.html" title="&#10;&#9;&#9;Handling Exceptions&#10;&#9;" />
14    <link rel="next" href="openingforeignkeys.html" title="&#10;&#9;&#9;&#10;&#9;&#9;More Secondary Key Indices&#10;&#9;" />
15  </head>
16  <body>
17    <div class="navheader">
18      <table width="100%" summary="Navigation header">
19        <tr>
20          <th colspan="3" align="center">Chapter��3.��
21		Using Secondary Indices
22	</th>
23        </tr>
24        <tr>
25          <td width="20%" align="left"><a accesskey="p" href="handlingexceptions.html">Prev</a>��</td>
26          <th width="60%" align="center">��</th>
27          <td width="20%" align="right">��<a accesskey="n" href="openingforeignkeys.html">Next</a></td>
28        </tr>
29      </table>
30      <hr />
31    </div>
32    <div class="chapter" lang="en" xml:lang="en">
33      <div class="titlepage">
34        <div>
35          <div>
36            <h2 class="title"><a id="UsingSecondaries"></a>Chapter��3.��
37		Using Secondary Indices
38	</h2>
39          </div>
40        </div>
41        <div></div>
42      </div>
43      <div class="toc">
44        <p>
45          <b>Table of Contents</b>
46        </p>
47        <dl>
48          <dt>
49            <span class="sect1">
50              <a href="UsingSecondaries.html#opensecondaryindices">
51		Opening Secondary Key Indices
52	</a>
53            </span>
54          </dt>
55          <dt>
56            <span class="sect1">
57              <a href="openingforeignkeys.html">
58		
59		More Secondary Key Indices
60	</a>
61            </span>
62          </dt>
63          <dt>
64            <span class="sect1">
65              <a href="indexedcollections.html">
66		Creating Indexed Collections
67	</a>
68            </span>
69          </dt>
70          <dt>
71            <span class="sect1">
72              <a href="retrievingbyindexkey.html">
73		Retrieving Items by Index Key
74	</a>
75            </span>
76          </dt>
77        </dl>
78      </div>
79      <p>
80    In the Basic example, each store has a single <span class="emphasis"><em>primary
81	key</em></span>. The Index example extends the Basic example to add the use of 
82    <span class="emphasis"><em>secondary keys</em></span>. 
83</p>
84      <p>
85    The complete source of the final version of the example program
86	is included in the Berkeley DB distribution.
87</p>
88      <div class="sect1" lang="en" xml:lang="en">
89        <div class="titlepage">
90          <div>
91            <div>
92              <h2 class="title" style="clear: both"><a id="opensecondaryindices"></a>
93		Opening Secondary Key Indices
94	</h2>
95            </div>
96          </div>
97          <div></div>
98        </div>
99        <p>
100    <span class="emphasis"><em>Secondary indices</em></span> or <span class="emphasis"><em>secondary databases</em></span> are used
101	to access a primary database by a key other than the primary key.
102	Recall that the Supplier Number field is the primary key of the
103	Supplier database. In this section, the Supplier City field will be
104	used as a secondary lookup key. Given a city value, we would like
105	to be able to find the Suppliers in that city. Note that more than
106	one Supplier may be in the same city.
107</p>
108        <p>
109    Both primary and secondary databases contain key-value records.
110	The key of an index record is the secondary key, and its value is
111	the key of the associated record in the primary database. When lookups by
112	secondary key are performed, the associated record in the primary
113	database is transparently retrieved by its primary key and returned
114	to the caller.
115</p>
116        <p>
117    Secondary indices are maintained automatically when index key
118	fields (the City field in this case) are added, modified or removed
119	in the records of the primary database. However, the application
120	must implement a 
121    
122    <a href="../../java/com/sleepycat/db/SecondaryKeyCreator.html" target="_top">SecondaryKeyCreator</a>
123    
124	that extracts the index key from the database record.
125</p>
126        <p>
127    It is useful to contrast opening an secondary index with opening
128	a primary database (as described earlier in 
129    <a href="opendatabases.html">
130		Opening and Closing Databases
131	</a>.
132</p>
133        <div class="itemizedlist">
134          <ul type="disc">
135            <li>
136              <p>
137            A primary database may be associated with one or more secondary
138            indices. A secondary index is always associated with exactly one
139            primary database.
140        </p>
141            </li>
142            <li>
143              <p>
144            For a secondary index, a 
145            
146            <a href="../../java/com/sleepycat/db/SecondaryKeyCreator.html" target="_top">SecondaryKeyCreator</a>
147            
148            must be implemented by the application to extract the index key
149            from the record of its associated primary database.
150        </p>
151            </li>
152            <li>
153              <p>
154            A primary database is represented by a 
155            
156            <a href="../../java/com/sleepycat/db/Database.html" target="_top">Database</a>
157            
158            object and a secondary index is represented by a 
159            
160            <a href="../../java/com/sleepycat/db/SecondaryDatabase.html" target="_top">SecondaryDatabase</a>
161            
162            object. The 
163            
164            <a href="../../java/com/sleepycat/db/SecondaryDatabase.html" target="_top">SecondaryDatabase</a>
165            
166            class extends the 
167            
168            <a href="../../java/com/sleepycat/db/Database.html" target="_top">Database</a>
169            
170            class.
171        </p>
172            </li>
173            <li>
174              <p>
175            When a 
176            
177            <a href="../../java/com/sleepycat/db/SecondaryDatabase.html" target="_top">SecondaryDatabase</a>
178            
179            is created it is associated with a primary 
180            
181            <a href="../../java/com/sleepycat/db/Database.html" target="_top">Database</a>
182            
183            object and a 
184            
185            <span>
186                <a href="../../java/com/sleepycat/db/SecondaryKeyCreator.html" target="_top">SecondaryKeyCreator</a>.
187            </span>
188        </p>
189            </li>
190          </ul>
191        </div>
192        <p>
193    The <tt class="classname">SampleDatabase</tt> class is extended to open the
194	Supplier-by-City secondary key index.
195</p>
196        <a id="index_java_sampledatabase"></a>
197        <pre class="programlisting"><b class="userinput"><tt>import com.sleepycat.bind.serial.SerialSerialKeyCreator;
198import com.sleepycat.db.SecondaryConfig;
199import com.sleepycat.db.SecondaryDatabase;</tt></b>
200...
201public class SampleDatabase
202{
203    ...
204<b class="userinput"><tt>    private static final String SUPPLIER_CITY_INDEX = "supplier_city_index";
205    ...
206    private SecondaryDatabase supplierByCityDb;
207    ...</tt></b>
208    public SampleDatabase(String homeDirectory)
209        throws DatabaseException, FileNotFoundException
210    {
211        ...
212<b class="userinput"><tt>        SecondaryConfig secConfig = new SecondaryConfig();
213        secConfig.setTransactional(true);
214        secConfig.setAllowCreate(true);
215        secConfig.setType(DatabaseType.BTREE);
216        secConfig.setSortedDuplicates(true);
217
218        secConfig.setKeyCreator(
219            new SupplierByCityKeyCreator(javaCatalog,
220                                         SupplierKey.class,
221                                         SupplierData.class,
222                                         String.class));
223
224        supplierByCityDb = env.openSecondaryDatabase(null, 
225                                                     SUPPLIER_CITY_INDEX,
226                                                     null,
227                                                     supplierDb,
228                                                     secConfig);</tt></b>
229    ...
230    }
231} </pre>
232        <p>
233    A 
234    
235    <a href="../../java/com/sleepycat/db/SecondaryConfig.html" target="_top">SecondaryConfig</a>
236    
237	object is used to configure the secondary database. The 
238    
239    <a href="../../java/com/sleepycat/db/SecondaryConfig.html" target="_top">SecondaryConfig</a>
240    
241	class extends the 
242    
243    <a href="../../java/com/sleepycat/db/DatabaseConfig.html" target="_top">DatabaseConfig</a>
244    
245	class, and most steps for configuring a secondary database are the
246	same as for configuring a primary database. The main difference in
247	the example above is that the
248	<tt class="methodname">SecondaryConfig.setSortedDuplicates()</tt> method is called to
249	allow duplicate index keys. This is how more than one Supplier may
250	be in the same City. If this property is not specified, the default is
251	that the index keys of all records must be unique.
252</p>
253        <p>
254    For a primary database, duplicate keys are not normally used
255	since a primary database with duplicate keys may not have any
256	associated secondary indices. If primary database keys are not
257	unique, there is no way for a secondary key to reference a specific
258	record in the primary database.
259</p>
260        <p>
261    Note that <tt class="methodname">setSortedDuplicates()</tt> and not
262    <tt class="methodname">setUnsortedDuplicates()</tt> was called. Sorted
263    duplicates are always used for indices rather than unsorted duplicates,
264    since sorting enables optimized equality joins.
265</p>
266        <p>
267    Opening a secondary key index requires creating a 
268    
269    <span>
270        <a href="../../java/com/sleepycat/db/SecondaryKeyCreator.html" target="_top">SecondaryKeyCreator</a>.
271    </span>
272	The <tt class="classname">SupplierByCityKeyCreator</tt> class implements the 
273    
274    <a href="../../java/com/sleepycat/db/SecondaryKeyCreator.html" target="_top">SecondaryKeyCreator</a>
275    
276	interface and will be defined below.
277</p>
278        <p>
279    The 
280    
281    <a href="../../java/com/sleepycat/db/SecondaryDatabase.html" target="_top">SecondaryDatabase</a>
282    
283	object is opened last. If you compare the
284	<tt class="methodname">openSecondaryDatabase()</tt> and <tt class="methodname">openDatabase()</tt> methods you'll
285	notice only two differences:
286</p>
287        <div class="itemizedlist">
288          <ul type="disc">
289            <li>
290              <p>
291            <tt class="methodname">openSecondaryDatabase()</tt> has an extra parameter for
292            specifying the associated primary database. The primary database is
293            <tt class="literal">supplierDb</tt> in this case.
294        </p>
295            </li>
296            <li>
297              <p>
298            The last parameter of <tt class="methodname">openSecondaryDatabase()</tt> is a
299            <tt class="literal">SecondaryConfig</tt> instead of a <tt class="literal">DatabaseConfig</tt>.
300        </p>
301            </li>
302          </ul>
303        </div>
304        <p>
305    How to use the secondary index to access records will be shown
306	in a later section.
307</p>
308        <p>
309    The application-defined <tt class="classname">SupplierByCityKeyCreator</tt> class is
310	shown below. It was used above to configure the secondary
311	database.
312</p>
313        <a id="index_supplierbycitykeycreator"></a>
314        <pre class="programlisting">public class SampleDatabase
315{
316...
317<b class="userinput"><tt>    private static class SupplierByCityKeyCreator
318        extends SerialSerialKeyCreator
319    {
320        private SupplierByCityKeyCreator(StoredClassCatalog catalog,
321                                         Class primaryKeyClass,
322                                         Class valueClass,
323                                         Class indexKeyClass)
324        {
325            super(catalog, primaryKeyClass, valueClass, indexKeyClass);
326        }
327
328        public Object createSecondaryKey(Object primaryKeyInput,
329                                         Object valueInput)
330        {
331            SupplierData supplierData = (SupplierData) valueInput;
332            return supplierData.getCity();
333        }
334    }</tt></b>
335...
336} </pre>
337        <p>
338    In general, a key creator class must implement the 
339    
340    <a href="../../java/com/sleepycat/db/SecondaryKeyCreator.html" target="_top">SecondaryKeyCreator</a>
341    
342	interface. This interface has methods that operate on the record
343	data as raw bytes. In practice, it is easiest to use an abstract
344	base class that performs the conversion of record data to and from
345	the format defined for the database's key and value. The base class
346	implements the 
347    
348    <a href="../../java/com/sleepycat/db/SecondaryKeyCreator.html" target="_top">SecondaryKeyCreator</a>
349    
350	interface and has abstract methods that must be implemented in turn
351	by the application.
352</p>
353        <p>
354    In this example the 
355    <a href="../../java/com/sleepycat/bind/serial/SerialSerialKeyCreator.html" target="_top">SerialSerialKeyCreator</a>
356    
357	base class is used because the database record uses the serial
358	format for both its key and its value. The abstract methods of this
359	class have key and value parameters of type 
360    <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html" target="_top">Object</a>
361    
362	which are automatically converted to and from the raw record data
363	by the base class.
364</p>
365        <p>
366    To perform the conversions properly, the key creator must be
367	aware of all three formats involved: the key format of the primary
368	database record, the value format of the primary database record,
369	and the key format of the index record. The 
370    <a href="../../java/com/sleepycat/bind/serial/SerialSerialKeyCreator.html" target="_top">SerialSerialKeyCreator</a>
371    
372	constructor is given the base classes for these three formats as
373	parameters.
374</p>
375        <p>
376    The <tt class="methodname">SerialSerialKeyCreator.createSecondaryKey</tt> method is
377	given the key and value of the primary database record as
378	parameters, and it returns the key of the index record. In this
379	example, the index key is a field in the primary database record
380	value. Since the record value is known to be a <tt class="classname">SupplierData</tt>
381	object, it is cast to that class and the city field is
382	returned.
383</p>
384        <p>
385    Note that the <tt class="literal">primaryKeyInput</tt> parameter is not used in
386	the example. This parameter is needed only when an index key is
387	derived from the key of the primary database record. Normally an
388	index key is derived only from the primary database record value,
389	but it may be derived from the key, value or both.
390</p>
391        <p>
392    The following getter methods return the secondary database
393	object for use by other classes in the example program. The
394	secondary database object is used to create Java collections for
395	accessing records via their secondary keys.
396</p>
397        <a id="index_getsupplierbycitydatabase"></a>
398        <pre class="programlisting">public class SampleDatabase
399{
400    ...
401<b class="userinput"><tt>    public final SecondaryDatabase getSupplierByCityDatabase()
402    {
403        return supplierByCityDb;
404    }</tt></b>
405    ...
406} </pre>
407        <p>
408    The following statement closes the secondary database.
409</p>
410        <a id="index_close"></a>
411        <pre class="programlisting">public class SampleDatabase
412{
413    ...
414    public void close()
415        throws DatabaseException {
416
417<b class="userinput"><tt>        supplierByCityDb.close();</tt></b>
418        partDb.close();
419        supplierDb.close();
420        shipmentDb.close();
421        javaCatalog.close();
422        env.close();
423    }
424    ...
425} </pre>
426        <p>
427    Secondary databases must be closed before closing their
428	associated primary database.
429</p>
430      </div>
431    </div>
432    <div class="navfooter">
433      <hr />
434      <table width="100%" summary="Navigation footer">
435        <tr>
436          <td width="40%" align="left"><a accesskey="p" href="handlingexceptions.html">Prev</a>��</td>
437          <td width="20%" align="center">
438            <a accesskey="u" href="index.html">Up</a>
439          </td>
440          <td width="40%" align="right">��<a accesskey="n" href="openingforeignkeys.html">Next</a></td>
441        </tr>
442        <tr>
443          <td width="40%" align="left" valign="top">
444		Handling Exceptions
445	��</td>
446          <td width="20%" align="center">
447            <a accesskey="h" href="index.html">Home</a>
448          </td>
449          <td width="40%" align="right" valign="top">��
450		
451		More Secondary Key Indices
452	</td>
453        </tr>
454      </table>
455    </div>
456  </body>
457</html>
458