Una base de datos NoSQL provee un mecanismo para el almacenamiento y el retorno de información que usa modelos de consistencia menores que bases de datos relacionales en orden de alcanzar escalabilidad horizontal y mayor disponibilidad. Alguns autores se refieren a ellas como "No solamente SQL" para enfatizar que algunos sistemas NoSQL permiten consultas similares a SQL.
Al ser el lenguaje C del siglo XXI, Go tiene soporte para bases de datos NoSQL, incluyendo populares como redis, mongoDB, Cassandra y Membase.
redis es un sistema de almacenamiento llave valor como Memcached, que soporta los tipos de cadenas, listas conjuntos y conjuntos ordenados.
Aquí están algunos de los manejadores de bases de datos para redis:
- https://github.com/garyburd/redigo
- https://github.com/go-redis/redis
- https://github.com/hoisie/redis
- https://github.com/alphazero/Go-Redis
- https://github.com/simonz05/godis
Let's see how to use the driver that redigo to operate on a database:
package main
import (
"fmt"
"github.com/garyburd/redigo/redis"
"os"
"os/signal"
"syscall"
"time"
)
var (
Pool *redis.Pool
)
func init() {
redisHost := ":6379"
Pool = newPool(redisHost)
close()
}
func newPool(server string) *redis.Pool {
return &redis.Pool{
MaxIdle: 3,
IdleTimeout: 240 * time.Second,
Dial: func() (redis.Conn, error) {
c, err := redis.Dial("tcp", server)
if err != nil {
return nil, err
}
return c, err
},
TestOnBorrow: func(c redis.Conn, t time.Time) error {
_, err := c.Do("PING")
return err
},
}
}
func close() {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
signal.Notify(c, syscall.SIGTERM)
signal.Notify(c, syscall.SIGKILL)
go func() {
<-c
Pool.Close()
os.Exit(0)
}()
}
func Get(key string) ([]byte, error) {
conn := Pool.Get()
defer conn.Close()
var data []byte
data, err := redis.Bytes(conn.Do("GET", key))
if err != nil {
return data, fmt.Errorf("error get key %s: %v", key, err)
}
return data, err
}
func main() {
test, err := Get("test")
fmt.Println(test, err)
}
Realicé una bifurcación de el último de estos paquetes, arreglé algunos servicios y lo usé en mi sistema de acortado de urls (2 millones de peticiones por día).
Veamos como usar el manejador que bifurqué para operar con la base de datos:
package main
import (
"github.com/astaxie/goredis"
"fmt"
)
func main() {
var client goredis.Client
// Definir el puerto por defecto de redis
client.Addr = "127.0.0.1:6379"
// Manipulación de cadenas
client.Set("a", []byte("hello"))
val, _ := client.Get("a")
fmt.Println(string(val))
client.Del("a")
// Operaciones con listas
vals := []string{"a", "b", "c", "d", "e"}
for _, v := range vals {
client.Rpush("l", []byte(v))
}
dbvals,_ := client.Lrange("l", 0, 4)
for i, v := range dbvals {
println(i,":",string(v))
}
client.Del("l")
}
Como podemos ver es muy sencillo operar redis en Go, y como tiene un alto rendimiento. Los comandos de este cliente son casi lo mismo que los comandos que vienen con redis.
mongoDB (de "humongous" (enorme)) es una bases de datos orientada a documentos de código abierto desarrollado y mantenida por 10gen. Hace parte de la familia de bases de datos NoSQL. En lugar de almacenar la información en tablas como es hecho en bases de datos relacionales 'clasicas', MongoDB guarda la información en estructurada en documentos al estilo JSON con esquemas dinámicos (MongoDB llama el formato BSON) haciendo que la integración de los datos en cierto tipo de aplicaciones sea mas fácil y rápido.
Figura 5.1 MongoDB comparada con Mysql
El mejor manejador para mongoDB es llamado mgo
, y es posible que se incluya en la librería estándar en el futuro.
Aquí está un ejemplo
package main
import (
"fmt"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
"log"
)
type Person struct {
Name string
Phone string
}
func main() {
session, err := mgo.Dial("server1.example.com,server2.example.com")
if err != nil {
panic(err)
}
defer session.Close()
// Optional. Switch the session to a monotonic behavior.
session.SetMode(mgo.Monotonic, true)
c := session.DB("test").C("people")
err = c.Insert(&Person{"Ale", "+55 53 8116 9639"},
&Person{"Cla", "+55 53 8402 8510"})
if err != nil {
log.Fatal(err)
}
result := Person{}
err = c.Find(bson.M{"name": "Ale"}).One(&result)
if err != nil {
log.Fatal(err)
}
fmt.Println("Phone:", result.Phone)
}
Como podemos ver no hay muchas diferencias en lo que respecta a operar con mgo o bases de datos beedb; ambas son basadas en estructuras. Esta es la manera en que Go hace las cosas.
- Índice
- Sección previa: Desarrollo de un ORM basado en beedb
- Siguiente sección: Resumen