?? fastdb.htm
字號(hào):
Structure fields can be indexed and used in an <code>order by</code>
specification. Structures can contain other structures as their components;
there are no limitations on the nesting level.<P>
The programmer can define methods for structures, which can be used
in queries with the same syntax as normal structure components.
Such a method should have no arguments except a pointer to the object to which
it belongs (the <code>this</code> pointer in C++), and should return
an atomic value (of boolean, numeric, string or reference type).
Also the method should not change the object instance (immutable method).
If the method returns a string, this string should be allocated using the
<code>new char</code> operator, because it will be deleted after copying of
its value.<P>
So user-defined methods can be used for
the creation of <I>virtual</I> components -
components which are not stored in the database,
but instead are calculated
using values of other components.
For example, the FastDB <code>dbDateTime</code>
type contains only integer timestamp components and such methods
as <code>dbDateTime::year()</code>, <code>dbDateTime::month()</code>...
So it is possible to specify queries like: "<code>delivery.year = 1999</code>"
in an application, where the <code>delivery</code> record field has
<code>dbDateTime</code> type. Methods are executed in the context of the
application, where they are defined, and are not available to other
applications and interactive SQL.<P>
<H3><A NAME = "array">Arrays</A></H3>
FastDB accepts arrays with dynamic length as components of records.
Multidimensional arrays are not supported, but it is possible to
define an array of arrays. It is possible to sort records in the result set
by length of array field.
FastDB provides a set of special constructions for dealing with arrays:<P>
<OL>
<LI>It is possible to get the number of elements in the array by
the <code>length()</code> function.
<LI>Array elements can be fetched by the<code>[]</code> operator.
If an index expression is out of array range, an exception will be raised.
<LI>The operator <code>in</code> can be used to check if an array contains
a value specified by the left operand. This operation can be used only for arrays of
atomic type: with boolean, numeric, reference or string components.
<LI>Array can be updated using <code>update</code> method which creates copy of the array and returns
non-constant reference.
<LI>Iteration through array elements is performed by the <code>exists</code>
operator. A variable specified after the <code>exists</code> keyword can be used
as an index in arrays in the expression preceeded by the <code>exists</code>
quantor. This index variable will iterate through all possible array
index values, until the value of the expression will become <code>true</code> or
the index runs out of range. The condition
<PRE>
exists i: (contract[i].company.location = 'US')
</PRE>
will select all details which are shipped by companies
located in 'US', while the query
<PRE>
not exists i: (contract[i].company.location = 'US')
</PRE>
will select all details which are shipped from companies outside 'US'.<P>
Nested <code>exists</code> clauses are allowed. Using nested
<code>exists</code>
quantors is equivalent to nested loops using the correspondent
index variables. For example the query
<PRE>
exists column: (exists row: (matrix[column][row] = 0))
</PRE>
will select all records, containing 0 in elements of a <code>matrix</code>
field, which has type array of array of integer.
This construction is equivalent to the following
two nested loops:
<PRE>
bool result = false;
for (int column = 0; column < matrix.length(); column++) {
for (int row = 0; row < matrix[column].length(); row++) {
if (matrix[column][row] == 0) {
result = true;
break;
}
}
}
</PRE>
The order of using indices is essential!
The result of the following query execution
<PRE>
<code>exists row: (exists column: (matrix[column][row] = 0))</code>
</PRE>
will be completely different from the result of the previous query.
In the last case, the program simply hangs due to an infinite loop
in case of empty matrices.
</OL>
<H3><A NAME = "string">Strings</A></H3>
All strings in FastDB have varying length and the programmer should not
worry about specification of maximal length for character fields.
All operations acceptable for arrays are also applicable to strings.
In addition to them, strings have a set of own operations.
First of all, strings can be compared with each other using standard
relation operators. At present, FastDB supports only the
ASCII character set (corresponds to type <code>char</code> in C) and
byte-by-byte comparison of strings ignoring locality settings.<P>
The operator <code>like</code> can be used for
matching a string with a pattern containing special wildcard characters
'%' and '_'. The character '_' matches any single character,
while the character '%' matches zero or more characters.
An extended form of the <code>like</code> operator together with
the <code>escape</code> keyword can be used to handle the
characters '%' and '_' in the pattern as normal characters if
they are preceded by a special escape character, specified after
the <code>escape</code> keyword.<P>
It is possible to search substrings within a string by the <code>in</code>
operator. The expression <code>('blue' in color)</code> will be true
for all records which <code>color</code> field contains 'blue'.
If the length of the searched string is greater than some threshold value
(currently 512), a Boyer-Moore substring search algorithm is used instead
of a straightforward search implementation.<P>
Strings can be concatenated by <code>+</code> or <code>||</code> operators.
The last one was added for compatibility with the ANSI SQL standard.
As far as FastDB doesn't support the implicit conversion to string type in
expressions, the semantic of the operator <code>+</code> can be redefined for
strings.<P>
<H3><A NAME = "reference">References</A></H3>
References can be dereferenced using the same dot notation as used for
accessing structure components. For example the following query
<PRE>
company.address.city = 'Chicago'
</PRE>
will access records referenced by the <code>company</code> component of
a <code>Contract</code> record and extract the city component of the
<code>address</code> field of the referenced record from
the <code>Supplier</code> table.<P>
References can be checked for <code>null</code> by <code>is null</code>
or <code>is not null</code> predicates. Also references can be compared for
equality with each other as well as with the special <code>null</code>
keyword. When a null reference is dereferenced, an exception is raised
by FastDB.<P>
There is a special keyword <code>current</code>, which
during a table search can be used to refer to the current record.
Usually , the <code>current</code>
keyword is used for comparison of the current record identifier with
other references or locating it within an array of references.
For example, the following query will search in the <code>Contract</code>
table for all active contracts
(assuming that the field <code>canceledContracts</code> has a
<code>dbArray< dbReference<Contract> ></code> type):
<PRE>
current not in supplier.canceledContracts
</PRE><P>
FastDB provides special operators for recursive traverse of records by
references:
<PRE>
<code>start from</code> <I>root-references</I>
( <code>follow by</code> <I>list-of-reference-fields</I> )
</PRE>
The first part of this construction is used to specify root objects.
The nonterminal <I>root-references</I> should be a variable of reference or
of array of reference type. The two special keywords <code>first</code> and
<code>last</code> can be used here, locating the first/last record in the table
correspondingly.
If you want to check all records
referenced by an array of references or a single reference field
for some condition, then this
construction can be used without the <code>follow by</code> part.<P>
If you specify the follow by part, then FastDB will recursively traverse
the table of records, starting from the root
references and using a
<I>list-of-reference-fields</I> for transition between records.
The <I>list-of-reference-fields</I> should consist of fields of
reference or of array of reference type. The traverse is done in depth first
top-left-right order (first we visit the parent node and then the siblings in
left-to-right order).
The recursion terminates when a null reference is accessed
or an already visited record is referenced. For example the following
query will search a tree of records with weight larger than 1 in TLR order:<P>
<PRE>
"weight > 1 start from first follow by left, right"
</PRE><P>
For the following tree:
<PRE>
A:1.1
B:2.0 C:1.5
D:1.3 E:1.8 F:1.2 G:0.8
</PRE>
the result of the query execution will be:
<PRE>
('A', 1.1), ('B', 2.0), ('D', 1.3), ('E', 1.8), ('C', 1.5), ('F', 1.2)
</PRE><P>
As was already mentioned FastDB always manipulates with objects and doesn't accept joins.
Joins can be implemented using references. Consider the classical
<code>Supplier-Shipment-Detail</code> examples:
<PRE>
struct Detail {
char const* name;
double weight;
TYPE_DESCRIPTOR((KEY(name, INDEXED), FIELD(weight)));
};
struct Supplier {
char const* company;
char const* address;
TYPE_DESCRIPTOR((KEY(company, INDEXED), FIELD(address)));
};
struct Shipment {
dbReference<Detail> detail;
dbReference<Supplier> supplier;
int4 price;
int4 quantity;
dbDateTime delivery;
TYPE_DESCRIPTOR((KEY(detail, HASHED), KEY(supplier, HASHED),
FIELD(price), FIELD(quantity), FIELD(delivery)));
};
</PRE>
We want to get information about delivery of some concrete details from some concrete
suppliers. In relational database this query will be written something like this:
<PRE>
select from Supplier,Shipment,Detail where
Supplier.SID = Shipment.SID and Shipment.DID = Detail.DID
and Supplier.company like ? and Supplier.address like ?
and Detail.name like ?
</PRE>
In FastDB this request should be written as:
<PRE>
dbQuery q = "detail.name like",name,"and supplier.company like",company,
"and supplier.address like",address,"order by price";
</PRE>
FastDB will first perform index search in the table <code>Detail</code> for details
matching the search condition. Then it performs another index search to locate shipment
records referencing selected details. Then sequential search is used to check the rest of
select predicate.
<P>
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -