After the sub-library sub-table, how to deal with the primary key id

Based on implementation of the database

Database increment 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 increments id own several one-time return to a group of id, id and then modify the current maximum value to a value after the increment several id; but in any case 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.

Table or database sequence set increment step Field

Horizontal scaling may be provided by a database sequence table or self-energizing field step.

For example, there are eight service nodes, each service node using a function to generate a sequence ID, the ID of each different starting sequence, and successively increment step size is 8.

database-id-sequence-step

Suitable scenario: when a user ID is prevented repeated, this solution is relatively simple to implement, can achieve performance objectives. But the service node fixed step size is also fixed, but also to increase in the future if the service node, bad did.

UUID

Benefit is locally generated, based on the database do not come; a bad place is, UUID too long, large space, as the primary key performance bad; more importantly, UUID does not have orderly, can lead to B + tree index in the writing of the excessive random writes (continuous ID generating portion can be sequential write), and, because it is not generating sequential write append operation, when the insert operation is required, will read the entire B + tree nodes into memory, this record is inserted after the entire node will be written back to disk, this operation in the recording space is relatively large, significant performance degradation.

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

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

Gets 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 number.

snowflake algorithm

snowflake algorithm is revenue distributed twitter id generation algorithm using Scala language, 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 10 bit id, 12 bit as 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 a 0 uniform.
  • 41 bit: it indicates that the timestamp milliseconds. 41 bit number can represent up to  2^41 - 1, that is, you can identify  2^41 - 1 a millisecond value, expressed in terms of an adult is 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. Meaning that most representatives of  2^5a room (32 rooms), in each room can represent  2^5 a machine (32 machines).
  • 12 bit: the maximum positive integer that is used to record the same milliseconds different id generated, 12 bit may represent  2^12 - 1 = 4096, i.e. this number can be represented by 12 bit to distinguish between different id 4096 milliseconds in the same .
0 | 0001100 10100010 10111110 10001001 01011100 00 | 10001 | 1 1001 | 0000 00000000
public class IdWorker {

    Private Long workerId; Private Long datacenterId; Private Long Sequence; public IdWorker ( Long workerId, Long datacenterId, Long Sequence) { // Sanity the 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) { the throw new new an IllegalArgumentException ( String .format ( "cAN not BE worker id Within last Greater% or less Within last D 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 workerIdBits Long = 5L; Private Long datacenterIdBits = 5L; // this is a binary operation, only 5 bit is up to 31 digits, i.e. the machine can only be within the id 32 Private Long maxWorkerId = - 1L ^ ( - 1L workerIdBits <<); // this is a mean, 5 bit is only up to 31 digits, only up to room id within 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 the synchronized Long nextId () { // get the current time stamp is here, milliseconds Long timestamp = TIMEGEN (); IF (timestamp <LastTimestamp) { the System .err .printf ( "Clock IS Moving Backwards Rejecting an until Requests% D.. ", LastTimestamp); the throw new new a RuntimeException ( String .format ( " Clock Moved Backwards ID for refusing to Generate% D milliseconds. ", LastTimestamp - timestamp));} IF (LastTimestamp == timestamp) { // this means that a can only have up to 4096 numbers in milliseconds // No matter how much you passed in, this place is always guarantee operation in 4096 this range, you pass a sequence to avoid exceeding the scope of the 4096 sequence = (sequence +. 1) & sequenceMask; IF (Sequence == 0) {timestamp = tilNextMillis (LastTimestamp);}} the else {Sequence = 0;} // here timestamp recorded at the last generated id milliseconds LastTimestamp = timestamp; / / time stamp here is to the left, into the 41 bit there; // id left into the room where 5 bit; // put the machine left id where 5 bit; the last sequence number to put 'bit 12 is; // Finally spliced together into a 64 bit binary number, 10 decimal is converted into a long-type return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift) | (workerId << workerIdShift) | Sequence;} Private Long tilNextMillis ( Long LastTimestamp) {long timestamp = timeGen(); while (timestamp <= lastTimestamp) { timestamp = timeGen(); } return timestamp; } private long timeGen() { return System.currentTimeMillis(); } // ---------------测试--------------- 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 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), the other 5 bit your machine is passed in id (but only within maximum 32), the rest of the 12 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.

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/windpoplar/p/10926571.html