Skip to content

Commit 36d03d6

Browse files
authored
Merge pull request #6 from Rurutia1027/payment-example-v2
Add examples for both HQL Query and DB/Table Sharding
2 parents c4b2616 + 8d0783e commit 36d03d6

File tree

21 files changed

+3009
-0
lines changed

21 files changed

+3009
-0
lines changed
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# Payment Example V2 - Complex Sharding Scenarios
2+
3+
## Overview
4+
5+
Payment Example V2 is an e-commerce payment system example built on top of the `persistence-common` and
6+
`persistence-sharding` modules. It demonstrates **complex cross-module and cross-database sharding scenarios**, include
7+
database-level and table-level sharding.
8+
9+
## Core Features
10+
11+
### Multi-Module Database Architecture
12+
13+
### Complex Business Scenarios
14+
15+
### Sharding Strategy
16+
17+
- Database-level sharding: 2 database shards (`ds_ecommerce_0/1`, `ds_payment_0/1`)
18+
- Table-level sharding: each table is sharded based on business needs (16-64 shards)
19+
- Sharding key: `user_id` (user-dimension sharding)
20+
21+
## Architecture Design
22+
23+
### Database Architecture
24+
25+
```
26+
27+
```
28+
29+
## Sharding Configuration
30+
31+
### E-Commerce Module Tables
32+
33+
#### Table: `t_orders`
34+
35+
- Database Shards: 2 (`ds_ecommerce_0/1`)
36+
- Table Shards: 16 per DB
37+
- Description: Order table, sharded by `user_id`
38+
39+
#### Table: `t_order_items`
40+
41+
- Database Shards: 2 (`ds_ecommerce_0/1`)
42+
- Table Shards: 16 per DB
43+
- Description: Order item table, aligned with order sharding
44+
45+
### Payment Module Table
46+
47+
#### Table: `t_payments`
48+
49+
- Database Shard: 2 (`ds_payment_0/1`)
50+
- Table Shards: 16 per DB
51+
- Description: Payment table, sharded by `user_id`
52+
53+
#### Table: `t_payment_records`
54+
55+
- Database Shard: 2 (`ds_payment_0/1`)
56+
- Table Shards: 16 per DB
57+
- Description: Payment record table, aligned with payment sharding
58+
59+
#### Table: `t_refunds`
60+
61+
- Database Shard: 2 (`ds_payment_0/1`)
62+
- Table Shards: 8 per DB
63+
- Description: Refund table, sharded by `user_id`
64+
65+
#### Table: `t_account_balance`
66+
67+
- Database Shard: 2 (`ds_payment_0/1`)
68+
- Table Shards: 1 (no table sharding)
69+
- Description: Account balance table
70+
71+
#### Table: `t_account_transaction`
72+
73+
- Database Shard: (`ds_payment_0/1`)
74+
- Table Shards: 32 per DB
75+
- Description: Account transaction table, sharded by `user_id`
76+
77+
---
78+
79+
## Complex Business Scenarios
80+
81+
### Cross-Shard Aggregation Queries
82+
83+
**Scenarios**: Calculate platform-wide business metrics (total orders, total payment amount, payment method
84+
distribution, etc.)
85+
86+
**Characteristics**:
87+
88+
- Query condition **do not include the sharding key (user_id)**
89+
- ShardingSphere queries **all shards** and merges results
90+
- Suitable for analytics and reporting use cases
91+
92+
**Example**:
93+
94+
```java
95+
// Calculate platform-wide order count and total payment amount
96+
97+
BusinessMetriics metrics = analyticsService.getOverallMetrics(startDate, endDate);
98+
99+
// ShardingSphere queries all 4 database shards and merges the aggregated results
100+
```
101+
102+
**Performance Considerations**:
103+
104+
- Cross-shard queries across all shards and are slower
105+
- Prefer asynchronous processing or caching
106+
- For low real-time requirements, use scheduled pre-computation
107+
108+
### Single-Shard Optimized Queries
109+
110+
**Scenario**: Query order and payment data for a specific user
111+
112+
**Characteristics**:
113+
114+
- Query conditions include the sharding key (`user_id`)
115+
- ShardingSphere routes to a **single shard**
116+
- Optimal performance, suitable for high-frequency queries
117+
118+
Example:
119+
120+
```java
121+
// Query user-specific metrics (single shard)
122+
BusinessMetrics userMetrics = analyticsService.getUserMetrics(userId, startDate, endDate);
123+
// Routed to a single shard based on userId
124+
125+
```
126+
127+
### Cross Module Data Association
128+
129+
**Scenario**: Orders and payments reside in different database modules but must be queried together
130+
131+
**Design Strategies**:
132+
133+
- Application-level join (recommended): Query order first, then payment
134+
- Data redundancy: Store payment status redundantly in order table (already implemented)
135+
- Event-driven synchronization: Use message queues for data synchronization (for non-real-time requirements)
136+
137+
Example:
138+
139+
```java
140+
// 1. Query order (E-Commerce Module)
141+
Order order = queryService.findObjectById(Order.class, orderId, userId);
142+
143+
// 2. Query payment (Payment Module, same userId ensures same shard index logic)
144+
Payment payment = queryService.findObjectById(Payment.class, paymentId, userId);
145+
146+
// 3. Assemble result at application layer
147+
OrderWithPayment result = new OrderWithPayment(order, payment);
148+
```
149+
150+
## Performance Optimization Recommendations
151+
152+
### Query Optimization
153+
154+
- Always include the sharding key (`user_id`) in high-frequency queries
155+
- Avoid cross-shard queries in latency-sensitive scenarios
156+
- Cache cross-shard aggregation results (e.g., Redis)
157+
158+
### Data Redundancy
159+
160+
- Store payment status in order table
161+
- Store product information in order items
162+
- Store order information in payment table for fast lookup
163+
164+
### Asynchronous Processing
165+
166+
- Use scheduled jobs for metrics computation
167+
- Use message queues for cross-module synchronization
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
services:
2+
# E-Commerce Module Database Shard 0
3+
postgres-ecommerce-0:
4+
image: postgres:15
5+
container_name: postgres-ecommerce-0
6+
environment:
7+
POSTGRES_DB: ecommerce_0
8+
POSTGRES_USER: ecommerce
9+
POSTGRES_PASSWORD: ecommerce
10+
ports:
11+
- "5433:5432"
12+
volumes:
13+
- postgres_ecommerce_0_data:/var/lib/postgresql/data
14+
networks:
15+
- payment-network
16+
healthcheck:
17+
test: ["CMD-SHELL", "pg_isready -U ecommerce -d ecommerce_0"]
18+
interval: 10s
19+
timeout: 5s
20+
retries: 5
21+
22+
# E-Commerce Module Database Shard 1
23+
postgres-ecommerce-1:
24+
image: postgres:15
25+
container_name: postgres-ecommerce-1
26+
environment:
27+
POSTGRES_DB: ecommerce_1
28+
POSTGRES_USER: ecommerce
29+
POSTGRES_PASSWORD: ecommerce
30+
ports:
31+
- "5434:5432"
32+
volumes:
33+
- postgres_ecommerce_1_data:/var/lib/postgresql/data
34+
networks:
35+
- payment-network
36+
healthcheck:
37+
test: ["CMD-SHELL", "pg_isready -U ecommerce -d ecommerce_1"]
38+
interval: 10s
39+
timeout: 5s
40+
retries: 5
41+
42+
# Payment Module Database Shard 0
43+
postgres-payment-0:
44+
image: postgres:15
45+
container_name: postgres-payment-0
46+
environment:
47+
POSTGRES_DB: payment_0
48+
POSTGRES_USER: payment
49+
POSTGRES_PASSWORD: payment
50+
ports:
51+
- "5435:5432"
52+
volumes:
53+
- postgres_payment_0_data:/var/lib/postgresql/data
54+
networks:
55+
- payment-network
56+
healthcheck:
57+
test: ["CMD-SHELL", "pg_isready -U payment -d payment_0"]
58+
interval: 10s
59+
timeout: 5s
60+
retries: 5
61+
62+
# Payment Module Database Shard 1
63+
postgres-payment-1:
64+
image: postgres:15
65+
container_name: postgres-payment-1
66+
environment:
67+
POSTGRES_DB: payment_1
68+
POSTGRES_USER: payment
69+
POSTGRES_PASSWORD: payment
70+
ports:
71+
- "5436:5432"
72+
volumes:
73+
- postgres_payment_1_data:/var/lib/postgresql/data
74+
networks:
75+
- payment-network
76+
healthcheck:
77+
test: ["CMD-SHELL", "pg_isready -U payment -d payment_1"]
78+
interval: 10s
79+
timeout: 5s
80+
retries: 5
81+
82+
volumes:
83+
postgres_ecommerce_0_data:
84+
postgres_ecommerce_1_data:
85+
postgres_payment_0_data:
86+
postgres_payment_1_data:
87+
88+
networks:
89+
payment-network:
90+
driver: bridge

0 commit comments

Comments
 (0)