A. 雪花算法与Mysql自增的优缺点
雪花算法与Mysql自增的优缺点分别是:
雪花算法优点是:
1、不会重复。
2、有序,不会造成空间浪费和胡乱插入影响性能。
3、生成很快特别是比UUid快得多。
4、相比UUid更小。
缺点是:时间回拨造成错乱。
Mysql自增的优点是:
1、存储空间小。
2、插入和查询性能高。
缺点是:
1、int的范围可能不够大。
2、当要做数据迁移的时候,会很麻烦,主键容易冲突。
3、id自增,自身的业务增长情况很容易被别人掌握。
4、自增在高并发的情况下性能不好。
生成id的代码是:
自增和UUid差异的原因是:mysql数据库一般我们会采用支持事务的Innodb,在Innodb中,采用的是B+数索引。Innodb的存储结构,是聚簇索引。对于聚簇索引顺序主键和随机主键的对效率的影响很大。
自增是顺序主键存储,查找和插入都很方便(插入会按顺序插到前一个的后面),但UUid是无序的,通过计算获得的hashcode也会是无序的(是按照hashcode选择存储位置)。
所以对于他的查找效率很低,而且因为他是无序的,他的插入有可能会插到前面的数据中,会造成很多其他的操作,很影响性能或者很多存储空间因为没有顺序的存储而被空缺浪费。
B. 如何保证数据库集群中id的唯一性,假设每秒钟并发20万次
用雪花算法的工具类,1秒内可以生成26万不重复的值,数据库的主键不要自增,手动设置
java">packageentity;
importjava.lang.management.ManagementFactory;
importjava.net.InetAddress;
importjava.net.NetworkInterface;
/**
*<p>名称:IdWorker.java</p>
*<p>描述:分布式自增长ID</p>
*<pre>
*Twitter的SnowflakeJAVA实现方案
*</pre>
*核心代码为其IdWorker这个类实现,其原理结构如下,我分别用一个0表示一位,用—分割开部分的作用:
*1||0------00000---00000---000000000000
*在上面的字符串中,第一位为未使用(实际上也可作为long的符号位),接下来的41位为毫秒级时间,
*然后5位datacenter标识位,5位机器ID(并不算标识符,实际是为线程标识),
*然后12位该毫秒内的当前毫秒内的计数,加起来刚好64位,为一个Long型。
*这样的好处是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和机器ID作区分),
*并且效率较高,经测试,snowflake每秒能够产生26万ID左右,完全满足需要。
*<p>
*64位ID(42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加))
*
*@authorPolim
*/
publicclassIdWorker{
//时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)
privatefinalstaticlongtwepoch=1288834974657L;
//机器标识位数
=5L;
//数据中心标识位数
=5L;
//机器ID最大值
=-1L^(-1L<<workerIdBits);
//数据中心ID最大值
=-1L^(-1L<<datacenterIdBits);
//毫秒内自增位
=12L;
//机器ID偏左移12位
=sequenceBits;
//数据中心ID左移17位
=sequenceBits+workerIdBits;
//时间毫秒左移22位
=sequenceBits+workerIdBits+datacenterIdBits;
=-1L^(-1L<<sequenceBits);
/*上次生产id时间戳*/
=-1L;
//0,并发控制
privatelongsequence=0L;
privatefinallongworkerId;
//数据标识id部分
privatefinallongdatacenterId;
publicIdWorker(){
this.datacenterId=getDatacenterId(maxDatacenterId);
this.workerId=getMaxWorkerId(datacenterId,maxWorkerId);
}
/**
*@paramworkerId
*工作机器ID
*@paramdatacenterId
*序列号
*/
publicIdWorker(longworkerId,longdatacenterId){
if(workerId>maxWorkerId||workerId<0){
(String.format("workerIdcan'tbegreaterthan%dorlessthan0",maxWorkerId));
}
if(datacenterId>maxDatacenterId||datacenterId<0){
(String.format("datacenterIdcan'tbegreaterthan%dorlessthan0",maxDatacenterId));
}
this.workerId=workerId;
this.datacenterId=datacenterId;
}
/**
*获取下一个ID
*
*@return
*/
publicsynchronizedlongnextId(){
longtimestamp=timeGen();
if(timestamp<lastTimestamp){
thrownewRuntimeException(String.format("Clockmovedbackwards.Refusingtogenerateidfor%dmilliseconds",lastTimestamp-timestamp));
}
if(lastTimestamp==timestamp){
//当前毫秒内,则+1
sequence=(sequence+1)&sequenceMask;
if(sequence==0){
//当前毫秒内计数满了,则等待下一秒
timestamp=tilNextMillis(lastTimestamp);
}
}else{
sequence=0L;
}
lastTimestamp=timestamp;
//ID偏移组合生成最终的ID,并返回ID
longnextId=((timestamp-twepoch)<<timestampLeftShift)
|(datacenterId<<datacenterIdShift)
|(workerId<<workerIdShift)|sequence;
returnnextId;
}
privatelongtilNextMillis(finallonglastTimestamp){
longtimestamp=this.timeGen();
while(timestamp<=lastTimestamp){
timestamp=this.timeGen();
}
returntimestamp;
}
privatelongtimeGen(){
returnSystem.currentTimeMillis();
}
/**
*<p>
*获取maxWorkerId
*</p>
*/
(longdatacenterId,longmaxWorkerId){
StringBuffermpid=newStringBuffer();
mpid.append(datacenterId);
Stringname=ManagementFactory.getRuntimeMXBean().getName();
if(!name.isEmpty()){
/*
*GETjvmPid
*/
mpid.append(name.split("@")[0]);
}
/*
*MAC+PID的hashcode获取16个低位
*/
return(mpid.toString().hashCode()&0xffff)%(maxWorkerId+1);
}
/**
*<p>
*数据标识id部分
*</p>
*/
(longmaxDatacenterId){
longid=0L;
try{
InetAddressip=InetAddress.getLocalHost();
NetworkInterfacenetwork=NetworkInterface.getByInetAddress(ip);
if(network==null){
id=1L;
}else{
byte[]mac=network.getHardwareAddress();
id=((0x000000FF&(long)mac[mac.length-1])
|(0x0000FF00&(((long)mac[mac.length-2])<<8)))>>6;
id=id%(maxDatacenterId+1);
}
}catch(Exceptione){
System.out.println("getDatacenterId:"+e.getMessage());
}
returnid;
}
publicstaticvoidmain(String[]args){
//推特26万个不重复的ID
IdWorkeridWorker=newIdWorker(0,0);
for(inti=0;i<2600;i++){
System.out.println(idWorker.nextId());
}
}
}
C. 递归写Koch雪花的算法
这里有一个程序 希望可以帮到你 vb写的Koch雪花递归算法Const pi = 3.14159 Private Sub Form_Click() ScaleTop = 300 ScaleLeft = -75 ScaleWidth = 400 ScaleHeight = -300 Call fractal(50 + 30, 150, 110 + 30, 254, 1) Call fractal(110 + 30, 254, 170 + 30, 150, 1) Call fractal(170 + 30, 150, 50 + 30, 150, 1) End Sub Sub fractal(ax As Single, ay As Single, bx As Single, by As Single, s As Integer) If (bx - ax) * (bx - ax) + (by - ay) * (by - ay) < s Then Line (ax, ay)-(bx, by) Else Dim cx As Single, cy As Single Dim dx As Single, dy As Single Dim ex As Single, ey As Single Dim l As Single Dim alpha As Single cx = ax + (bx - ax) / 3 cy = ay + (by - ay) / 3 ex = bx - (bx - ax) / 3 ey = by - (by - ay) / 3 Call fractal(ax, ay, cx, cy, s) Call fractal(ex, ey, bx, by, s) l = Sqr((ex - cx) * (ex - cx) + (ey - cy) * (ey - cy)) alpha = Atn((ey - cy) / (ex - cx)) If (alpha >= 0 And (ex - cx) < 0) Or (alpha <= 0 And (ex - cx) < 0) Then alpha = alpha + pi End If dy = cy + Sin(alpha + pi / 3) * l dx = cx + Cos(alpha + pi / 3) * l Call fractal(cx, cy, dx, dy, s) Call fractal(dx, dy, ex, ey, s) End IfEnd Sub 祝你好运俄