This lab focuses on Oracle’s NoSQL database system, KV(lite), which runs as a Java program, independently of OracleXE.
KVLite provides an API for Java application programs.
DOS> cd C:\kv-X.Y.Z DOS> java -jar lib/kvstore.jar kvlite
Notes:
-Xmx256m -Xms256m
ctrl-C
in the DOS command window.Copy the sample KVLite application (see code/13postrelational/HelloKVLite.java
)
into a new Intellij IDEA Java project (under cs342/13postrelational/Lab13
) and
add the KVLite library to the application build path, see:
C:\kv-X.Y.Z\lib\kvclient.jar
Run the program as a Java application.
Save this modified program for submission. Also, save answers to the following questions in a
notes.txt
file in the root of your project.
Compare and contrast the store.put()
command used here for KVLite and the
em.persist()
command you used for the GlassFish entity manager in the previous lab.
Compare and contrast the store.put()
command with the standard Java hashtable’s myHashTable.put()
command.
We now look a bit more deeply at keys and values, using both major and minor key paths. Relational records can be implemented in noSQL databases using either structured values (e.g., using Avro), which we’ll ignore, or multiple key-value pairs, which we’ll implement.
Build a new HelloRecords.java
application whose output is similar to the
following.
New movie record: /movie/92616/-/name : Dr. Strangelove /movie/92616/-/year : 1964 /movie/92616/-/rating : 8.7
To achieve this, follow the model shown in HelloKVLite.java
noting the
following.
Include the instantiation and closing of a store
entity.
Create/put a separate key-value pair for each field value in the Movie record (i.e.,
name, year and rating in the example above).
Note how the key structure shown in the
example bundles the field values of a record together using a common major key path
(i.e., /movie/$id/
) and heterogeneous minor key paths (i.e., /$fieldname
),
where the $
indicates a varying key path entry. The values are simple
strings.
You create the major and minor key paths as follows.
Key.createKey(Arrays.asList("movie", movieIdString), Arrays.asList(fieldName))
Here, the two arguments to createKey()
are ArrayLists of the major and
the minor paths. The result is an instance of Key
. In this case, the
“movie” is hard-coded in order to distinguish this key-value pair from
other key-value pairs for actors, directors, etc. All the key path elements are
strings. You can add more or less elements to each Arrays.asList()
element as required by your chosen key structure.
Remember to convert your value string into a byte array using
myValueString.getBytes()
.
Store this application so that you can upgrade it below. Also, save answers to the following questions in your
notes.txt
file.
Compare and contrast KVLite keys with relational database keys.
Note that because the create operations store the key-value pairs persistently in the KVstore,
you could separate this program into separate CreateRecords.java
and ReadRecords.java
applications. In this lab, continue to work with one file; in the homework, it will be more
convenient to split the functions into separate Java applications.
KVLite supports multi-valued gets of various kinds. For this exercise, modify your program
by refactoring the output code. Right now, it probably uses separate calls to
get()
, one for each field. Replace this with a single call to
multiget()
, configured as follows.
Key majorKeyPathOnly = Key.createKey(Arrays.asList("movie", movieIdString)); Map<Key, ValueVersion> fields = store.multiGet(majorKeyPathOnly, null, null); for (Map.Entry<Key, ValueVersion> field : fields.entrySet()) { String fieldName = field.getKey().getMinorPath().get(0); String fieldValue = new String(field.getValue().getValue().getValue()); System.out.println("\t" + fieldName + "\t: " + fieldValue); }
Note the following about this code segment.
multiGet()
retrieves a full-key-path-to-value map that contains entries for each key-value pair
sharing the given major key path. In the example output above, that’s the pairs
for each of movie 92616’s field values.
myKey.getMinorPath().get(keyPathIndex)
as shown. A similar function, getMajorPath()
, is also provided.
Save this upgraded version of the application. Also, add answers to the following in your notes.txt
file.
So far, the implementation has only dealt with records in one relational table, Movie. Explain how a key-value database might implement the one-to-many join relationships commonly implemented in relational databases using foreign keys.
KVLite requires that there be a key, but it is possible to have an “empty”
value. Such a value can be created using Value.createValue(new byte[0])
.
Where might one need such a construct?
KVLite supports several read operations: get()
, multiGet()
and
storeIterator()
.
This lab has introduced the first two. You’ll need the third as well for the homework.
We will grade your work according to the following criteria: