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 5. Secondary Databases</title>
7    <link rel="stylesheet" href="gettingStarted.css" type="text/css" />
8    <meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
9    <link rel="home" href="index.html" title="Getting Started with Berkeley DB" />
10    <link rel="up" href="index.html" title="Getting Started with Berkeley DB" />
11    <link rel="previous" href="CoreCursorUsage.html" title="Cursor Example" />
12    <link rel="next" href="keyCreator.html" title="Implementing Key &#10;        &#10;        Extractors&#10;        " />
13  </head>
14  <body>
15    <div class="navheader">
16      <table width="100%" summary="Navigation header">
17        <tr>
18          <th colspan="3" align="center">Chapter 5. Secondary Databases</th>
19        </tr>
20        <tr>
21          <td width="20%" align="left"><a accesskey="p" href="CoreCursorUsage.html">Prev</a> </td>
22          <th width="60%" align="center"> </th>
23          <td width="20%" align="right"> <a accesskey="n" href="keyCreator.html">Next</a></td>
24        </tr>
25      </table>
26      <hr />
27    </div>
28    <div class="chapter" lang="en" xml:lang="en">
29      <div class="titlepage">
30        <div>
31          <div>
32            <h2 class="title"><a id="indexes"></a>Chapter 5. Secondary Databases</h2>
33          </div>
34        </div>
35        <div></div>
36      </div>
37      <div class="toc">
38        <p>
39          <b>Table of Contents</b>
40        </p>
41        <dl>
42          <dt>
43            <span class="sect1">
44              <a href="indexes.html#CoreDbAssociate">Opening and Closing Secondary Databases</a>
45            </span>
46          </dt>
47          <dt>
48            <span class="sect1">
49              <a href="keyCreator.html">Implementing Key 
50        
51        Extractors
52        </a>
53            </span>
54          </dt>
55          <dd>
56            <dl>
57              <dt>
58                <span class="sect2">
59                  <a href="keyCreator.html#multikeys">Working with Multiple Keys</a>
60                </span>
61              </dt>
62            </dl>
63          </dd>
64          <dt>
65            <span class="sect1">
66              <a href="readSecondary.html">Reading Secondary Databases</a>
67            </span>
68          </dt>
69          <dt>
70            <span class="sect1">
71              <a href="secondaryDelete.html">Deleting Secondary Database Records</a>
72            </span>
73          </dt>
74          <dt>
75            <span class="sect1">
76              <a href="secondaryCursor.html">
77        
78        Using Cursors with Secondary Databases
79    </a>
80            </span>
81          </dt>
82          <dt>
83            <span class="sect1">
84              <a href="joins.html">Database Joins</a>
85            </span>
86          </dt>
87          <dd>
88            <dl>
89              <dt>
90                <span class="sect2">
91                  <a href="joins.html#joinUsage">Using Join Cursors</a>
92                </span>
93              </dt>
94            </dl>
95          </dd>
96          <dt>
97            <span class="sect1">
98              <a href="coreindexusage.html">Secondary Database Example</a>
99            </span>
100          </dt>
101          <dd>
102            <dl>
103              <dt>
104                <span class="sect2">
105                  <a href="coreindexusage.html#edlWIndexes">Secondary Databases with example_database_load</a>
106                </span>
107              </dt>
108              <dt>
109                <span class="sect2">
110                  <a href="coreindexusage.html#edrWIndexes">Secondary Databases with example_database_read</a>
111                </span>
112              </dt>
113            </dl>
114          </dd>
115        </dl>
116      </div>
117      <p>
118    Usually you find database records by means of the record's key.  However,
119    the key that you use for your record will not always contain the
120    information required to provide you with rapid access to the data that you
121    want to retrieve. For example, suppose your 
122        
123        <span>database</span>
124    contains records related to users. The key might be a string that is some
125    unique identifier for the person, such as a user ID. Each record's data,
126    however, would likely contain a complex object containing details about
127    people such as names, addresses, phone numbers, and so forth.
128    While your application may frequently want to query a person by user
129    ID (that is, by the information stored in the key), it may also on occasion
130    want to locate people by, say, their name.
131  </p>
132      <p>
133    Rather than iterate through all of the records in your database, examining
134    each in turn for a given person's name, you create indexes based on names
135    and then just search that index for the name that you want.  You can do this
136    using secondary databases. In DB, the 
137        
138        <span>database</span> 
139    that contains your data is called a
140    <span class="emphasis"><em>primary database</em></span>. A database that provides an
141    alternative set of keys to access that data is called a <span class="emphasis"><em>secondary
142    database</em></span><span>.</span> In a secondary database, the keys are your alternative 
143    (or secondary) index, and the data corresponds to a primary record's key.
144  </p>
145      <p>
146    You create a secondary database by creating the database, opening it, and
147    then <span class="emphasis"><em>associating</em></span> the database with 
148    the <span class="emphasis"><em>primary</em></span> database (that is, the database for which
149    you are creating the index). As a part of associating
150    the secondary database to the primary, you must provide a callback that is
151    used to create the secondary database keys. Typically this callback creates
152    a key based on data found in the primary database record's key or data.
153  </p>
154      <p>
155  Once opened, DB manages secondary databases for you. Adding or deleting
156  records in your primary database causes DB to update the secondary as
157  necessary. Further, changing a record's data in the primary database may cause
158  DB to modify a record in the secondary, depending on whether the change
159  forces a modification of a key in the secondary database.
160  </p>
161      <p>
162    Note that you can not write directly to a secondary database. 
163
164    
165
166    <span>Any attempt to write to a secondary database
167    results in a non-zero status return.</span>
168    
169    To change the data referenced by a 
170        
171        <span>secondary</span>
172    record, modify the primary database instead. The exception to this rule is
173    that delete operations are allowed on the
174         
175        <span>secondary database.</span> 
176    
177    See <a href="secondaryDelete.html">Deleting Secondary Database Records</a> for more
178    information.
179  </p>
180      <div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
181        <h3 class="title">Note</h3>
182        <p>
183
184        Secondary database records are updated/created by DB 
185        only if the 
186            
187            <span>key creator callback function</span>
188        returns 
189             
190            <span><tt class="literal">0</tt>.</span> 
191        If 
192             
193            <span>a value other than <tt class="literal">0</tt></span>
194        is returned, then DB will not add the key to the secondary database, and 
195        in the event of a record update it will remove any existing key. 
196
197        <span>Note that the callback can use either
198        <tt class="literal">DB_DONOTINDEX</tt> or some error code outside of DB's
199        name space to indicate that the entry should not be indexed.</span>
200
201     </p>
202        <p>
203        See <a href="keyCreator.html">Implementing Key 
204        
205        <span>Extractors</span>
206        </a> for more
207            
208            <span>information.</span>
209    
210    </p>
211      </div>
212      <p>
213    When you read a record from a secondary database, DB automatically
214    returns 
215         
216        <span>the data and optionally the key</span> 
217    from the corresponding record in the primary database.
218    
219  </p>
220      <div class="sect1" lang="en" xml:lang="en">
221        <div class="titlepage">
222          <div>
223            <div>
224              <h2 class="title" style="clear: both"><a id="CoreDbAssociate"></a>Opening and Closing Secondary Databases</h2>
225            </div>
226          </div>
227          <div></div>
228        </div>
229        <p>
230        You manage secondary database opens and closes in the same way as you
231        would any normal database. The only difference is that:
232    </p>
233        <div class="itemizedlist">
234          <ul type="disc">
235            <li>
236              <p>
237                You must associate the secondary to a primary database using
238                    <span><tt class="methodname">DB-&gt;associate()</tt>.</span>
239                    
240            </p>
241            </li>
242            <li>
243              <p>
244                When closing your databases, it is a good idea to make sure you
245                close your secondaries before closing your primaries. This is
246                particularly true if your database closes are not single
247                threaded.
248            </p>
249            </li>
250          </ul>
251        </div>
252        <p>
253        When you associate a secondary to a primary database, you must provide a
254        callback that is used to generate the secondary's keys. These
255        callbacks are described in the next section.
256     </p>
257        <p>
258        For example, to open a secondary database and associate it to a primary
259        database:
260     </p>
261        <a id="c_index1"></a>
262        <pre class="programlisting">#include &lt;db.h&gt;
263
264...
265
266DB *dbp, *sdbp;    /* Primary and secondary DB handles */
267u_int32_t flags;   /* Primary database open flags */
268int ret;           /* Function return value */
269                                                                                                                                     
270/* Primary */
271ret = db_create(&amp;dbp, NULL, 0);
272if (ret != 0) {
273  /* Error handling goes here */
274}
275                                                                                                                                     
276/* Secondary */
277ret = db_create(&amp;sdbp, NULL, 0);
278if (ret != 0) {
279  /* Error handling goes here */
280}
281
282/* Usually we want to support duplicates for secondary databases */
283ret = sdbp-&gt;set_flags(sdbp, DB_DUPSORT);
284if (ret != 0) {
285  /* Error handling goes here */
286}
287
288
289/* Database open flags */
290flags = DB_CREATE;    /* If the database does not exist,
291                       * create it.*/
292
293/* open the primary database */
294ret = dbp-&gt;open(dbp,        /* DB structure pointer */
295                NULL,       /* Transaction pointer */
296                "my_db.db", /* On-disk file that holds the database. */
297                NULL,       /* Optional logical database name */
298                DB_BTREE,   /* Database access method */
299                flags,      /* Open flags */
300                0);         /* File mode (using defaults) */
301if (ret != 0) {
302  /* Error handling goes here */
303}
304
305/* open the secondary database */
306ret = sdbp-&gt;open(sdbp,          /* DB structure pointer */
307                 NULL,          /* Transaction pointer */
308                 "my_secdb.db", /* On-disk file that holds the database. */
309                 NULL,          /* Optional logical database name */
310                 DB_BTREE,      /* Database access method */
311                 flags,         /* Open flags */
312                 0);            /* File mode (using defaults) */
313if (ret != 0) {
314  /* Error handling goes here */
315}
316
317/* Now associate the secondary to the primary */
318dbp-&gt;associate(dbp,            /* Primary database */
319               NULL,           /* TXN id */
320               sdbp,           /* Secondary database */
321               get_sales_rep,  /* Callback used for key creation. Not 
322                                * defined in this example. See the next
323                                * section. */
324               0);              /* Flags */</pre>
325        <p>
326    Closing the primary and secondary databases is accomplished exactly as you
327    would for any database:
328  </p>
329        <a id="c_index2"></a>
330        <pre class="programlisting">/* Close the secondary before the primary */
331if (sdbp != NULL)
332    sdbp-&gt;close(sdbp, 0);
333if (dbp != NULL)
334    dbp-&gt;close(dbp, 0); </pre>
335      </div>
336    </div>
337    <div class="navfooter">
338      <hr />
339      <table width="100%" summary="Navigation footer">
340        <tr>
341          <td width="40%" align="left"><a accesskey="p" href="CoreCursorUsage.html">Prev</a> </td>
342          <td width="20%" align="center">
343            <a accesskey="u" href="index.html">Up</a>
344          </td>
345          <td width="40%" align="right"> <a accesskey="n" href="keyCreator.html">Next</a></td>
346        </tr>
347        <tr>
348          <td width="40%" align="left" valign="top">Cursor Example </td>
349          <td width="20%" align="center">
350            <a accesskey="h" href="index.html">Home</a>
351          </td>
352          <td width="40%" align="right" valign="top"> Implementing Key 
353        
354        Extractors
355        </td>
356        </tr>
357      </table>
358    </div>
359  </body>
360</html>
361