| 181 | | - **Екстремно висок волумен на податоци** Бидејќи табелата моментално содржи 12 милиони записи, и при секое ново плаќање се прави нов тикет оваа табела станува критична за перформансите. |
| 182 | | |
| 183 | | - **Природа на пребарувањата (Клуч за партиционирање)**Билетите во реалниот систем најчесто се пребаруваат поединечно преку нивниот уникатен ID (`ticket_id`) при валидација на станица или при проверка од кондуктер. Поради ова, HASH партиционирањето е најефикасниот избор. |
| 184 | | |
| 185 | | - **Рамномерна распределба** Преку HASH партиционирање со користење на `ticket_id`, податоците математички се делат на еднакви делови. Наместо една масивна табела, системот користи 16 помали партиции каде што податоците се идеално распределени. |
| 186 | | |
| 187 | | - **Како помага партиционирањето** Кога системот извршува прашање за конкретен `ticket_id`, PostgreSQL врши брзо хаширање на бараниот ID и веднаш детерминира во која точно партиција се наоѓа билетот. Базата целосно ги игнорира останатите 15 партиции, со што драстично се крати времето на пребарување и се одржуваат мали и брзи индекси. |
| | 181 | - **Екстремно висок волумен на податоци** Бидејќи табелата моментално содржи 12 милиони записи, и при секое ново плаќање се прави нов тикет, оваа табела станува критична за перформансите. Без партиционирање, секое пребарување би морало да скенира милиони редови истовремено. |
| | 182 | |
| | 183 | - **Природа на пребарувањата (Клуч за партиционирање)**Билетите во реалниот систем најчесто се пребаруваат во контекст на одредено патување – при валидација на станица, при проверка од кондуктер или при преглед на резервации за конкретен воз. Поради ова, RANGE партиционирањето по Train Triptrip_id е најлогичен избор, бидејќи сите билети кои припаѓаат на исто патување физички се наоѓаат во иста партиција. |
| | 184 | |
| | 185 | -**Еден тикет – една партиција**Клучна забелешка во дизајнот е дека еден тикет не смее да се појавува во две различни партиции (ниту во Payment ниту во Train Trip). Со партиционирање по Train Triptrip_id, ова е гарантирано – секој тикет логички и физички припаѓа на точно едно патување и со тоа на точно една партиција. |
| | 186 | |
| | 187 | - **Рамномерна распределба** Преку RANGE партиционирање со чекор од 650 trip_id вредности по партиција, системот создава партиции со предвидлива и контролирана големина. Со вкупно ~400,000 Train Trip записи и ~30 тикети по патување, секоја партиција содржи приближно ~19,500 записи, со што се задоволува барањето за партиции од ~20,000 редови. |
| | 188 | |
| | 189 | - **Усогласеност со Payment преку transaction_date** За да се спречи појавување на еден тикет во две партиции на Payment, во Ticket табелата е додадена колоната payment_transaction_date. На овој начин, Foreign Key кон Payment е составен (composite) клуч (payment_id, transaction_date), кој директно одговара на партицискиот клуч на Payment табелата. |
| | 190 | |
| | 191 | -**Математичко објаснување на партиционирањето** |
| | 192 | ПресметкаБидејќи партициите на Train Trip се поделени по месеци и содржат по ~3,300 возови за една месечна партиција. |
| | 193 | генерира:$$\text{Билети по месечна партиција} = 3,300 \text{ возови} \times 30 \text{ билети} = 99,000 \text{ билети}$$ |
| | 194 | Тоа значи дека една месечна партиција на Train Trip е преголема за директно пресликување во една партиција на Ticket. За да се добијат партиции од препорачаните ~20,000 редови, секој месец мора логаритамски да се „исече“ на помали парчиња: |
| | 195 | $$\frac{99,000 \text{ билети по месец}}{20,000 \text{ билети по партиција}} \approx 5 \text{ партиции по месец}$$ |
| | 196 | Со тоа, опсегот на train_trip_id во една партиција на Ticket треба да биде:$$\frac{3,300 \text{ возови по месец}}{5 \text{ партиции}} = 660 \approx \mathbf{650 \text{ возови по партиција}}$$ |
| | 197 | |
| | 198 | Финална проверка на капацитетот:$$650 \text{ возови} \times 30 \text{ билети} = \mathbf{19,500 \text{ билети}} \approx 20,000 \quad \checkmark$$ |