乐趣区

关于后端:手把手教你PolarDBX中的表设计用户表

简介:本系列旨在形容一个具体的业务场景,给出建表的例子,帮忙大家更好的应用 PolarDB-X。本期的主题是:用户表。
本系列旨在形容一个具体的业务场景,给出建表的例子,帮忙大家更好的应用 PolarDB-X。本期的主题是:用户表。

需要形容
大多业务都会有一张用户表,用来存用户的数据,例如这样一张用户表:

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)
)
对这张表,个别会有以下几种业务操作:

● 注册,特点是要保障用户名、手机号、邮箱等惟一:

INSERT INTO users VALUES (?, ?, ?)
● 登录,当初大多数 APP 都反对手机号、邮箱地址、用户名等多个维度进行登录,所以会有多种类型的 SQL:

// 依照用户名(user_name)进行登录:
SELECT *
FROM users
WHERE user_name = ?;

// 依照手机号(mobile_phone)进行登录:
SELECT *
FROM users
WHERE mobile_phone = ?;

// 依照邮箱(email)进行登录:
SELECT *
FROM users
WHERE email = ?;
● 登录后,零碎内个别会应用用户 ID(user_id)查问或者更新用户信息:

SELECT *
FROM users
WHERE user_id = ?;

UPDATE users
SET xxxx = ?
WHERE user_id = ?;
对于这样的一张表,咱们在 PolarDB- X 中该如何设计呢?

这里咱们依据数据库的 MODE(PolarDB- X 中数据库的 MODE 参数:https://help.aliyun.com/docum…),给出两种示例:

DRDS 模式
在 DRDS 模式的数据库中,咱们须要设计表的分区键。

users 表的查问条件有 user_id、user_name、mobile_phone、email,这四种条件的查问的量都差不多,都属于在线类查问。对于传统的分库分表中间件来说,一个表的分区键只能抉择一个,那么无论抉择哪一个做分区键,对于其余三个条件的查问,都会是一场劫难。

PolarDB- X 反对全局索引(什么是全局索引:https://zhuanlan.zhihu.com/p/…),那这个问题就很好解决了,咱们依照上面语句建表即可:

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);
这样,咱们在 user_name、mobile_phone、email 上别离创立了三个全局惟一索引。对于上述的查问 SQL,每一种都会十分的高效。同时,也会保障注册场景下的唯一性。

当然,这些创立索引的语句也能够间接合并在建表语句中,相干语法参考:https://help.aliyun.com/docum…:

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);
此外,如果想进一步晋升查问的性能,防止全局索引回表的代价,还能够把全局索引创立为全局聚簇索引。这样会耗费更多的空间,但查问性能会更高。例如:

CREATE GLOBAL CLUSTERED UNIQUE INDEX gsi_clustered_users_user_name ON users (user_name) DBPARTITION BY HASH(user_name);
留神:上述用法对于 PolarDB-X 1.0(version >= 5.4.12)也同样实用。

AUTO 模式
对于 AUTO 模式,则无需关注分区键等信息,像在 MySQL 中建表即可:

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),
UNIQUE KEY uk_user_name(user_name),
UNIQUE KEY uk_mobile_phone(mobile_phone),
UNIQUE KEY uk_email(email)
);
同样的能达到和手动分区一样的成果。

咱们能够应用 EXPLAIN 语句来查看一下执行打算:

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)
能够看到,这个 SQL 会正确的应用索引来进行查问,而不会进行全表扫描。

测试环境
以上示例均在阿里云公共云 PolarDB-X 2.0 5.4.13-16462728 验证通过。

本文作者:梦实
本文起源:PolarDB-X 知乎号

原文链接:https://click.aliyun.com/m/10…

本文为阿里云原创内容,未经容许不得转载。

退出移动版