Cete noun
A group of badgers.
Cete is an easy-to-use, lightweight, pure Go embedded database built on Badger for use in your Go programs. Unlike most other embedded database toolkits for Go, Cete is schemaless, yet still blazing fast. It's great for cases where you need a fast, on-disk, embedded database. Cete is licensed under the MIT License.
Cete is currently in alpha, it is somewhat unstable and NOT recommended for use in production yet. Breaking library changes may be released.
Here's a short example to show how easy it is to use the database:
package main
import (
"github.com/1lann/cete"
"fmt"
)
type Person struct {
Name string
Age int
}
func main() {
db, _ := cete.Open("./cete_data")
defer db.Close()
db.NewTable("people")
db.Table("people").Set("ash", Person{
Name: "Ash Ketchum",
Age: 10,
})
db.Table("people").NewIndex("Age")
var result Person
db.Table("people").Index("Age").One(10, &result)
fmt.Printf("People who are 10: %+v\n", result)
// Or if you just want simple key-value usage
db.Table("people").Get("ash", &result)
fmt.Printf("This is Ash: %+v\n", result)
}
I don't know if anyone uses Cete, but whatever.
I've recently made some breaking changes to how Range
works. It's now a more traditional cursor setup that allows for cleaner concise code, similar to bufio.Scanner
. Here's an example how you use it:
r := db.Table("people").All()
for r.Next() {
var result Person
r.Decode(&result)
fmt.Println("person is:", result)
fmt.Println("key is:", r.Key())
fmt.Println("counter is:", r.Counter())
fmt.Println("name (document demo) is:", r.Document().QueryString("Name"))
}
fmt.Println("final error:", r.Error()) // will typically return ErrEndOfRange
- Indexes.
- Compound indexes.
- Multi-indexes (tags).
- Transparent field name compression (i.e. document field names are mapped to smaller bytes when written to disk).
- All range queries are sorted (ascending by default).
- Uses a custom version of MessagePack as underlying storage structure.
- Efficient, concurrent range retrievers, filters, and index generation.
- Supports filtering.
- Lockless read/writes. Achieve safe updates with
Update
and counters. - Schemaless!
- Thread safe.
- Pure Go.
- Uses the fastest pure Go key-value store in the world 😉.
- When indexed, strings are case unsensitized using
strings.ToLower
. If you don't want this behavior, use a byte slice instead. - Indexing with numbers above maximum int64 is unsupported and will result in undefined behavior when using
Between
. Note that it's fine to index uint64, just values over max int64 (9,223,372,036,854,775,807) will result in issues when usingBetween
. - If your documents' keys have any of the following characters:
.,*
,Query
will not work on them. UseDecode
instead. - When working with compound indexes, you may use
MaxValue
andMinValue
as maximum integers or minimum integers of any size and float64s. This however cannot be be used for float32.
Find documentation on GoDoc.
Examples can be found on the wiki.
- Review performance, specifically
Between
on aRange
. - Write more examples.
I've performed some benchmarks comparing Cete to two other pure Go database wrappers, Storm and BoltHold. The source code for this benchmark can be found here.
For this test, Storm was running in batched write modes.
These benchmarks consists of simple sets and gets. However the gets were by secondary index instead of primary index, as is in a lot of real-world cases. If it were all by primary index, it will be more of a performance indicator of the underlying key-value store.
Cete is typically twice as fast as Storm for concurrent operations, and BoltHold was magnitudes slower than either. Cete is actually quite slow when it comes to sequential write operations (and isn't shown here), so it's strongly recommended to write concurrently. Cete also fairs similarly to Storm with sequential reads.
The index is skipped for that document! The document won't ever appear in the index. This also applies to compound indexes, if any of the queries for the compound index fails/results in nil, the document won't be indexed for that compound index.
No, Cete uses Badger v0.8.1, which does not support transactions. Cete itself is meant to be a very simple and basic abstraction layer of Badger.
For single document updates (such as incrementing a value), you can use the Update
method which constantly re-attempts the update until the counter matches, eradicating race conditions. Alternatively you can use the counter yourself and implement the logic to handle unmatched counters.
For more complex transactions, you'll need to implement your own solution. Although typically if you need more complex transactions you would be willing to sacrifice performance for an ACID compliant database. That being said if you need ACID compliance, I recommend you to use one of the great BoltDB wrappers that are available, such as Storm.
If you're desperate to use transactions with Cete, you can implement your own 2 phase commits.
On the upside, because there is no support for transactions, all read/writes are lockless, making it super fast!