Data Model
Data is organized by TCStore into collections called datasets. Each Dataset is comprised of zero or more records. EachRecord has a key, unique within the dataset, and zero or more cells. Each Cell has a name, unique within the record; a declared type; and a non-null value. While records within a dataset must have a uniform key type, records are not required to have uniform content - each record may be comprised of cells having different names and/or different types. Each record and each cell is self-describing and is understood by the storage engine.
Figure 1. TCStore Data Storage Model - typed data.
Using popular/industry definitions, TCStore is an "Aggregate oriented, Key-Value NoSQL store". As noted above, the individual values stored within TCStore contain cells with type information enabling the store to make use of the data it holds. However, like other NoSQL stores, TCStore is schema-less in its core design, allowing individual entries to contain identical sets of cells, a subset of common cells, or a completely different sets of cells.
As such, and like other NoSQL stores, TCStore is not intended for usage patterns that are traditional to tabular data or RDBMSs. Data contained within TCStore are not and cannot be directly relational, and care should be taken to use modeling techniques (such as de-normalization of data) other than those commonly used with RDBMSs.
Type system
Fundamental to TCStore is the type system used in the data model.
The supported data types are:
BOOL: A boolean value (either true or false), mapping to
java.lang.Boolean; the
BOOL type is associated with cells of type
Cell<Boolean> and cell definitions of type
BoolCellDefinition and
CellDefinition<Boolean> BYTES: An array of bytes, signed 8-bit each, mapping to
byte[]; the
BYTES type is associated with cells of type
Cell<byte[]> and cell definitions of type
BytesCellDefinition and
CellDefinition<byte[]> CHAR: A single UTF-16 character, 16-bit unsigned, mapping to
java.lang.Character; the
CHAR type is associated with cells of type
Cell<Character> and cell definitions of type
CharCellDefinition and
CellDefinition<Character> DOUBLE: A 64-bit floating point value, mapping to
java.lang.Double; the
DOUBLE type is associated with cells of type
Cell<Double> and cell definitions of type
DoubleCellDefinition and
CellDefinition<Double> INT: A signed 32-bit integer value, mapping to
java.lang.Integer ; the
INT type is associated with cells of type
Cell<Integer> and cell definitions of type
IntCellDefinition and
CellDefinition<Integer> LONG: A signed 64-bit integer value, mapping to
java.lang.Long; the
LONG type is associated with cells of type
Cell<Long> and cell definitions of type
LongCellDefinition and
CellDefinition<Long> STRING: A variable length sequence of
CHAR, mapping to
java.lang.String; the
STRING type is associated with cells of type
Cell<String> and cell definitions of type
StringCellDefinition and
CellDefinition<String> The key of a Record may be an instance of any of the above types except BYTES. The value of a Cell may be an instance of any one of the above types.
Datasets
A Dataset is a (possibly distributed), collection of Record instances. Each Record instance is uniquely identified by a key within the Dataset. The key type is declared when the Dataset is created. Aside from the Record key type, a Dataset has no predefined schema.
Records
A Record is a key plus an unordered set of "name to (typed) value" pairs representing a natural aggregate of your domain model. Each Record within a Dataset can hold completely different sets of name/value pairs, as there is no schema to obey. Record instances held within a given Dataset are immutable. Changing one or multiple values on a Record creates a new instance of that Record which replaces the old instance.
Record represents the only atomically alterable type in TCStore. You can mutate as many Cell instances of a given Record instance as you wish as an atomic action, but atomic actions cannot encompass more than one record.
Cell definitions and values
A Record contains zero or more Cell instances, each derived from a CellDefinition. A CellDefinition is a "type/name" pair (e.g. String firstName). From a CellDefinition you can create a Cell (e.g. firstName = "Alex", where "Alex" is of type String) to store in a Record. The name of the Cell is the name from the CellDefinition used to create the cell; the value of the Cell is of the type specified in the CellDefinition used to create the cell.
Cell instances cannot contain null values but, since every Record in the dataset need not have uniform content, a Cell instance may be omitted from a Record for which that cell has no value. The API will then let you test a Record for the absence of that cell.
The Cell instances within a Record are unordered.