MySQL compatibility
ApsaraDB for SelectDB speaks the MySQL network protocol and supports most MySQL syntax. As an analytical, column-oriented database, SelectDB still differs from MySQL in data types, DDL, and DML behavior. This topic walks through these differences so you can migrate from MySQL or troubleshoot issues against the same baseline.
Data types
Numeric types
Type |
MySQL |
SelectDB |
Boolean |
|
|
Bit |
|
Not supported. Express the same intent with BOOLEAN or TINYINT. |
Tinyint |
|
|
Smallint |
|
|
Mediumint |
|
Not supported. Use INT instead. |
Int |
|
|
Bigint |
|
|
Largeint |
Not available. |
|
Decimal |
|
|
Float / Double |
Both signed and unsigned were valid before MySQL 8.0.17; unsigned has been deprecated in later versions. |
Signed only; no unsigned counterpart. |
Date and time types
Type |
MySQL |
SelectDB |
Date |
|
|
DateTime |
|
|
Timestamp |
|
Not supported. Use DATETIME instead. |
Time |
|
Not supported. Store the time portion in VARCHAR or extract it from a DATETIME column at query time. |
Year |
|
Not supported. Use SMALLINT or DATE instead. |
String types
Type |
MySQL |
SelectDB |
Char |
|
|
Varchar |
|
|
String |
No equivalent type. |
|
Binary / Varbinary |
Binary counterparts of CHAR / VARCHAR. |
Not supported. Use STRING instead. |
Blob / Text |
TinyBlob, Blob, MediumBlob, LongBlob plus the matching Text family. |
Not supported. Use STRING instead. |
Enum / Set |
|
Not supported. Constrain values yourself with VARCHAR or STRING. |
JSON data type
Both MySQL and SelectDB ship a native JSON type. You can store JSON documents directly and access fields with JSON functions.
SelectDB-specific data types
The following types are unique to SelectDB and target analytical workloads:
-
HLL(HyperLogLog): an approximate distinct-count type with about 1% error (occasionally up to 2%), well suited to ultra-large cardinality estimates. Cannot be a Key column. Must be used with the HLL_UNION aggregate and accessed via HLL_UNION_AGG, HLL_CARDINALITY, and similar functions. -
BITMAP: an exact distinct-count type that outperforms COUNT(DISTINCT). Cannot be a Key column. Must be used with the BITMAP_UNION aggregate and accessed via BITMAP_UNION_COUNT, BITMAP_HASH, and similar functions. -
QUANTILE_STATE: an approximate quantile type that switches to TDigest aggregation when value count exceeds 2,048. Cannot be a Key column. Must be used with the QUANTILE_UNION aggregate and accessed via QUANTILE_PERCENT, TO_QUANTILE_STATE, and similar functions. -
ARRAY<T>: an ordered collection of elements of type T. Cannot be a Key column. -
MAP<K, V>: a collection of key-value pairs of types K and V. Cannot be a Key column. -
STRUCT<field_name:field_type, ...>: a struct with a fixed set of named, always-Nullable fields. Cannot be a Key column. -
VARIANT: a semi-structured type that auto-detects its schema and is stored columnarly. Suited to logs and user-profile workloads where field shape evolves over time. -
AGG_STATE: holds an intermediate aggregation state. Requires the aggregate function signature to be declared at table creation; storage size depends on the implementation. Cannot be a Key column. Only usable with the STATE / MERGE / UNION combinators.
DDL syntax differences
CREATE TABLE
The overall SelectDB CREATE TABLE skeleton is:
CREATE TABLE [IF NOT EXISTS] [database.]table
(
column_definition_list
[, index_definition_list]
)
[engine_type]
[keys_type]
[table_comment]
[partition_info]
distribution_desc
[rollup_list]
[properties]
[extra_properties]
How each clause differs from MySQL:
Clause |
Difference |
column_definition_list |
|
index_definition_list |
|
engine_type |
|
keys_type |
|
table_comment |
Same usage as MySQL. |
partition_info |
|
distribution_desc |
|
rollup_list |
|
properties |
Property keys and values differ entirely from MySQL. They configure SelectDB-specific knobs such as replica count and storage policy. |
Full example:
CREATE TABLE demo.user_behavior (
user_id BIGINT,
item_id BIGINT,
behavior VARCHAR(20),
ts DATETIME
)
DUPLICATE KEY(user_id, item_id)
DISTRIBUTED BY HASH(user_id) BUCKETS 8
PROPERTIES ("replication_allocation" = "tag.location.default: 1");
CREATE INDEX
CREATE INDEX [IF NOT EXISTS] index_name ON table_name (column [, ...]) [USING BITMAP];
SelectDB supports three CREATE INDEX kinds: bitmap, inverted, and N-Gram. The Bloom filter index is configured through table PROPERTIES instead. The B+Tree and Hash indexes that MySQL relies on are unnecessary in SelectDB because the underlying columnar format already provides the equivalent filtering.
CREATE VIEW
Logical views behave like MySQL views. SelectDB additionally provides synchronous and asynchronous materialized views, which MySQL does not.
-- Logical view
CREATE VIEW [IF NOT EXISTS] [db_name.]view_name
(column1[ COMMENT "col comment"][, column2, ...])
AS query_stmt;
-- Asynchronous materialized view
CREATE MATERIALIZED VIEW [IF NOT EXISTS] mv_name
(col_defs)
[BUILD (IMMEDIATE | DEFERRED)]
[REFRESH [refresh_method] [refresh_trigger]]
[KEY (keys)]
[COMMENT "comment"]
[PARTITION BY (partition_key)]
[DISTRIBUTED BY {HASH(keys) | RANDOM} [BUCKETS num|AUTO]]
[PROPERTIES (...)]
AS query;
ALTER / DROP TABLE and INDEX
ALTER TABLE / ALTER INDEX and DROP TABLE / DROP INDEX behave close enough to MySQL that existing scripts can usually be reused. Be aware that SelectDB column changes go through Schema Change and run asynchronously; track progress with SHOW ALTER TABLE COLUMN before issuing follow-up writes or queries that depend on the new column.
DML syntax differences
INSERT
INSERT is MySQL-compatible and adds clauses for partition pinning, the WITH LABEL identifier, and execution-plan hints:
INSERT INTO table_name
[PARTITION (p1, ...)]
[WITH LABEL label]
[(column [, ...])]
[[hint [, ...]]]
{VALUES ({expression | DEFAULT} [, ...]) [, ...] | query};
UPDATE
UPDATE looks like MySQL's, but with two limitations:
A WHERE clause is mandatory; omitting it raises a syntax error.
Only Unique Key tables can be updated. For other models, use INSERT OVERWRITE or re-load the data.
UPDATE target_table [table_alias]
SET assignment_list
WHERE condition;
DELETE
DELETE is close to MySQL and offers two forms to match different data models:
-- Form 1: simple predicates only; works on any data model
DELETE FROM table_name [table_alias]
[PARTITION partition_name | PARTITIONS (partition_name [, ...])]
WHERE column_name op {value | value_list} [AND column_name op {value | value_list} ...];
-- Form 2: complex conditions and multi-table joins (USING); Unique Key tables only
DELETE FROM table_name [table_alias]
[PARTITION partition_name | PARTITIONS (partition_name [, ...])]
[USING additional_tables]
WHERE condition;
SelectDB is an analytical database and is not optimized for high-frequency single-row deletes. Maintain data through partition rotation or INSERT OVERWRITE batches whenever possible.
SELECT
SELECT is MySQL-compatible and adds Hint, EXCEPT column elimination, PARTITION/TABLET pinning, TABLESAMPLE, GROUPING SETS / ROLLUP / CUBE for multi-dimensional aggregation, and INTO OUTFILE:
SELECT
[hint_statement, ...]
[ALL | DISTINCT]
select_expr [, select_expr ...]
[EXCEPT (col_name1 [, col_name2, ...])]
[FROM table_references
[PARTITION partition_list]
[TABLET tabletid_list]
[TABLESAMPLE sample_value [ROWS | PERCENT] [REPEATABLE pos_seek]]]
[WHERE where_condition]
[GROUP BY [GROUPING SETS | ROLLUP | CUBE] {col_name | expr | position}]
[HAVING where_condition]
[ORDER BY {col_name | expr | position} [ASC | DESC], ...]
[LIMIT {[offset_count,] row_count | row_count OFFSET offset_count}]
[INTO OUTFILE 'file_name'];
SQL functions
Beyond covering most MySQL built-ins, SelectDB ships analytical extensions for BITMAP, HLL, ARRAY, MAP, and more. See the SelectDB function reference for the full inventory.
SQL Mode
Set a SQL Mode through SET sql_mode = 'MODE_NAME'. The most common modes are listed below.
Name |
When set |
When unset |
Notes |
|
|
|
- |
|
Backslashes inside string literals are taken literally and no longer trigger escape sequences. |
Backslashes inside string literals start an escape sequence. |
- |
|
Non-aggregated columns in SELECT must appear in GROUP BY, otherwise the query errors out. |
SELECT may return scalar columns that are not in the GROUP BY KEY. |
Available since 3.1.0. |