比如需要分片的表:
public class Transaction {
@Id
@Column(name = "transaction_id")
private String transactionId;
@Column(name = "source_account")
private String sourceAccount;
@Column(name = "target_account")
private String targetAccount;
private BigDecimal amount;
private OffsetDateTime timestamp;
}
现在希望根据sourceAccount+targetAccount+timestamp 生成唯一不重复的transactionId,然后根据transactionId取模进行分片,并且根据sourceAccount或者targetAccount能快速找到分片
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.UUID;
public class TransactionIdGenerator {
private static final int SHARD_COUNT = 16; // 假设 16 个分片
public static String generateId(String sourceAccount, String targetAccount, OffsetDateTime timestamp) {
long ts = timestamp.toInstant().toEpochMilli();
int sourceHash = Math.abs(sourceAccount.hashCode()) & 0xFFFF;
int targetHash = Math.abs(targetAccount.hashCode()) & 0xFFFF;
long uniquePart = UUID.randomUUID().getMostSignificantBits() & 0xFFFFFFFFFFFFL; //序列号可以用数据库来生成
long id = ((ts << 48) |
((long) sourceHash << 32) |
((long) targetHash << 16) |
uniquePart);
return Long.toUnsignedString(id);
}
public static int getShardFromTransactionId(String transactionId) {
long id = Long.parseUnsignedLong(transactionId);
int sourceHash = (int) ((id >> 32) & 0xFFFF);
int targetHash = (int) ((id >> 16) & 0xFFFF);
// 合并 sourceHash 和 targetHash
int combinedHash = sourceHash ^ targetHash;
return combinedHash % SHARD_COUNT;
}
public static int getShardFromSourceAccount(String sourceAccount) {
int sourceHash = Math.abs(sourceAccount.hashCode()) & 0xFFFF;
return sourceHash % SHARD_COUNT;
}
}