属性

UUID

概述

数据类型UUID存储由RFC 4122、ISO/IEC 9834-8:2005以及相关标准定义的通用唯一标识符(UUID)。

UUID(Universally Unique Identifier)是一个128位长度的唯一标识符,它可以用来标识计算机系统中的实体。UUID的生成算法保证了它在全球范围内的唯一性,即使在不同的计算机系统和网络中也是如此。

UUID有多种版本,最常见的是基于时间戳的版本和随机数的版本。

基于时间戳的UUID使用当前的时间戳和计算机的MAC地址生成,确保在同一台计算机上生成的UUID具有唯一性,并且可以根据时间戳的顺序进行排序。

随机数的UUID则是完全随机生成的,不依赖于任何计算机特定的信息。这种UUID的唯一性是基于随机数生成算法的强大性能保证的。

UUID在很多领域得到广泛应用,比如数据库的主键、分布式系统中的节点标识、文件和目录的唯一标识等。由于其高度的唯一性和不可预测性,UUID在避免冲突和提高系统安全性方面有着重要的作用。

定义

UUID使用16进制表示,共有36个字符组成,格式为8-4-4-4-12。

示例:

xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
3ea70a2e-51c6-4c39-9c7a-87b55a3c2d3c
21457791-1d8f-44c2-9cf7-1f9df79518ba

作用

UUID的目的是让分布式系统中的所有元素都能有唯一的识别信息。如此一来,每个人都可以创建不与其它人冲突的UUID,就不需考虑数据库创建时的名称重复问题。其作用视场景而定。

首先,想象一下一张客户表。例如,我们不希望使用cust_namecust_addr作为唯一标识符之类的字段,因为可能有多个客户可能具有相同的姓名或共享相同的地址。然而,为每一行分配唯一的标识是个好办法;

其次,在建表过程中,无法使用有效的业务字段作为主键;

因此,建议用UUID来作为主键列。此函数生成的值保证是唯一的,并且在集群中分布良好。

UUID被广泛使用的部分原因是它们很可能在整个环境内是唯一的,这意味着我们的行的UUID不仅在我们的数据库表中是唯一的。

示例

要自动生成唯一的行标识符,使用UUID带有gen_random_uuid()函数的列作为默认值。

数据库,尤其是分布式数据库,具有内置的UUID生成。例如,在 Hubble中,我们建议使用UUID作为行标识符,这样做就像使用gen_random_uuid()函数一样简单

创建一张带有uuid的表

create table cust_info (
        id uuid not null DEFAULT gen_random_uuid(),
        city string not null,
        name string null,
        address string null,
        credit_card string null,
        CONSTRAINT "primary" PRIMARY KEY (city ASC, id ASC)
);

向表中插入数据

insert into cust_info (name, city) values ('liu dehua', 'beijing'), ('gao yuanyuan', 'shanghai'), ('zhen zidan', 'hk');
select * from cust_info;
                  id                  |   city   |     name     | address | credit_card
---------------------------------------+----------+--------------+---------+--------------
  3ea70a2e-51c6-4c39-9c7a-87b55a3c2d3c| beijing  | liu dehua    | NULL    | NULL
  95b1d540-eb0f-4c80-84d0-3bb576fd6487| hk       | zhen zidan   | NULL    | NULL
  21457791-1d8f-44c2-9cf7-1f9df79518ba| shanghai | gao yuanyuan | NULL    | NULL

序列

序列(SEQUENCE)是序列号生成器,可以为表中的行自动生成序列号,产生一组等间隔的数值(类型为数字);不占用磁盘空间,占用内存。

其主要用途是生成表的主键值,可以在插入语句中引用,也可以通过查询检查当前值,或使序列增至下一个值。

create sequence sequence_name
MINVALUE  1 
MAXVALUE  n 
INCREMENT 1 
START     1

1、INCREMENT用于定义序列的步长,如果省略,则默认为1。

2、START定义序列的初始值(即产生的第一个值),默认为1。

3、MAXVALUE定义序列生成器能产生的最大值。对于递减序列,最大值是-1。

4、MINVALUE定义序列生成器能产生的最小值。对于递增序列,最小值是1。

  • 创建SEQUENCE
CREATE SEQUENCE user_seq 
MINVALUE 1 
MAXVALUE 9223372036854775807 
INCREMENT 1 
START 1
show create user_seq;
table_name |    create_statement
-----------+------------------------------
userid_seq | CREATE SEQUENCE user_seq 
           | MINVALUE 1 
           | MAXVALUE 9223372036854775807 
           | INCREMENT 1 
           | START 1

建表时指定主键根据sequence自动增长

create table user_table(
  user_id int PRIMARY KEY DEFAULT nextval('user_seq'),
  phone_number string,
  create_date date
);

插入几条测试数据

insert into user_table (phone_number, create_date)
values
('13920163254','2012-11-21'),
('15122537891','2004-05-05'),
('18812680426','2018-10-20');
select * from user_table;
  user_id | phone_number | create_date
----------+--------------+--------------
        1 | 13920163254  | 2012-11-21
        2 | 15122537891  | 2004-05-05
        3 | 18812680426  | 2018-10-20

当数据被删除之后,仍然可以从删除的位置的序列值自增

truncate table user_table;
select * from user_table;
  user_id | phone_number | create_date
----------+--------------+--------------
(0 rows)
insert into user_table (phone_number, create_date)
                           values
                           ('13954775785','2017-09-23'),
                           ('13148934774','2012-11-24'),
                           ('18597548993','2014-08-13');
select * from user_table;
  user_id | phone_number | create_date
----------+--------------+--------------
        4 | 13954775785  | 2017-09-23
        5 | 13148934774  | 2012-11-24
        6 | 18597548993  | 2014-08-13
  • 查看序列的当前值

要查看当前值而不增加序列,请使用:

select * from user_seq;

使用SEQUENCE比使用内置函数gen_random_uuid()uuid_v4()unique_rowid()自动生成的唯一ID要慢。

unique_rowid()

如果生成的ID必须存储在相同的键值范围内,则可以使用整数类型使用unique_rowid()功能作为默认值

create table user_info (
        id int default unique_rowid(),
        city string not null,
        name string null,
        CONSTRAINT "primary" PRIMARY KEY (city asc, id asc),
        FAMILY "primary" (id, city, name)
);
insert into user_info (name, city) VALUES ('liudehua', 'HK'), ('huangxiaomimg', 'shanghai'), ('wanglikun', 'meimeng');
select * from user_info;
          id         |   city   |     name
---------------------+----------+----------------
  891846286839218177 | HK       | liudehua
  891846286839349249 | meimeng  | wanglikun
  891846286839316481 | shanghai | huangxiaomimg

三种属性值的比较

UUIDunique_rowid()序列
大小16字节8字节1至8字节
排序属性无序 高度有序高度有序
价值分配均匀分布(128位)包含时间和空间(节点ID)组件密集、小数值
数据位置最大分布近距离生成的值位于同一位置高度本地化
insert用作密钥时的延迟小,对并发不敏感小,但随着并发INSERT的增加而增加较高的
insert用作密钥时的吞吐量最高受1个节点上的最大吞吐量限制受1个节点上的最大吞吐量限制
用作密钥时的读取吞吐量最高(最大并行度)有限有限