Rdb: Ruby-Nachbau der MWC /rdb-Werkzeuge
This commit is contained in:
+426
@@ -0,0 +1,426 @@
|
||||
.TH search "" "" "/rdb Command"
|
||||
.PC "Search a table"
|
||||
\fBsearch [-m[bhirs]] [\-hsnx +x] [\-l [2> \fIlocation\fB]] \fItableorlist \fB[\fIkeycolumn ...\fB] [ < \fIkeytable\fB ]\fR
|
||||
.PP
|
||||
.II "row^find quickly"
|
||||
The command
|
||||
.B search
|
||||
finds a row quickly.
|
||||
It searches
|
||||
.I tableorlist
|
||||
for each row in which the value
|
||||
.I keycolumn
|
||||
matches one or keys you supply.
|
||||
The key or keys can either be entered interactively,
|
||||
or read from
|
||||
.IR keytable .
|
||||
You must use the
|
||||
.B /rdb
|
||||
command
|
||||
.B index
|
||||
to index
|
||||
.I tableorlist
|
||||
before you can use
|
||||
.B search
|
||||
to search it.
|
||||
.PP
|
||||
By default, a key's value must match exactly the string within
|
||||
.IR keycolumn .
|
||||
The options
|
||||
.B \-x
|
||||
and
|
||||
.B +x
|
||||
modify this behavior; they are described below.
|
||||
.PP
|
||||
You can use
|
||||
.B search
|
||||
in any of several different ways.
|
||||
Because it reads the key values from the standard input,
|
||||
you can input the keys by typing them interactively at the terminal,
|
||||
by diverting the contents of
|
||||
.I keytable
|
||||
into it,
|
||||
or by piping the output of a command into it.
|
||||
Each method is demonstrated in the examples given below.
|
||||
Therefore, it is easy to use
|
||||
.B search
|
||||
on a command line or in a shell script.
|
||||
For example, the command
|
||||
.B domain
|
||||
is a shell script that uses
|
||||
.B search
|
||||
to speed its searches.
|
||||
If you use a pipe to pass data to
|
||||
.BR search ,
|
||||
think of a stream of keys going into it
|
||||
and a stream of matching rows coming out.
|
||||
.PP
|
||||
.B search
|
||||
can use a number of different methods of searching.
|
||||
There are advantages and disadvantages to each;
|
||||
different sizes and structures of tables are best suited to different
|
||||
methods of searching.
|
||||
If you are not sure which method to use, you can try them all
|
||||
on your
|
||||
.IR tableorlist .
|
||||
Use the COHERENT command
|
||||
.B time
|
||||
to find how long each method takes, then pick the one that
|
||||
runs the fastest.
|
||||
Another
|
||||
.B /rdb
|
||||
command,
|
||||
.BR timesearch ,
|
||||
runs each form of
|
||||
.B search
|
||||
on the sample
|
||||
.BR unixtable ,
|
||||
which is kept in directory
|
||||
.BR $RDB/demo .
|
||||
Because
|
||||
.B timesearch
|
||||
is a shell script, you can modify it to time the different methods
|
||||
for your own file.
|
||||
.PP
|
||||
The behavior of
|
||||
.B search
|
||||
depends upon which method of searching you choose.
|
||||
With some methods, it first searches
|
||||
another table (called the ``secondary index file'')
|
||||
built by the command
|
||||
.BR index .
|
||||
One method, sequential, searches every row in
|
||||
.IR tableorlist .
|
||||
.PP
|
||||
If you change
|
||||
.IR tableorlist ,
|
||||
such as when you add a new row or delete an old one, you must reindex it.
|
||||
If you develop application programs, you can have them update
|
||||
secondary index files to handle dynamic file-processing.
|
||||
.SH "Methods of Searching"
|
||||
The following describes the different methods of searching a table.
|
||||
Each method is introduced by the command-line option with which
|
||||
you can invoke it:
|
||||
.IP \fB\-m\fR
|
||||
.II "search^sequential
|
||||
Perform a sequential search.
|
||||
This is the default method.
|
||||
.IP \fB\-mb\fR
|
||||
.II search^binary
|
||||
Binary search.
|
||||
This first looks at the middle record of the file.
|
||||
If the key column's value is greater than that of the key that
|
||||
.B search
|
||||
is seeking, then
|
||||
.B search
|
||||
look at the record one quarter of the way through the file.
|
||||
.B search
|
||||
continues to bifurcate the table until it finds the row, or finds
|
||||
that the row is not there.
|
||||
.sp \n(pDu
|
||||
The method of searching
|
||||
requires that you first sort the table on the key column.
|
||||
.sp \n(pDu
|
||||
A binary search takes log(2)\fIn\fR accesses:
|
||||
.DS
|
||||
.ta 1.0iC 2.5iC
|
||||
\fIAccesses No. of Records\fR
|
||||
10 1 thousand
|
||||
20 1 million
|
||||
30 1 billion
|
||||
40 1 trillion
|
||||
.DE
|
||||
.sp \n(pDu
|
||||
Binary searching is a good method for searching tables
|
||||
that must remain sorted on the key column.
|
||||
.IP \fB\-mh\fR
|
||||
.II search^hash
|
||||
Hash searching.
|
||||
A hash search computes an address from the key and
|
||||
looks into a secondary file at that address.
|
||||
If the key matches,
|
||||
it retrieves the address of the row you want in the main file and then
|
||||
retrieves it.
|
||||
If the address
|
||||
.B search
|
||||
hashes to is empty (i.e., has a value of zero),
|
||||
then the key does not match and the row is not in the file.
|
||||
.sp \n(pDu
|
||||
Occasionally, another key is there that happens to hash
|
||||
to the same address;
|
||||
this is called a
|
||||
.IR collision .
|
||||
When a collision occurs,
|
||||
.B search
|
||||
will keep looking at
|
||||
subsequent entries in the secondary table until
|
||||
it either finds a match or finds an empty or deleted (\-1) entry.
|
||||
.sp \n(pDu
|
||||
A hash search usually takes two disk accesses when the
|
||||
hash table is half full.
|
||||
For this reason,
|
||||
.B /rdb
|
||||
sets up hash tables that are twice as large as the number
|
||||
of records being hashed.
|
||||
As the data table grows, it must be reindexed to keep the hash speed up.
|
||||
.sp \n(pDu
|
||||
Hashing is a good method for tables that are static or change only rarely.
|
||||
.IP \fB\-mi\fR
|
||||
.II search^inverted
|
||||
.II search^indexed
|
||||
Inverted or indexed searching.
|
||||
An inverted search uses a secondary file that must have been created by
|
||||
.BR index .
|
||||
This index table has two columns:
|
||||
the key column from the data table, sorted to allow binary searching;
|
||||
and the offset of each key-column value within the data table.
|
||||
When
|
||||
.B search
|
||||
finds the key in the index table's key column, it then uses value from
|
||||
the address column to retrieve the row from the data table
|
||||
in a single disk read.
|
||||
The inverted method takes a little longer than binary,
|
||||
but sorting the index file is much faster than sorting the data table.
|
||||
.IP \fB\-mr\fR
|
||||
.II search^record
|
||||
Record number searching.
|
||||
A record search simply retrieves the row requested.
|
||||
For example, if you enter `5', you will get the fifth row in the data table.
|
||||
.sp \n(pDu
|
||||
To retrieve a record by its row number,
|
||||
.B search
|
||||
reads a secondary file that
|
||||
that contains the offset for each record in the data table.
|
||||
The record method is a faster way to retrieve a record;
|
||||
however, you must know the number of the record you want, and you must
|
||||
either keep the data table in that order, or reindex it.
|
||||
You can use the command
|
||||
.B replace
|
||||
to move a row to the of its table and update the secondary
|
||||
index to point to the row's new location.
|
||||
.IP \fB\-ms\fR
|
||||
.II search^sequential
|
||||
.II search^linear
|
||||
Sequential or linear searching.
|
||||
A sequential search examines all records in
|
||||
the data table in the order in which they appear.
|
||||
It is not a fast-access method, although it may
|
||||
still be faster than that used by the command
|
||||
.BR row .
|
||||
It is provided as a benchmark for timing other methods.
|
||||
If your file is not big enough to
|
||||
make the other access methods worthwhile, just use sequential
|
||||
.B search
|
||||
or
|
||||
.B row
|
||||
and save yourself the overhead of building and maintaining an index.
|
||||
.sp \n(pDu
|
||||
A sequential search can search multiple key columns, and and can search
|
||||
any column.
|
||||
.II grep
|
||||
The sequential method is better than the COHERENT command
|
||||
.B grep
|
||||
because it looks at one column, whereas
|
||||
.B grep
|
||||
scans the entire row for a pattern match.
|
||||
.SH "Other Options"
|
||||
.B search
|
||||
also recognizes the following command-line options:
|
||||
.IP \fB\-h\fR
|
||||
Do not print the table's head line.
|
||||
By default,
|
||||
.B search
|
||||
prints the head line of the table it searches as well as all rows it finds.
|
||||
The \fB\-h\fR option suppresses the printing of the head line
|
||||
and prints only the rows you are seeking.
|
||||
.IP \fB\-l\fR
|
||||
Output the location of the record in the data table
|
||||
and the location of the index record in the index table.
|
||||
.II replace
|
||||
.II lock
|
||||
.II unlock
|
||||
These locations is in the form
|
||||
.IR from to xfrom xto" ,
|
||||
and can be piped to the commands
|
||||
.BR replace ,
|
||||
.BR lock ,
|
||||
and
|
||||
.BR unlock .
|
||||
.B search
|
||||
writes these data to the standard-error device,
|
||||
to separate them from the table it writes to the standard output.
|
||||
.sp \n(pDu
|
||||
Because
|
||||
.B search
|
||||
is a shell program, it demonstrates how you can do this in your own programs.
|
||||
Turning on this option also turns on the
|
||||
.B \-s
|
||||
option because
|
||||
.B /rdb
|
||||
allows you to lock or replace one record at a time.
|
||||
Therefore, all keys in your file must be unique, or
|
||||
some will never be found.
|
||||
.IP \fB\-s\fR
|
||||
Search for only one row.
|
||||
This speeds the search because
|
||||
.B search
|
||||
quits when it finds the first match and continue searching the file.
|
||||
.IP \fB\-x\fR
|
||||
Partial match and case insensitive, like the Berkeley command \fBlook\fR.
|
||||
.IP \fB+x\fR
|
||||
Exact match, including blank characters.
|
||||
The default matching ignores blank characters.
|
||||
.SH Examples
|
||||
Assume you have a file called
|
||||
.BR inventory ,
|
||||
which appears as follows:
|
||||
.DM
|
||||
Item Amount Cost Value Description
|
||||
---- ------ ---- ----- --------------
|
||||
1 3 50 150 rubber gloves
|
||||
2 100 5 500 test tubes
|
||||
3 5 80 400 clamps
|
||||
4 23 19 437 plates
|
||||
5 99 24 2376 cleaning cloth
|
||||
6 89 147 13083 bunsen burners
|
||||
7 5 175 875 scales
|
||||
.DE
|
||||
.PP
|
||||
If you had indexed the column
|
||||
.BR Description ,
|
||||
then you have several ways to find rows:
|
||||
.IP \fB1.\fR 0.3i
|
||||
Interactively type key values.
|
||||
.B search
|
||||
immediately prints the rows it finds.
|
||||
For example, type:
|
||||
.DM
|
||||
search -mh inventory Description
|
||||
.DE
|
||||
.sp \n(pDu
|
||||
.B search
|
||||
responds with the head line of the inventory table.
|
||||
Now you can type names, in this example
|
||||
.BR scales ;
|
||||
if
|
||||
.B search
|
||||
finds a match, it returns the row that contains the key.
|
||||
.IP \fB2.\fR
|
||||
Divert a table or list file to
|
||||
.BR search .
|
||||
You can create a table with a column of key values; for example:
|
||||
.DM
|
||||
Description
|
||||
-----------
|
||||
scales
|
||||
clamps
|
||||
.DE
|
||||
.sp \n(pDu
|
||||
The following command line diverts this table into
|
||||
.B search
|
||||
.DM
|
||||
search -mh inventory Description < description
|
||||
.DE
|
||||
.sp \n(pDu
|
||||
and produces the following output:
|
||||
.DM
|
||||
Item Amount Cost Value Description
|
||||
---- ------ ---- ----- --------------
|
||||
7 5 175 875 scales
|
||||
3 5 80 400 clamps
|
||||
.DE
|
||||
.IP \fB3.\fR
|
||||
Input keys through a COHERENT pipe.
|
||||
For example, the command
|
||||
.DM
|
||||
column Description < sometable | search -mh inventory | column Value
|
||||
.DE
|
||||
.sp \n(pDu
|
||||
returns the following:
|
||||
.DM
|
||||
Value
|
||||
-----
|
||||
875
|
||||
400
|
||||
.DE
|
||||
.sp \n(pDu
|
||||
If you wish to justify a table like this, just pipe the output of
|
||||
.B search
|
||||
to the command
|
||||
.BR justify .
|
||||
.sp \n(pDu
|
||||
This lets you use the COHERENT command
|
||||
.B echo
|
||||
to pipe a key value:
|
||||
.DM
|
||||
echo scales | search -mh inventory Description
|
||||
.DE
|
||||
.sp \n(pDu
|
||||
which returns the following to the standard output:
|
||||
.DM
|
||||
Item Amount Cost Value Description
|
||||
---- ------ ---- ----- --------------
|
||||
7 5 175 875 scales
|
||||
.DE
|
||||
.PP
|
||||
In shell programming, you can capture the output of a program
|
||||
or a pipe by putting it within two grave (`) symbols.
|
||||
In a shell script, you can set an environmental variable like this:
|
||||
.DM
|
||||
RECORD=`echo key | search -mh -h bigtable column`
|
||||
.DE
|
||||
.PP
|
||||
The command
|
||||
.B "echo $RECORD"
|
||||
displays the data diverted into this variable; for example:
|
||||
.DM
|
||||
7 5 175 875 scales
|
||||
.DE
|
||||
.PP
|
||||
Now the
|
||||
.B RECORD
|
||||
environmental variable is equal to the matching row in the table.
|
||||
Note the
|
||||
.B \-h
|
||||
is important to keep the head line from being written into
|
||||
.BR RECORD .
|
||||
.SH "Search vs. Select"
|
||||
.B search
|
||||
is important for application programs written in
|
||||
shell scripts, the C programming language, or other code.
|
||||
It can be used interactively, but the command
|
||||
.B row
|
||||
is much more powerful because it can seek combinations of logical conditions,
|
||||
regular expressions, and conditions such as
|
||||
.I "greater than,"
|
||||
whereas
|
||||
.B search
|
||||
needs a key (either exact or partial).
|
||||
But for pulling a row out of a big table,
|
||||
.B search
|
||||
can speed things up enough to be preferred.
|
||||
In summary,
|
||||
.B search
|
||||
is for high-speed access with keys, whereas
|
||||
.B row
|
||||
should be used to retrieve rows that match complex logical conditions
|
||||
and regular expressions.
|
||||
.SH "See Also"
|
||||
.B
|
||||
append,
|
||||
column,
|
||||
delete,
|
||||
index,
|
||||
replace,
|
||||
row,
|
||||
seek,
|
||||
update
|
||||
.R
|
||||
.br
|
||||
COHERENT Lexicon:
|
||||
.B
|
||||
egrep,
|
||||
grep,
|
||||
look,
|
||||
time
|
||||
.R
|
||||
Reference in New Issue
Block a user