UJCMS后端二次开发教程15-主键生成

2023-12-20 23:15 阅读

常用策略

自增主键

依赖数据库的功能,mysql、sqlserver有主键自增功能,oracle、db2则没有;postgresql可以将序列值设置成默认值,实现主键自增功能。

没有跨平台需求时,可以考虑使用。分库、分表时,不能使用。

数据库序列

依赖数据库的功能,mysql没有序列。

没有跨平台需求时,可以考虑使用。分表可以使用,分库不能使用。

UUID

不依赖数据库。通过程序产生一个32位的不重复的字符串。由于字符串过长且无序,作为主键容易影响数据库性能,一般不建议使用。

Table策略

使用一个单独的数据库表来记录其它表的主键值,模仿数据库序列的功能。

缺点是ID值和数据量容易被猜测(主键自增和数据库序列都有这个问题)。

数据量不是特别大的情况下,ID值可以设置为int,占用空间少,性能较好。

通用性好,可以跨平台。分表可以使用,分库不能使用。

雪花算法

使用一个长整型作为主键ID。最高1位是符号位(一般不用),41位用于存放时间戳(共69年),10位作为机器(共2014台机器),12位作为序列号(共4096个ID)。

ID无法被猜测,且隐藏了系统中数据量的大小。

适合分库、分表场合,是分布式系统的首选。即使不分表分库也是一个很好的选择。特别是数据量敏感或者ID需保密的表。

UJCMS的主键生成

UJCMS的主键使用Table策略,主键表为ujcms_seq

主键缓存

由于获取主键需要使用数据库锁,频繁获取主键性能较低,所以一次会获取多个主键。默认一次获取50个主键。配置文件为WEB-INF/classes/application.yaml(源码则为src/resources/application.yaml),配置项为ujcms.sequence-cache-size: 50

对于个别表需要单独调整主键缓存大小的,可以设置主键表ujcms_seqcache_size_字段。该字段为0则使用上述程序中的默认大小,如指定大于0的值,则以数据库的设定为准。

由于一次取出多个主键值,一旦程序重启,未使用的主键值将会浪费,导致数据库表里的ID值不连续。这是正常现象,不影响程序使用。

主键接口

com.ujcms.cms.core.service.SeqService

    /**
     * 获取下一个序列值
     *
     * @param name 序列名称。一般为表名。
     */
    public int getNextVal(final String name) {
        ...
    }

    /**
     * 获取下一个长整型序列值
     *
     * @param name 序列名称。一般为表名。
     */
    public long getNextLongVal(final String name) {
        ...
    }
咨询
交流群
电话