前言
在本地数据库创建一条数据通常需要一个主键,这个主键必须要满足两个特性:不可变、唯一。由于技术总监要求,我的需求增加一条:长度为9的字符串。
不可变性:一旦数据创建,在任何情况下都不能改变。
唯一性:不能与其他数据的主键相同。在同一个数据库下保证唯一性只要需要通过一个自增的变量就可以完成,但是如果数据需要与其他数据库(比如服务器的数据库)交互,那么一这个简单的自增变量就无法达到。这个时候我们通常会引入时间戳。为保证唯一我们还可以加入随机数。
创建数据库主键值思路
为达到上面的三个要求,我的思路是这样的:5位字符串表示时间戳,2位表示自增值,2位随机值。(字符串由0-9,a-z,A-Z 组成(62进制))。
下面是具体步骤:
1、 将时间戳以10年一个轮回取余数,再转成62进制的字符串(5位);
2、定义一个静态变量用作累加,加到62*62回0,,再转成62进制的字符串(2位,不足补0);
3、生成两位的随机字符串(2位);
4、将上面三个字符串拼接起来就完成了;
具体代码
+(NSString *)creatID{
long long time = time_stamp().longLongValue;
time = time%3600*24*365*10;
NSString *timeStr = hex(time , 62);
NSString * subContString = [self createCountString];
NSString *result = [NSString stringWithFormat:@"%@%@%@",timeStr,subContString,randomString(2)];
//NSLog(@"id:%@",result);
return result;
}
//创建累加字符串
+(NSString *)createCountString{
staticnum += 1;
staticnum = staticnum%(62*62);
NSString *str = hex(staticnum , 62);
if (str.length == 2) {
return str;
}
if (str.length > 2) {
return [str substringFromIndex:str.length-2];
}
if (str.length < 2) {
return [@"0" stringByAppendingString:str];
}
return str;
}
//创建随机字符串
NSString *randomString(NSInteger lenth){
NSString *string = [[NSString alloc]init];
for (int i = 0; i < lenth; i++) {
int number = arc4random() % 36;
if (number < 10) {
int figure = arc4random() % 10;
NSString *tempString = [NSString stringWithFormat:@"%d", figure];
string = [string stringByAppendingString:tempString];
}else {
int figure = (arc4random() % 26) + 97;
char character = figure;
NSString *tempString = [NSString stringWithFormat:@"%c", character];
string = [string stringByAppendingString:tempString];
}
}
return string;
}
10进制数转为0-9 a-z A-Z字符串
NSString * hexChar(NSInteger num){
NSString *result = @"=";
if (num < 10) {
[NSString stringWithFormat:@"%ld",num];
}else if (num < 36) {
NSInteger figure = num - 10 + 65;
char character = figure;
NSString *tempString = [NSString stringWithFormat:@"%c", character];
return tempString;
}else if (num < 64) {
NSInteger figure = num - 36 + 97;
char character = figure;
NSString *tempString = [NSString stringWithFormat:@"%c", character];
return tempString;
}
return result;
}
//10进制数转任意进制字符串(此处为62进制)
NSString * hex(long long num ,NSInteger count){
NSString *result = @"";
while (num>0) {
NSInteger r = num % count;
result = [hexChar(r) stringByAppendingString:result];
num = num/count;
}
return result;
}
//获取时间戳
NSNumber * time_stamp(){
NSDate *senddate = [NSDate date];
NSString *date2 = [NSString stringWithFormat:@"%ld", (NSInteger)[senddate timeIntervalSince1970]];
return [NSNumber numberWithInteger:date2.integerValue];
}