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 祝你好運俄