After interviewing library series points table with 38 points, how to deal with id primary key?

(1) from the database by id

 

This means that every time your system to get an id, is to insert a table in a library of a little business meaning of the data, and then get an id increment of a database. Then go down to get the id corresponding to the sub-sub-library table write go.

 

The advantage of this scheme is convenient and simple, and who will use; drawback is that a single library generation increment id, if the high concurrency, then there will be a bottleneck; if you simply want to improve the look, then and opened a service out of this service every times to get the maximum current id, and then himself several increments id, id number of one-time return, and then modify the current maximum id value to a value after the increment several id; but no matter how hard are based on a single database .

 

Appropriate scene: you sub-library sub-table on two reasons, either the single database concurrency is too high, or else a single library data is too big; unless you concurrency is not high, but the amount of data is too large to sub-library sub-table expansion, you can use this program, because it may be complicated by the highest per second up to a few hundred, then left alone to generate a library and table auto-increment primary key.

 

Concurrency is very low, a few hundred / s, but the large amount of data, billions of data, you need to rely on sub-library sub-table to store vast amounts of data

 

(2)uuid

 

Benefit is locally generated, based on the database do not come; a bad place is, uuid too long, as the primary key performance bad, not suitable for the primary key.

 

Appropriate scene: If you are what you want to randomly generated file name, the number and the like, you can use uuid, but can not be used as a primary key uuid's.

 

UUID.randomUUID().toString().replace(“-”, “”) -> sfsdf23423rr234sfdaf

 

(3) to obtain the current system time

 

This is to get the current time, but the problem is that when high concurrency, such as one second concurrent thousands, there will be repeat of the situation, this is certainly not appropriate. Basic would not have considered.

 

Appropriate scene: If you use this program in general, is the current time with many other business fields spliced ​​together, as a id, if the business you think is acceptable, is also possible. You can level business field values ​​with the current time spliced ​​together to form a globally unique serial number, order number, time stamp, user id + + coding business meaning

 

(4) snowflake algorithm

 

twitter id open distributed generation algorithm, the long type id is a 64-bit, 1 bit is not used, bit 41 is used therein as a few milliseconds, with a working machine id 10 bit, bit 12 is a sequence number

 

1 bit: do not, so why then? Because the binary in the first bit is 1 if it is, then it is negative, but we generate id are positive, so the first bit is 0 Uniform

 

41 bit: it indicates that the timestamp milliseconds. 41 bit numbers can be represented by up to 2 ^ 41--1, i.e. 2 ^ may identify 41--1 millisecond values, expressed in terms of the adult, 69 years.

 

10 bit: recording work machine id, represents the service can be deployed on up to 2 ^ 10 machines which, namely 1024 machine. But in the five bit 10 bit behalf room id, 5 Ge bit on behalf of the machine id. Means that up to 2 ^ 5 Representative room (room 32), and each may represent a room where the machine 2 ^ 5 (32 machine).

 

12 bit: This is used to record with a different id generated within milliseconds, the maximum 12 bit may represent a positive integer of 2 ^ 12--1 = 4096, i.e. this number can be used to distinguish the same 12bit represented a millisecond 4096 different id

 

long-type 64-bit ID, a 64-bit long -> Binary

 

0 | 0001100 10100010 10111110 10001001 01011100 00 | 10001 | 1 1001 | 0000 00000000

 

2018-01-01 10:00:00 -> done some calculations, and then converted into a binary, 41bit to put -> 0001100 1,010,001,010,111,110 1,000,100,101,011,100 00

 

Room id, 17 -> converted into a binary -> 10001

 

Machine id, 25 -> converted into a binary -> 11001

 

snowflake algorithms service, will determine what, if the current request is the engine room 17 of the machine 25, the first request sent by the 2175/11/7 12:12:14 point in time, if it is the first request

 

Assume, at 2175/11/7 12:12:14 time, 17 of the machine room 25, sent a second message, snowflake algorithms services, will find the machine room 17 of the 25 said, in 2175/11/7 12: 12:14 time in the milliseconds before been generated over a id, at this time if you the same room, the same machine, in the same millisecond, again generate a required id, at this time I can only add 1

 

0 | 0001100 10100010 10111110 10001001 01011100 00 | 10001 | 1 1001 | 0000 00000001

 

 

For example, we observe that the above is a typical 64-bit id binary, decimal is converted into 910499571847892992.

 

public class IdWorker{

 

    private long workerId;

    private long datacenterId;

    private long sequence;

 

    public IdWorker(long workerId, long datacenterId, long sequence){

        // sanity check for workerId

// here not to check a bit, requires that you passed in the engine room and machine id id can not be more than 32, not less than 0

        if (workerId > maxWorkerId || workerId < 0) {

            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0",maxWorkerId));

        }

        if (datacenterId > maxDatacenterId || datacenterId < 0) {

            throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0",maxDatacenterId));

        }

        System.out.printf("worker starting. timestamp left shift %d, datacenter id bits %d, worker id bits %d, sequence bits %d, workerid %d",

                timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits, workerId);

 

        this.workerId = workerId;

        this.datacenterId = datacenterId;

        this.sequence = sequence;

    }

 

    private long twepoch = 1288834974657L;

 

    private long workerIdBits = 5L;

    private long datacenterIdBits = 5L;

    private long maxWorkerId = -1L ^ (-1L << workerIdBits); // this is a binary operation, only 5 bit is up to 31 digits, that is to say within the machine id is at most 32

    // This is within a meaning, is 5 bit can only have up to 31 digits, only up to room id 32; private long maxDatacenterId = -1L ^ (-1L << datacenterIdBits)

    private long sequenceBits = 12L;

 

    private long workerIdShift = sequenceBits;

    private long datacenterIdShift = sequenceBits + workerIdBits;

    private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;

    private long sequenceMask = -1L ^ (-1L << sequenceBits);

 

    private long lastTimestamp = -1L;

 

    public long getWorkerId(){

        return workerId;

    }

 

    public long getDatacenterId(){

        return datacenterId;

    }

 

    public long getTimestamp(){

        return System.currentTimeMillis();

    }

 

public synchronized long nextId() {

// here is to get the current timestamp in milliseconds

        long timestamp = timeGen();

 

        if (timestamp < lastTimestamp) {

            System.err.printf("clock is moving backwards.  Rejecting requests until %d.", lastTimestamp);

            throw new RuntimeException(String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds",

                    lastTimestamp - timestamp));

        }

 

// 0

// in the same millisecond, and sends a request to generate a id, 0 -> 1

 

        if (lastTimestamp == timestamp) {

            sequence = (sequence + 1) & sequenceMask; // This means that within a millisecond can only have up to 4096 numbers, no matter how much you passed in, this place is always guarantee operation in 4096 this range, you avoid a transfer this sequence of more than 4096 range

            if (sequence == 0) {

                timestamp = tilNextMillis(lastTimestamp);

            }

        } else {

            sequence = 0;

        }

 

// Here the record about the latest id generated timestamp in milliseconds

        lastTimestamp = timestamp;

 

// here is to stamp left, there into 41 bit; id left into the room where 5 bit; id left into the machine where 5 bit; the last sequence number placed 10 bit; up to a final spliced 64 bit binary number, 10 decimal is converted into a long type

        return ((timestamp - twepoch) << timestampLeftShift) |

                (datacenterId << datacenterIdShift) |

                (workerId << workerIdShift) |

                sequence;

    }

 

0 | 0001100 10100010 10111110 10001001 01011100 00 | 10001 | 1 1001 | 0000 00000000

 

 

    private long tilNextMillis(long lastTimestamp) {

        long timestamp = timeGen();

        while (timestamp <= lastTimestamp) {

            timestamp = timeGen();

        }

        return timestamp;

    }

 

    private long timeGen(){

        return System.currentTimeMillis();

    }

 

    //---------------test---------------

    public static void main(String[] args) {

        IdWorker worker = new IdWorker(1,1,1);

        for (int i = 0; i < 30; i++) {

            System.out.println(worker.nextId());

        }

    }

 

}

 

How do you say, about the meaning of it, that is 41 bit, is a current timestamp in milliseconds, it is this sense; then 5 bit is that you passed in a room id (but only within maximum 32), 5 bit your machine is passed in id (but only within maximum 32), the rest of the 10 bit serial number, that is, if you follow the previous generation are still within a millisecond id of time, then the order will give you accumulate, up to less than 4096 numbers.

 

So you take advantage of the tools that he engaged in a service, then for each machine in each room are initialized such a thing, the beginning of the serial number of the machine room is 0. Then each time it receives a request, saying that the machine room to generate a id, you will find the corresponding Worker, generation.

 

His algorithm generates the time, this will put the current 41 bit In milliseconds, then the room is 5 bit id, id 5 bit machine, followed by a determination id generated on time if not the same as the sequence number automatically from zero; if the last time with now or within a millisecond, he took seq incremented by 1, that is, automatically generate a different number of milliseconds.

 

The algorithm that can be said that every room to ensure each machine every millisecond, generating up to 4096 are not repeated in the id.

 

Using this algorithm snowflake, you can develop your own company's services, even for a machine room and id id, anyway, you set aside 5 bit + 5 bit, you have a business meaning into other things are possible.

 

The snowflake algorithm is still relatively tricky, so you have to really do id distributed generation, what if it is high concurrency, then this should be a relatively good performance, usually tens of thousands of concurrent scenes per second, enough with you a.

 

Guess you like

Origin www.cnblogs.com/xiufengchen/p/11259311.html