在涉及数据库存储数据的时候,经常会遇到唯一值问题,有的是主键带来的限制,有的则是业务上的需要。
下面介绍几种唯一值的获取或者生产方法:
先建一个测试用的表tbl_user,有三个字段:Id、Name、Age,其中Id为主键。
drop table if exists `tbl_user`; create table `tbl_user` ( `Id` int(10), `Name` varchar(20), `Age` int(10), PRIMARY KEY (`Id`) )DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
插入几条数据
insert into tbl_user values (1000,"小猫",22); insert into tbl_user values (1001,"小狗",22); insert into tbl_user values (1002,"小刺猬",22);
查询结果:
1.由应用程序根据一定算法生成唯一值:一般采用”MD5(时间戳+随机数)“或者其他的UUID算法,基本也比较好实现。如果遇到多机器上分布的程序访问统一数据库的表,可以把Ip、网卡号等信息考进来就可以解决了(当然可以不是简单的拼接,你可以根据需要去合适的位数经过一定的算法去获取)。
2.先查询表中最大的值select max(id),再加1后作为新的值。很笨的方法。
select max(Id) from tbl_user; #查询到的最大Id为 1002,之后插入 1003 insert into tbl_user values (1003,"小熊",22);
此时表中数据为
3.如果是表级别的唯一,即在同一个表中某个字段唯一,可以把该字段设置为“自增(AUTO_INCREMENT)”的。这样你不必费心思去生成这个不能重复的唯一值了。但是一般应用程序是需要这个唯一值的,这个时候你就得在查询一次去获取刚才数据库自增生成的Id。比如在用户登录的时候,你要生成一个登录会话Id或者Token,这些程序一般是需要得到这个值而不是仅仅存在数据库中。生成的值,a.可以一般的select条件查询,根据条件查询刚才插入的数据。b.直接调用select @@IDENTITY 就可以得到上一次插入记录时自动产生的ID(注意是在数据库同一个连接(会话)中),用在插入后立即select @@IDENTITY。
看例子,先将表中的Id字段设置为自增,再插入一条数据(不要插入Id值,让数据库自增得到值),select @@IDENTITY查询,最后验证看看。
#1.#将Id改为自增(auto_increment) ALTER TABLE tbl_user CHANGE Id Id int not null auto_increment; #或者 先删除Id字段再添加一个Id字段 alter table tbl_user auto_increment=1000; alter table tbl_user drop column Id; alter table tbl_user add Id int not null auto_increment primary key first; #2.插入一条记录 insert tbl_user set Name='小猴',Age=23; #3.查询刚才的自增Id值 select @@IDENTITY; #值是1004
验证下:select * from tbl_user;得到的当前表记录为
过刚插入的数据“小猴”id为1004,和select @@IDENTITY;结果一样。
4.使用mysql的 UUID()函数。前面的自增字段(auto_increment)只能生成”表内”的唯一值,且需要搭配使其为”唯一的主键或唯一索引”,它的值是逐步增长的。这里的UUID产生的是字符串类型值,固定长度为:36个字符。UUID生成的是在时间、空间上都独一无二的值,是“随机+规则”组合而成。
select uuid(); -- c725d905-388e-11e6-9cab-b8ca3a6f5881 select uuid(); -- cb7d3894-388e-11e6-9cab-b8ca3a6f5881 select replace(uuid(),'-',''); -- eb1347a2388e11e69cabb8ca3a6f5881
可以看到,多次调用UUID()函数得到的值不相同,它由五部分组成,并且有连字符(-)隔开,一共36个字符。其中:
前3组值是时间戳换算过来的,解决“时间上唯一”;
第4组值是暂时性保持时间戳的唯一性,重启mysql才会变动;
第5组是mac值转过来的,有助于解决“空间上的唯一”,同一个机器多实例的一般相同。如果mac值获取不到,则是一个随机值。
这些已经可以保证得到的值在时间和空间上的唯一。当然你也可以去掉连字符: select replace(uuid(),'-','')。
在MySQL 5.1.*及更高版本有一个变种的UUID()函数,UUID_SHORT(),可以生成一个17-64位无符号的整数,注意是生成的一个整数,而前面UUID()生成的是字符串。MySQL启动后第一次执行的值是通过时间戳等初始化这个值,在本次运行中再次调用的时候都加1。这个值一般比较大,可以调用right(UUID_SHORT(),9)取后面的若干位。或者,你还可以写成自定义函数,来按需生成这个值。举个例子:
#1.调用uuid_short()函数
SELECT UUID_SHORT(); -- 17246045196806782976
SELECT UUID_SHORT(); -- 17246045196806782977
#执行两次得到的值递增的:
23285634974089217
#2.创建一个自定义函数,按需获取唯一值:
delimiter //
CREATE FUNCTION `GetUuidTest`(SysId int) RETURNS int(10) DETERMINISTIC
begin
declare tmpID int;
set tmpID = 0;
SELECT concat(SysId,right(UUID_SHORT(),8)) into tmpID;#SysId和UUID_SHORT()后8位数拼接得到
return tmpID;
end; //
#3.调用自定义的函数GetUuidTest(int)函数:
select GetUuidTest(1);
select GetUuidTest(1);
select GetUuidTest(2);
select GetUuidTest(2);
#得到结果:
#1+uuid_short()后8位(74089233)组成
#1+uuid_short()后8位(74089234)组成
#2+uuid_short()后8位(74089235)组成
#3+uuid_short()后8位(74089236)组成
#uuid_short()值递增,前面在加一个Id,不同的服务器IdSysId不同。
#4.在例子中调用自定义函数GetUuidTest(int) 来插入记录:这时候不需要把Id设置为自增了。
insert tbl_user set Id=GetUuidTest(1),Name='小熊猫',Age=22;
insert tbl_user set Id=GetUuidTest(2),Name='小鸭子',Age=21;
例子中,select * from tbl_user;得到的所有记录为例子中,select * from tbl_user;得到的所有记录为
相关推荐
MySQL 雪花算法生成唯一整型ID主键的实现主要针对大数据环境下,需要大量生成全局唯一ID的需求。雪花算法是一种分布式ID生成策略,由Twitter开源,其设计目标是在分布式系统中生成具有全局唯一性、有序性和高并发性...
MySQL全局ID生成方法是数据库设计中的一个重要议题,特别是在大规模分布式系统中,确保ID的全局唯一性和高并发下的高效生成是数据库架构的关键要素。以下是一些常见的全局ID生成策略: 1. **基于CAS(Check and Set...
分布式架构中的全局唯一序列号生成是一个关键问题,特别是在大规模并发的场景下,保证序列号的唯一性和高效生成是系统设计的重要考量。本文档主要对比分析了几种常见的解决方案,并结合携程的实践经验进行了深入探讨...
总结来说,Go-GoMySQL实现的ID生成服务是一个高效、可靠的解决方案,它利用Go语言的并发能力,结合MySQL的持久化特性,实现了分布式环境下的全局唯一ID生成。通过HTTP接口提供服务,易于与其他系统集成,同时通过...
每个事务都有一个全局唯一的GTID,简化了复制管理和故障恢复过程,无需手动跟踪二进制日志位置。 2. **半同步复制增强**: 半同步复制在MySQL 5.7中得到了进一步优化,确保在主库上的事务提交前,至少有一个从库已经...
文件中提到的server-id=1配置项,用于设置MySQL服务器的唯一标识符,这对于设置复制环境非常重要。在复制设置中,每个服务器必须有一个唯一的server-id值。 最后,为了配置和优化MySQL服务器,了解各个参数的作用和...
- `server_id=1`:全局唯一标识号,用于联合多个MySQL实例时的识别。 - `character-set-server=gbk`:服务器端默认字符集。 - `default-storage-engine=InnoDB`:默认存储引擎。 - `innodb-file-per-table=1`:...
然而,当数据被分散到多个表甚至是多个数据库中时,原有的自增ID机制就不再适用,因为它不能保证全局的唯一性和连续性。因此,如何设计一种高效的全局自增ID生成方案成为了一个重要的技术问题。 #### 方案调研与...
4. **启动失败**:查看MySQL的错误日志文件(如上述配置中的`/data/mysqldata/3307/mysql-error.log`),以获取更详细的错误信息。 #### 八、总结 通过上述步骤,我们成功地在一台服务器上安装了两个MySQL实例,并...
- UUID():生成全局唯一的128位标识符(UUID)。 - JSON_*() 函数:MySQL 5.6开始支持JSON数据类型,提供了JSON相关的处理函数。 在实际应用中,理解并熟练使用这些内置函数可以显著提高查询效率,简化代码,增强...
6. **GTID(Global Transaction Identifier)全局事务ID**:通过全局唯一的事务ID,简化了复制和故障恢复过程,提高了数据一致性。 7. **窗口函数(Window Functions)**:新增窗口函数,允许在一组相关的行上执行...
- **唯一索引**:索引列的值必须唯一。 - **全文索引**:用于全文搜索。 - **组合索引**:基于多个列构建的索引。 **4.5 索引的数据结构(B树,Hash)** - **B树索引**:适合范围查询。 - **哈希索引**:适合等值...
- 查询唯一值:`SELECT DISTINCT name FROM user;` - 排序查询:`SELECT name, id FROM user ORDER BY name;` 在 PHP 部分,你可以创建用户前端。PHP 脚本在服务器端执行,然后将结果以 HTML 格式呈现给浏览器。...
在编程领域,单例模式是一种常用的软件设计模式,它确保一个类只有一个实例,并提供一个全局访问点。在Qt框架中,结合Mysql数据库的操作,单例模式可以有效地管理数据库连接,避免资源浪费并保证数据操作的一致性。...
Snowflake是一种流行的全局ID生成策略,它能够生成64位的唯一ID,其中包含时间戳、机器ID和序列号等信息,保证了分布式环境下的ID唯一性。 数据迁移是分库分表过程中必不可少的一个环节。数据迁移通常需要考虑数据...
- 检索唯一值:使用DISTINCT关键字检索唯一不同的值。 - 限制输出:使用LIMIT来限制查询结果的数量。 - 注释:SQL注释用于解释SQL语句,以增加可读性。注释不能跨行。 3. ORDER BY排序: - 单列排序:通过ORDER...
通常,我们通过私有化构造函数来防止直接实例化,然后提供一个静态方法来获取这个唯一的实例。 ```php class MySQLSingleton { private static $instance; // 私有化构造函数 private function __construct() {...
- 主键生成策略应根据实际需求选择,例如,`GenerationType.IDENTITY`适用于自动递增的主键,而`GenerationType.UUID`则生成全局唯一的UUID。 7. **datasourceUtils**: - 压缩包中的`datasourceUtils`可能是一个...
key buffer是MySQL中用于缓存MyISAM表索引块的一个全局缓冲区。这意味着它能够提高查询速度,尤其是对于频繁访问的索引。需要注意的是,key buffer并不缓存所有存储引擎的表索引,仅限于MyISAM表。这一特性对于优化...