Translate
martes, 16 de julio de 2019
Collections en Apache Cassandra
Como casandra no permite joins es muy dificil mantener relaciones como lo hariamos en una base SQL normal, por ejemplo si queremos mantener datos de un usuario y sus emails, una forma de hacerlo sería crear columnas adicionales, como email2, email3, etc.
Si bien este es un enfoque que funcionará, no escala muy bien y puede causar muchos cambios. Es mucho más simple tratar con las direcciones de correo electrónico como grupo o "colección". Cassandra hereda los tipos de Java por lo tanto tenemos Listas, conjuntos y mapas. Echemos un vistazo a cada uno de ellos:
set : El tipo de datos de conjunto almacena una colección de elementos. Los elementos no están ordenados, pero cqlsh devuelve los elementos en orden ordenado. Por ejemplo, los valores de texto se devuelven en orden alfabético. Los conjuntos pueden contener los tipos simples que revisamos en el post anterior, así como los tipos definidos por el usuario e incluso otras colecciones. Una de las ventajas de usar set es la capacidad de insertar elementos adicionales sin tener que leer el contenido primero.
Veamos un ejemplo de agregar un set de emails a la tabla usuario :
cqlsh:my_keyspace> ALTER TABLE user ADD emails set<text>;
Luego agregaremos una dirección de correo electrónico para Mary y verificaremos que se haya agregado con éxito:
cqlsh:my_keyspace> UPDATE user SET emails = {'mary@example.com' } WHERE first_name = 'Mary';
cqlsh:my_keyspace> SELECT emails FROM user WHERE first_name ='Mary';
emails
----------------------
{'mary@example.com'}
(1 rows)
Tenga en cuenta que al agregar esa primera dirección de correo electrónico, reemplazamos el contenido anterior del conjunto, que en este caso era nulo. Podemos agregar otra dirección de correo electrónico más tarde sin reemplazar todo el conjunto mediante concatenación:
cqlsh:my_keyspace> UPDATE user SET emails = emails + { 'mary.mcdonald.AZ@gmail.com' } WHERE first_name = 'Mary';
cqlsh:my_keyspace> SELECT emails FROM user WHERE first_name = 'Mary';
emails
---------------------------------------------------
{'mary.mcdonald.AZ@gmail.com', 'mary@example.com'}
(1 rows)
list : El tipo de datos de lista contiene una lista ordenada de elementos. Por defecto, los valores se almacenan en orden de inserción (es decir por un indice). Modifiquemos nuestra tabla de usuarios para agregar una lista de números de teléfono:
cqlsh:my_keyspace> ALTER TABLE user ADD phone_numbers list<text>;
Luego agregaremos un número de teléfono para Mary y verificaremos que se haya agregado correctamente:
cqlsh:my_keyspace> UPDATE user SET phone_numbers = ['1-800-999-9999' ] WHERE first_name = 'Mary';
cqlsh:my_keyspace> SELECT phone_numbers FROM user WHEREfirst_name = 'Mary';
phone_numbers
--------------------
['1-800-999-9999']
(1 rows)
Agreguemos un segundo número añadiéndolo:
cqlsh:my_keyspace> UPDATE user SET phone_numbers = phone_numbers + [ '480-111-1111' ] WHERE first_name = 'Mary';
cqlsh:my_keyspace> SELECT phone_numbers FROM user WHERE first_name = 'Mary';
phone_numbers
------------------------------------
['1-800-999-9999', '480-111-1111']
(1 rows)
El segundo número que agregamos ahora aparece al final de la lista.
Podemos reemplazar un elemento individual en la lista cuando lo referenciamos por su índice:
cqlsh:my_keyspace> UPDATE user SET phone_numbers[1] = '480-111-1111' WHERE first_name = 'Mary';
Al igual que con los conjuntos, también podemos usar el operador de resta para eliminar elementos que coincidan con un valor específico:
cqlsh:my_keyspace> UPDATE user SET phone_numbers =phone_numbers - [ '480-111-1111' ] WHERE first_name = 'Mary';
Finalmente, podemos eliminar un elemento específico directamente usando su índice:
cqlsh:my_keyspace> DELETE phone_numbers[0] from user WHERE first_name = 'Mary';
map : El tipo de datos mapa contiene una colección de pares clave/valor. Las claves y los valores pueden ser de cualquier tipo excepto contador. Probemos esto utilizando un mapa para almacenar información sobre los inicios de sesión de los usuarios. Crearemos una columna para rastrear el tiempo de inicio de sesión en segundos, con un timeuuid como clave:
cqlsh:my_keyspace> ALTER TABLE user ADD login_sessions map<timeuuid, int>;
Luego agregaremos un par de sesiones de inicio de sesión para Mary y veremos los resultados:
cqlsh:my_keyspace> UPDATE user SET login_sessions = { now(): 13, now(): 18} WHERE first_name = 'Mary';
cqlsh:my_keyspace> SELECT login_sessions FROM user WHERE first_name = 'Mary';
login_sessions
-----------------------------------------------
{6061b850-14f8-11e5-899a-a9fac1d00bce: 13,
6061b851-14f8-11e5-899a-a9fac1d00bce: 18}
(1 rows)
También podemos hacer referencia a un elemento individual en el mapa usando su clave.
Los tipos de colección son muy útiles en los casos en que necesitamos almacenar un número variable de elementos dentro de una sola columna.