LindormTable le permite ejecutar consultas SQL directamente en tablas de HBase creadas con HBase Shell o la API de Java de ApsaraDB for HBase, sin necesidad de migrar datos. La asignación de columnas conecta el modelo de almacenamiento sin esquema de HBase con Lindorm SQL. De este modo, usted puede filtrar, indexar y consultar los datos existentes con sintaxis SQL estándar.
Requisitos previos
La versión del motor de tabla ancha debe ser 2.6.4 o posterior. Para obtener información sobre cómo consultar o actualizar la versión actual, consulte LindormTable release notes y Upgrade the minor engine version of a Lindorm instance.
Contexto
El motor de tabla ancha de Lindorm accede directamente a las tablas de datos que se crean con Lindorm Shell o la API de Java de HBase. Sin embargo, como HBase no utiliza esquemas, sus columnas se tratan como columnas dinámicas de tipo VARBINARY (Byte). Para obtener más información sobre las columnas dinámicas, consulte Dynamic columns. ApsaraDB for HBase proporciona la asignación de columnas de HBase y tipos compatibles con HBase. Esto le permite usar Lindorm SQL en las columnas escritas mediante la API de HBase y aprovechar los tipos de datos avanzados y los índices secundarios.
Sintaxis
En Lindorm SQL, usted puede agregar asignaciones a los calificadores de familias de columnas personalizadas de una tabla de HBase para facilitar las consultas SQL.
A continuación se muestra la sintaxis para agregar y eliminar asignaciones:
dynamic_column_mapping_statement := ALTER TABLE table_name MAP DYNAMIC COLUMN
qualifer_definition hbase_type;
dynamic_column_unmapping_statement := ALTER TABLE table_name UNMAP DYNAMIC COLUMN
qualifer_definition_list;
qualifer_definition_list := qualifer_definition
(',' qualifer_definition)*
qualifer_definition := [ family_name ':' ] qualifier_name
hbase_type := HLONG | HINTEGER | HSHORT | HFLOAT |
HDOUBLE | HSTRING | HBOOLEAN
En la siguiente tabla se describen los tipos de datos de asignación que hbase_type puede especificar:
|
Tipo de dato |
Tipo de Java correspondiente |
Descripción |
|
HLONG |
java.lang.Long |
Escribe una columna de HBase mediante el método Bytes.toBytes(long). |
|
HINTEGER |
java.lang.Integer |
Escribe una columna de HBase mediante el método Bytes.toBytes(int). |
|
HSHORT |
java.lang.Short |
Escribe una columna de HBase mediante el método Bytes.toBytes(short). |
|
HFLOAT |
java.lang.Float |
Escribe una columna de HBase mediante el método Bytes.toBytes(float). |
|
HDOUBLE |
java.lang.Double |
Escribe una columna de HBase mediante el método Bytes.toBytes(double). |
|
HSTRING |
java.lang.String |
Escribe una columna de HBase mediante el método Bytes.toBytes(String). |
|
HBOOLEAN |
java.lang.Boolean |
Escribe una columna de HBase mediante el método Bytes.toBytes(boolean). |
La versión 2.5.1 o posterior del motor de tabla ancha es compatible con la asignación para Rowkey. El método de asignación es el mismo que se usa para otros calificadores. El objeto de asignación debe ser ROW y esta palabra clave debe ir entre comillas invertidas (``).
Si utiliza otro lenguaje, consulte el método toBytes de la clase de Java org.apache.hadoop.hbase.util.Bytes para codificar los datos antes de escribirlos.
El método Bytes.toBytes(String) de Java utiliza la codificación UTF-8. Cuando use toBytes para convertir String a Bytes en otro lenguaje, también se requiere la codificación UTF-8.
Preparación de datos
En el siguiente ejemplo se utiliza la API de Java de HBase. Para obtener más información, consulte Use ApsaraDB for HBase API for Java to develop applications.
Para conocer otros métodos de creación de tablas y escritura de datos, consulte Connect to LindormTable with Lindorm Shell.
// Create the HBase sample table named "dt" with column family "f1"
try (Admin admin = connection.getAdmin()) {
HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("dt"));
htd.addFamily(new HColumnDescriptor(Bytes.toBytes("f1")));
admin.createTable(htd);
}
// Write data
try (Table table = connection.getTable(TableName.valueOf("dt"))) {
byte[] rowkey = Bytes.toBytes("row1");
byte[] family = Bytes.toBytes("f1");
Put put = new Put(rowkey);
// Write a String value, column name "name"
String name = "Some one";
put.addColumn(family, Bytes.toBytes("name"), Bytes.toBytes(name));
// Write an Int value, column name "age"
int age = 25;
put.addColumn(family, Bytes.toBytes("age"), Bytes.toBytes(age));
// Write a Long value, column name "time"
long timestamp = 1656675491000L;
put.addColumn(family, Bytes.toBytes("time"), Bytes.toBytes(timestamp));
// Write a Short value, column name "buycode"
short buycode = 123;
put.addColumn(family, Bytes.toBytes("buycode"), Bytes.toBytes(buycode));
// Write a Float value, column name "price"
float price = 12.3f;
put.addColumn(family, Bytes.toBytes("price"), Bytes.toBytes(price));
// Write a Double value, column name "price2"
double price2 = 12.33333;
put.addColumn(family, Bytes.toBytes("price2"), Bytes.toBytes(price2));
// Write a Boolean value, column name "isMale"
boolean isMale = true;
put.addColumn(family, Bytes.toBytes("isMale"), Bytes.toBytes(isMale));
// Write a null value. For all types, writing null is expressed as:
//put.addColumn(family, qualifier, null);
table.put(put);
}
Procedimiento
En el siguiente ejemplo se utiliza la tabla de muestra dt para explicar cómo acceder a una tabla de HBase mediante SQL.
-
Conéctese al motor de tabla ancha mediante Lindorm-cli. Para obtener más información, consulte Connect to and use the wide table engine with Lindorm-cli.
NotaSi utiliza SQL para acceder a una tabla de HBase en ApsaraDB for HBase Enhanced Edition, construya la dirección obtenida en la consola con el formato
jdbc:lindorm:table:url=http://Java API address obtained in the console. Cambie el puerto de 30020 a 30060.Por ejemplo, si la dirección de cadena de conexión obtenida en la consola es
ld-bp1ietqp4fby3****-proxy-hbaseue.hbaseue.rds.aliyuncs.com:30020, la dirección de cadena de conexión convertida serájdbc:lindorm:table:url=http://ld-bp1ietqp4fby3****-proxy-hbaseue.hbaseue.rds.aliyuncs.com:30060. -
Utilice la instrucción
ALTER TABLEpara agregar asignaciones de columnas a los datos escritos en la tabla dt.ALTER TABLE dt MAP DYNAMIC COLUMN `ROW` HSTRING, f1:name HSTRING, f1:age HINTEGER, f1:time HLONG, f1:buycode HSHORT, f1:price HFLOAT, f1:price2 HDOUBLE, f1:isMale HBOOLEAN;NotaAl agregar una asignación de columna se especifica el tipo de dato de la columna, independientemente de si se escriben datos.
El sistema decodifica el valor original de Bytes según el esquema. Por lo tanto, debe utilizar el tipo de dato correcto al asignarlo a Lindorm SQL.
En el siguiente ejemplo, si especifica el tipo de dato de la columna f:age2 como HINTEGER, el sistema llama al método Bytes.toInt() y devuelve un valor original incorrecto.
int age = 25; byte[] ageValue = Bytes.toBytes(age); put.addColumn(Bytes.toBytes("f"), Bytes.toBytes("age"), ageValue);// The data type of column f:age is INT, and it is mapped to HINTEGER in Lindorm SQL. String age2 = "25"; byte[] age2Value = Bytes.toBytes(age2); put.addColumn(Bytes.toBytes("f"), Bytes.toBytes("age2"), age2Value);// The data type of column f:age2 is STRING, and it is mapped to HSTRING in Lindorm SQL. -
Utilice la instrucción DESCRIBE para consultar las relaciones de asignación del esquema actual.
DESCRIBE dt;NotaPara obtener más información sobre la sintaxis de DESCRIBE TABLE, consulte DESCRIBE/SHOW/USE.
-
Consulte los datos de la tabla dt mediante una instrucción SQL.
SELECT * FROM dt LIMIT 1; SELECT * FROM dt WHERE f1:isMale=true LIMIT 1; SELECT * FROM dt WHERE f1:name='Some one' LIMIT 1; SELECT * FROM dt WHERE f1:time>1656675490000 and f1:time<1656675492000 LIMIT 1; -
(Opcional) Cree un índice secundario.
Un índice secundario intercambia espacio por tiempo. Mejora la eficiencia de consulta de los patrones que no usan claves primarias, pero ocupa algo de espacio de almacenamiento. Para obtener más información sobre la sintaxis y los límites de uso de los índices secundarios, consulte CREATE INDEX y Secondary indexes.
-
Modifique las propiedades de la tabla principal dt.
ALTER TABLE dt SET 'MUTABILITY' = 'MUTABLE_LATEST';NotaSi utiliza marcas de tiempo personalizadas, establezca la propiedad de la tabla principal en MUTABLE_ALL.
-
Cree el índice secundario:
CREATE INDEX idx ON dt(f1:age) WITH (INDEX_COVERED_TYPE ='COVERED_DYNAMIC_COLUMNS'); -
Opcional: Si la versión de su motor de tabla ancha es anterior a la 2.6.3 y utiliza el parámetro async (compilación asíncrona de índices) al crear un índice secundario, compile manualmente los datos históricos de la tabla principal en la tabla de índices. Una vez finalizada la compilación, podrá consultar los datos históricos mediante el índice secundario. Si no utilizó el parámetro async durante la creación, omita este paso.
BUILD INDEX idx ON dt; -
Consulte el índice.
SHOW INDEX FROM dt;Resultado:
+---------------+----------- -+-------------+--------------+------------------+---------------+-----------------+----------------+-------------+ | TABLE_SCHEMA | DATA_TABLE | INDEX_NAME | INDEX_STATE | INDEX_PROGRESS | INDEX_TYPE | INDEX_COVERED | INDEX_COLUMN | INDEX_TTL | +---------------+-------------+-------------+--------------+------------------+---------------+-----------------+----------------+-------------+ | default | dt | idx | ACTIVE | 100% | SECONDARY | TRUE | f1:age,ROW | | +---------------+-------------+-------------+--------------+------------------+---------------+-----------------+----------------+-------------+NotaCuando INDEX_STATE en el valor devuelto es Active, la compilación de datos ha finalizado.
PINDEX_PROGRESS en el valor devuelto indica el progreso de la compilación del índice.
-
Opcional: Utilice la instrucción EXPLAIN para consultar el plan de ejecución y comprobar si se usó un índice secundario.
EXPLAIN SELECT * FROM dt WHERE f1:age=23 LIMIT 1;
-
-
Opcional: Cree un índice de búsqueda.
-
Cree un índice de búsqueda.
CREATE INDEX search_idx USING SEARCH ON dt(f1:age,f1:name);NotaSi crea un índice de búsqueda en una tabla de HBase mediante SQL, tenga en cuenta los siguientes límites para cada columna del índice de búsqueda:
Todas las columnas del índice de búsqueda deben definirse en la asignación de columnas.
Los tipos de datos compatibles coinciden con los tipos de datos que se pueden asignar. Para obtener más información, consulte Mapping data types.
No es posible eliminar la asignación de una columna del índice de búsqueda. De lo contrario, los resultados de la consulta serán incorrectos.
Si utiliza marcas de tiempo personalizadas para escribir en la tabla de HBase y necesita crear un índice de búsqueda, debe establecer la propiedad MUTABILITY de la tabla en
MUTABLE_ALL.
-
Compruebe si el índice se creó correctamente.
SHOW INDEX FROM dt;Resultado:
+--------------+------------+------------+-------------+----------------+------------+---------------+----------------+-----------+-------------------+ | TABLE_SCHEMA | DATA_TABLE | INDEX_NAME | INDEX_STATE | INDEX_PROGRESS | INDEX_TYPE | INDEX_COVERED | INDEX_COLUMN | INDEX_TTL | INDEX_DESCRIPTION | +--------------+------------+------------+-------------+----------------+------------+---------------+----------------+-----------+-------------------+ | default | dt | idx | ACTIVE | DONE | SECONDARY | DYNAMIC | f1:age,ROW | | | | default | dt | search_idx | BUILDING | N/A | SEARCH | NA | f1:age,f1:name | 0 | | +--------------+------------+------------+-------------+----------------+------------+---------------+----------------+-----------+-------------------+
-
-
Opcional: Elimine las asignaciones de columnas.
-
Elimine una asignación de columna. A continuación se muestra un ejemplo:
ALTER TABLE dt UNMAP DYNAMIC COLUMN f1:isMale; -
Elimine varias asignaciones de columnas. A continuación se muestra un ejemplo:
ALTER TABLE dt UNMAP DYNAMIC COLUMN f1:price2, f1:price2;
-