This series aims to describe a specific business scenario to help you learn how to use PolarDB-X more efficiently. Topic of this article: user table.
Most businesses have a user table to store user data. The following shows an example:
CREATE TABLE users (
user_id bigint AUTO_INCREMENT,
user_name varchar(64),
mobile_phone varchar(64),
email varchar(64),
enc_password varchar(256),
address varchar(128),
other_info1 varchar(128),
other_info2 varchar(128),
PRIMARY KEY (user_id)
)
For this table, the following business operations are generally performed:
INSERT INTO users VALUES (?, ?, ?)
//log in by user name (user_name):
SELECT *
FROM users
WHERE user_name = ?;
//log in by mobile phone (mobile_phone):
SELECT *
FROM users
WHERE mobile_phone = ?;
//log in by email (email):
SELECT *
FROM users
WHERE email = ?;
SELECT *
FROM users
WHERE user_id = ?;
UPDATE users
SET xxxx = ?
WHERE user_id = ?;
How should we design such a table in PolarDB-X?
Here are two examples based on the MODE (Databases in AUTO mode and DRDS mode) of the database:
In a DRDS mode database, we need to design the partition key of the table.
The user table has the following query conditions: user_id, user_name, mobile_phone, and email. All of the four conditions are online queries. For traditional database and table sharding middleware, only one partition key can be selected for a table. No matter which one is selected as the partition key, it will be a disaster for the other three query conditions.
PolarDB-X supports global index. Therefore, we can build a table according to the following statements to solve the problem:
CREATE DATABASE drds_test MODE='drds';
use drds_test;
CREATE TABLE users (
user_id bigint AUTO_INCREMENT,
user_name varchar(64),
mobile_phone varchar(64),
email varchar(64),
enc_password varchar(256),
address varchar(128),
other_info1 varchar(128),
other_info2 varchar(128),
PRIMARY KEY (user_id)
) DBPARTITION BY HASH(user_id);
CREATE GLOBAL UNIQUE INDEX gsi_users_user_name ON users (user_name) DBPARTITION BY HASH(user_name);
CREATE GLOBAL UNIQUE INDEX gsi_users_mobile_phone ON users (mobile_phone) DBPARTITION BY HASH(mobile_phone);
CREATE GLOBAL UNIQUE INDEX gsi_users_email ON users (email) DBPARTITION BY HASH(email);
We create three globally unique indexes on user_name, mobile_phone, and email. For the preceding query SQL, each index will be efficient. It also ensures the uniqueness in the registration scenario.
These index creation statements can also be directly merged into the table creation statements. For more information about the syntax, see CREATE INDEX (DRDS mode)
DROP TABLE users;
CREATE TABLE users (
user_id bigint AUTO_INCREMENT,
user_name varchar(64),
mobile_phone varchar(64),
email varchar(64),
enc_password varchar(256),
address varchar(128),
other_info1 varchar(128),
other_info2 varchar(128),
PRIMARY KEY (user_id),
UNIQUE GLOBAL KEY gsi_users_email (email) DBPARTITION BY HASH(email),
UNIQUE GLOBAL KEY gsi_users_mobile_phone (mobile_phone) DBPARTITION BY HASH(mobile_phone),
UNIQUE GLOBAL KEY gsi_users_user_name (user_name) DBPARTITION BY HASH(user_name)
) DBPARTITION BY hash(user_id);
In addition, if you want to further improve the query performance and avoid the cost of returning a global index to the table, you can also create a global index as a globally clustered index. It consumes more space, but the query can have performance. For example:
CREATE GLOBAL CLUSTERED UNIQUE INDEX gsi_clustered_users_user_name ON users (user_name) DBPARTITION BY HASH(user_name);
Note: The preceding use also applies to PolarDB-X 1.0 (version later than 5.4.12).
For AUTO mode:
CREATE DATABASE auto_test MODE='auto';
use auto_test;
CREATE TABLE users(
user_id bigint auto_increment,
user_name varchar(64),
mobile_phone varchar(64),
email varchar(64),
enc_password varchar(256),
address varchar(128),
other_info1 varchar(128),
other_info2 varchar(128),
PRIMARY KEY(user_id),
GLOBAL UNIQUE KEY uk_user_name(user_name) PARTITION BY HASH(user_name),
GLOBAL UNIQUE KEY uk_mobile_phone(mobile_phone) PARTITION BY HASH(mobile_phone),
GLOBAL UNIQUE KEY uk_email(email) PARTITION BY HASH(email)
)PARTITION BY HASH(user_id);
We can use the EXPLAIN statement to view the execution plan:
EXPLAIN SELECT * FROM users WHERE mobile_phone = 1;
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| LOGICAL EXECUTIONPLAN |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Project(user_id="user_id", user_name="user_name", mobile_phone="mobile_phone", email="email", enc_password="enc_password", address="address", other_info1="other_info1", other_info2="other_info2") |
| BKAJoin(condition="user_id = user_id", type="inner") |
| IndexScan(tables="uk_mobile_phone_$1ace[p16]", sql="SELECT `user_id`, `mobile_phone` FROM `uk_mobile_phone_$1ace` AS `uk_mobile_phone_$1ace` WHERE (`mobile_phone` = ?)") |
| Gather(concurrent=true) |
| LogicalView(tables="users[p1,p2,p3,...p16]", shardCount=16, sql="SELECT `user_id`, `user_name`, `email`, `enc_password`, `address`, `other_info1`, `other_info2` FROM `users` AS `users` WHERE ((`mobile_phone` = ?) AND (`user_id` IN (...)))") |
| HitCache:false |
| Source:PLAN_CACHE |
| TemplateId: beaaba3a |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
8 rows in set (0.32 sec)
As we can see, the SQL statement correctly uses indexes to query instead of scanning the full table.
The preceding examples are verified in Alibaba Cloud Public Cloud PolarDB-X 2.0 5.4.13-16462728.
New Features of PolarDB-X HTAP: Clustered Columnar Index (CCI)
PolarDB-X Best Practice Series (2): How to Implement Efficient Paged Queries
ApsaraDB - April 10, 2024
ApsaraDB - February 21, 2023
ApsaraDB - December 21, 2022
ApsaraDB - April 20, 2023
ApsaraDB - August 15, 2024
ApsaraDB - October 17, 2024
Follow our step-by-step best practices guides to build your own business case.
Learn MoreAlibaba Cloud PolarDB for Xscale (PolarDB-X) is a cloud-native high-performance distributed database service independently developed by Alibaba Cloud.
Learn MoreAlibaba Cloud PolarDB for PostgreSQL is an in-house relational database service 100% compatible with PostgreSQL and highly compatible with the Oracle syntax.
Learn MoreAlibaba Cloud PolarDB for MySQL is a cloud-native relational database service 100% compatible with MySQL.
Learn MoreMore Posts by ApsaraDB