Mundarija (24)
- Bu darsda
- 1. Nega bu kerak?
- 2. float — pul uchun emas
- 2.1 Bir million marta 0.1 so'm
- 2.2 Ikki to'g'ri yo'l
- 3. Valyuta va kurs
- 3.1 Pul yonida doim valyuta
- 3.2 Kurs tarixi
- 3.3 Bo'lish va yaxlitlash
- 3.4 money turi — tavsiya etilmaydi
- 4. Enum, lookup jadval va CHECK
- 4.1 Uch yo'l
- 4.2 Enum'ga qiymat qo'shish
- 4.3 Enum'dan qiymat o'chirish
- 4.4 Lookup jadval va hajm
- 5. Ko'p uchraydigan xatolar
- 6. Mashqlar
- 1-mashq (oson)
- 2-mashq (o'rta)
- 3-mashq (qiyin)
- 7. SQL qadami
- 8. Real ishda
- Xulosa
- Manbalar
Pul, miqdor va enum'larni modellash: numeric, tiyin, valyuta va holatlar
Qisqacha: Pul hech qachon
floatda saqlanmaydi — u ikkilik kasrda yaxlitlanadi va xato yig'iladi. To'g'ri yo'llar:numeric(19,4)(aniq o'nlik kasr) yoki butun son — eng kichik birlikda (biginttiyin yoki so'm). Pul yonida doim valyuta turadi, boshqa valyutaga o'girish — o'sha kundagi kurs bilan. Holatlar (yangi,tugadi) uchun uch yo'l bor: enum (ixcham, tartibli, lekin qiymatni o'chirib bo'lmaydi), lookup jadval (moslashuvchan) vaCHECK(oddiy).
Bu darsda
- Nega
floatpul uchun yaroqsizligini raqam bilan ko'rsata olasiz. numeric(19,4)vabigint(tiyin) orasida asosli tanlov qilasiz.- Valyuta ustuni va kurs tarixi bilan to'lovlarni to'g'ri so'mga o'girasiz.
- Summani bo'lishda qoldiqni yo'qotmaslikni bilasiz.
- Enum, lookup jadval va
CHECKni solishtirib, enum'ga qiymat qo'shish va o'chirish muammosini tushunasiz.
Oldin bilishingiz kerak: PostgreSQL ma'lumot turlari, Normalizatsiya, Subquery va LATERAL, ALTER TABLE.
1. Nega bu kerak?
Ilovada pul paydo bo'lishi bilan xato narxi keskin oshadi. Vazifa matnidagi xato — noqulaylik. To'lovdagi bir tiyinlik xato — mijoz shikoyati, buxgalteriya tafovuti, ba'zan sud.
vazifalar bazasida pul yo'q. Lekin kurs davomida «Bahor» oshxonasi menyusini, 24-qismdagi valyuta CLI'sidagi kurslarni ko'rdik; keyingi qismlarda to'lov (Click, Payme) va obuna paydo bo'ladi. Pulni saqlash qoidasi bir marta to'g'ri o'rganilishi kerak — shuning uchun bu dars tajriba bazasida, «Bahor» va to'lov misollarida.
O'xshatish: dorixona tarozisi. Bozordagi tarozida "taxminan bir kilo" yetarli, dorixonada esa milligramm aniq bo'lishi shart. Pul — dorixona tarozisi: "taxminan" bo'lmaydi.
2. float — pul uchun emas
2.1 Bir million marta 0.1 so'm
Ma'lumot turlari darsida 0.1 + 0.2 ning 0.30000000000000004 berishini ko'rdik. Kichik xato bitta amalda sezilmaydi — lekin u yig'iladi. Kanon tajribasi: bir million to'lov, har biri 0.1 so'm, uch xil turda (kanon sorovlar/39-pul-enum.sql, PostgreSQL 18.6; biz o'z 17.6 klasterimizda qayta ishga tushirdik — chiqish bir xil, uzun qatorlarni bo'lib yozdik):
SELECT sum(0.1::float8) AS float8,
sum(0.1::numeric(19,4)) AS numeric,
sum(10::bigint) / 100.0 AS tiyin_bigint
FROM generate_series(1, 1000000); float8 | numeric | tiyin_bigint
--------------------+-------------+---------------------
100000.00000133288 | 100000.0000 | 100000.000000000000
(1 row)float8 — 100 000 dan biroz ortiq; numeric va bigint — aniq 100 000. Xato kichik ko'rinadi, lekin u "ba'zan bor, ba'zan yo'q" — hisobot ikki marta hisoblanganda ikki xil natija berishi mumkin. Sababi: float sonni ikkilik kasrda saqlaydi va 0.1 ikkilikda cheksiz kasr (xuddi 1/3 o'nlikda 0.333… bo'lgani kabi).
JavaScript'da ham aynan shu — number ham float8 (Pul bilan ishlash JS'da darsida chuqur ko'ramiz):
console.log(0.1 + 0.2);
let jami = 0;
for (let i = 0; i < 10; i++) jami += 0.1;
console.log(jami);
const tiyinda = 10 * 10;
console.log(tiyinda / 100);Konsolda:
0.30000000000000004
0.9999999999999999
1O'n marta 10 tiyin qo'shsak — aniq 100 tiyin, ya'ni 1 so'm. O'n marta 0.1 so'm qo'shsak — 0.9999999999999999. Butun sonlar bilan xato yo'q.
2.2 Ikki to'g'ri yo'l
| Usul | Misol | Afzallik | Diqqat |
|---|---|---|---|
numeric(19,4) |
35000.0000 |
Aniq o'nlik kasr, istalgan valyuta | Sekinroq, Node'ga satr bo'lib keladi |
bigint (eng kichik birlik) |
tiyin: 3500000 |
Tez, ixcham (8 bayt) | Har joyda "100 ga bo'lish"ni eslash |
numeric(19,4) — jami 19 raqam, ulardan 4 tasi verguldan keyin. Nega aynan 4: valyuta kurslari va foizlar (masalan, 12.5 % soliq) oraliq hisobda ko'proq kasr talab qiladi; 19 raqam esa bigint diapazoniga yaqin. Bu ko'p moliyaviy tizimlardagi odatiy tanlov.
So'mda tiyin amalda ishlatilmaydi (narxlar butun so'mda). Shuning uchun faqat so'm bilan ishlaydigan ilovada bigint so'm ham to'g'ri variant — 1-mashqda shunday qilamiz. Bir nechta valyuta (dollar sentlari bilan) bo'lsa — numeric yoki har valyutaning eng kichik birligida bigint.
Node tomonida bitta muhim fakt: pg drayveri numeric va bigint ni satr bo'lib qaytaradi — aniqlik yo'qolmasligi uchun. Buni node-postgres asoslari darsida o'lchov bilan ko'ramiz.
Tekshirib ko'ring: Nega
numeric(10,2)emas,numeric(19,4)? So'm uchun 2 ta kasr ham yetarli emasmi?
Javob
Yakuniy summalar uchun 2 ta kasr yetarli bo'lishi mumkin. Lekin oraliq hisoblar ko'proq aniqlik talab qiladi: kurs bilan ko'paytirish, foiz, bo'lish. Aks holda har qadamda yaxlitlanib, xato yig'iladi. numeric(10,2) esa eng ko'pi 99 999 999.99 ni sig'diradi — yirik kompaniya aylanmasi uchun kam; sig'masa numeric field overflow xatosi.
3. Valyuta va kurs
3.1 Pul yonida doim valyuta
"35 000" — so'mmi, dollarmi? Ustun nomi (narx_som) yordam beradi, lekin ilova bir kun boshqa valyutani qabul qilsa — sxema o'zgaradi. To'g'ri yo'l: miqdor yonida valyuta kodi (ISO 4217: UZS, USD, EUR). Kanon tajribasi:
CREATE TABLE t39_tolov (
id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
miqdor numeric(19,4) NOT NULL CHECK (miqdor > 0),
valyuta char(3) NOT NULL DEFAULT 'UZS'
CHECK (valyuta ~ '^[A-Z]{3}$'),
vaqt timestamptz NOT NULL DEFAULT now()
);
INSERT INTO t39_tolov (miqdor, valyuta, vaqt) VALUES
(35000, 'UZS', '2026-10-20 13:00+05'),
(12.5, 'USD', '2026-10-20 14:00+05'),
(28000, 'UZS', '2026-10-21 13:00+05');
SELECT sum(miqdor) AS notogri_yigindi FROM t39_tolov;CREATE TABLE
INSERT 0 3
notogri_yigindi
-----------------
63012.5000
(1 row)63 012.5 — ma'nosiz son: so'm va dollar qo'shib yuborildi. Baza buni to'smaydi — valyutasi boshqa sonlar ham baribir sonlar. To'g'ri yig'indi — valyuta bo'yicha guruhlab:
SELECT valyuta, sum(miqdor)
FROM t39_tolov GROUP BY valyuta ORDER BY 1; valyuta | sum
---------+------------
USD | 12.5000
UZS | 63000.0000
(2 rows)Qoida: pulni faqat bir xil valyuta ichida qo'shing. Boshqacha yig'indi kerak bo'lsa — avval bitta valyutaga o'giring.
3.2 Kurs tarixi
Dollarni so'mga qaysi kurs bilan o'giramiz? Bugungi emas — to'lov kunidagi. Aks holda o'tgan oy hisobotlari har kuni o'zgaradi. Shuning uchun kurs jadvali tarixni saqlaydi: (valyuta, sana) — kalit. Har to'lov uchun "to'lov kunidan oldingi eng so'nggi kurs"ni LATERAL bilan olamiz. Kurslar o'ylab topilgan (12 000) — haqiqiy kurslarni 24-qismdagi valyuta CLI Markaziy bank API'sidan olgan edi. Kanon tajribasi:
CREATE TABLE t39_kurs (
valyuta char(3), sana date, kurs numeric(19,4),
PRIMARY KEY (valyuta, sana)
);
INSERT INTO t39_kurs VALUES
('USD', '2026-10-19', 11950), ('USD', '2026-10-20', 12000),
('UZS', '2026-10-20', 1), ('UZS', '2026-10-21', 1);
SELECT t.id, t.miqdor, t.valyuta, k.kurs,
round(t.miqdor * k.kurs, 2) AS som_da
FROM t39_tolov t
LEFT JOIN LATERAL (
SELECT kurs FROM t39_kurs k
WHERE k.valyuta = t.valyuta
AND k.sana <= (t.vaqt AT TIME ZONE 'Asia/Tashkent')::date
ORDER BY sana DESC LIMIT 1
) k ON true
ORDER BY t.id;CREATE TABLE
INSERT 0 4
id | miqdor | valyuta | kurs | som_da
----+------------+---------+------------+-----------
1 | 35000.0000 | UZS | 1.0000 | 35000.00
2 | 12.5000 | USD | 12000.0000 | 150000.00
3 | 28000.0000 | UZS | 1.0000 | 28000.00
(3 rows)Uch nozik joy:
- Kun Toshkent bo'yicha ajratiladi (Sana va vaqt zonalari) — UTC kuni bilan kurs bir kun siljishi mumkin.
<=vaORDER BY sana DESC LIMIT 1— dam olish kunlari kurs e'lon qilinmasa, oxirgi ma'lum kurs olinadi.round(…, 2)— yaxlitlash faqat oxirida.
3.3 Bo'lish va yaxlitlash
100 000 so'mlik hisobni uch kishi teng bo'lishmoqchi. Har biriga 33 333.33 — lekin uchtasi 99 999.99. Bir tiyin yo'qoldi. Kanon tajribasi:
SELECT round(100000 / 3.0, 2) AS har_biriga,
round(100000 / 3.0, 2) * 3 AS jami_tiklanmaydi,
100000 - 2 * round(100000 / 3.0, 2) AS oxirgisiga; har_biriga | jami_tiklanmaydi | oxirgisiga
------------+------------------+------------
33333.33 | 99999.99 | 33333.34
(1 row)Yechim — qoldiqni kimgadir berish: ikki kishiga 33 333.33, oxirgisiga 33 333.34. Jami — aniq 100 000. Buxgalteriyada bu "qoldiqni taqsimlash" deyiladi va qaysi qatorga berilishi qoida bilan belgilanadi (birinchisiga, eng kattasiga). 3-mashqda butun so'mlarda yozamiz.
3.4 money turi — tavsiya etilmaydi
Postgres'da money turi bor. Kanon tajribasi:
SELECT 35000::money AS money_en_us; money_en_us
-------------
$35,000.00
(1 row)Dollar belgisi o'zi paydo bo'ldi — chunki money server lokali (lc_monetary) bo'yicha formatlanadi. Ichida valyuta saqlanmaydi: boshqa lokalli serverda xuddi shu qiymat boshqa belgi bilan chiqadi. Kasrlar soni ham lokalga bog'liq. Postgres hujjati ham uni yangi loyihalarda emas, numeric ni tavsiya qiladi. Xulosa: money ishlatmang.
4. Enum, lookup jadval va CHECK
4.1 Uch yo'l
Holat, tur, daraja — oldindan belgilangan qiymatlar ro'yxati. Bizda ustuvorlik: past, orta, yuqori. Uni saqlashning uch yo'li:
| Usul | Qiymat qo'shish | Qiymat o'chirish | Qo'shimcha maydon |
|---|---|---|---|
Enum (CREATE TYPE … AS ENUM) |
ALTER TYPE … ADD VALUE |
Mumkin emas | Yo'q |
| Lookup jadval + FK | INSERT |
DELETE (ishlatilmasa) |
Bor (rang, tartib) |
CHECK (holat IN (…)) |
Cheklovni qayta yaratish | Cheklovni qayta yaratish | Yo'q |
Enum'ni ALTER TABLE darsida yaratgan edik va uning foydali xususiyatini ko'rdik: tartibi e'londagi tartib (ORDER BY ustuvorlik DESC → yuqori, orta, past), matn tartibi emas.
4.2 Enum'ga qiymat qo'shish
Kanon tajribasi — vaqtinchalik t39_holat turida. Yangi qiymat tranzaksiya ichida qo'shilishi mumkin (PG 12+), lekin o'sha tranzaksiyada ishlatib bo'lmaydi:
CREATE TYPE t39_holat AS ENUM ('yangi', 'jarayonda', 'tugadi');
BEGIN;
ALTER TYPE t39_holat ADD VALUE 'bekor' AFTER 'tugadi';
SELECT 'bekor'::t39_holat;CREATE TYPE
BEGIN
ALTER TYPE
ERROR: unsafe use of new value "bekor" of enum type t39_holat
LINE 1: SELECT 'bekor'::t39_holat;
^
HINT: New enum values must be committed before they can be used.Tarjimasi: "enum turidagi yangi «bekor» qiymatidan xavfli foydalanish"; maslahat — "yangi enum qiymatlari ishlatilishidan oldin commit qilinishi kerak". Bu migratsiyalarda haqiqiy muammo: "qiymat qo'sh + mavjud qatorlarni yangila" bitta tranzaksiyada ishlamaydi — ikki bosqichga bo'linadi. Tranzaksiya xatodan keyin ROLLBACK; bilan yopiladi. Tranzaksiyadan tashqarida esa qo'shish darhol ishlaydi:
ALTER TYPE t39_holat ADD VALUE 'bekor' AFTER 'tugadi';
SELECT enum_range(NULL::t39_holat);ALTER TYPE
enum_range
--------------------------------
{yangi,jarayonda,tugadi,bekor}
(1 row)AFTER 'tugadi' — tartibdagi o'rni. enum_range — hamma qiymatlar tartib bilan.
4.3 Enum'dan qiymat o'chirish
ALTER TYPE t39_holat DROP VALUE 'bekor';ERROR: dropping an enum value is not implemented
LINE 1: ALTER TYPE t39_holat DROP VALUE 'bekor';
^"Enum qiymatini o'chirish amalga oshirilmagan" — bunday buyruq yo'q. Qiymatni olib tashlash uchun yangi tur yaratib, ustunni unga ko'chirish (ALTER COLUMN … TYPE … USING …) kerak — katta jadvalda bu butun jadvalni qayta yozish. Nomini o'zgartirish esa mumkin:
ALTER TYPE t39_holat RENAME VALUE 'jarayonda' TO 'bajarilmoqda';
SELECT enum_range(NULL::t39_holat);ALTER TYPE
enum_range
-----------------------------------
{yangi,bajarilmoqda,tugadi,bekor}
(1 row)4.4 Lookup jadval va hajm
Lookup jadval — qiymatlar oddiy jadvalda, asosiy jadval ularga tashqi kalit bilan bog'lanadi. Qo'shish va o'chirish — oddiy INSERT/DELETE, qo'shimcha maydonlar (o'zbekcha nomi, rangi, tartibi) — bemalol. Hajmni solishtiramiz (kanon):
CREATE TABLE t39_holat_lookup (
kod text PRIMARY KEY, nom text NOT NULL, tartib int NOT NULL
);
INSERT INTO t39_holat_lookup VALUES
('yangi', 'Yangi', 1), ('jarayonda', 'Jarayonda', 2),
('tugadi', 'Tugadi', 3);
SELECT pg_column_size('bajarilmoqda'::t39_holat) AS enum_bayt,
pg_column_size('jarayonda'::text) AS text_bayt;CREATE TABLE
INSERT 0 3
enum_bayt | text_bayt
-----------+-----------
4 | 13
(1 row)Enum har qatorda 4 bayt, matn kodi — uzunligiga qarab (bu yerda 13). Millionlab qatorda bu farq sezilarli, lekin hal qiluvchi emas.
Qaysi birini tanlash — quyidagi savollar zanjiri bilan. Nimaga qarang: birinchi savol "qiymatda qo'shimcha ma'lumot bormi?".
flowchart TB
S1{"Nom, rang, tartib kabi<br/>qo'shimcha ma'lumot bormi?"} -- ha --> L["Lookup jadval + FK"]
S1 -- yo'q --> S2{"Ro'yxat tez-tez o'zgaradimi<br/>yoki qiymat o'chiriladimi?"}
S2 -- ha --> L
S2 -- yo'q --> S3{"Tartib muhimmi?"}
S3 -- ha --> E["Enum"]
S3 -- yo'q --> C["text + CHECK yoki enum"]- Enum — qiymatlar kam, kamdan-kam o'zgaradi, tartib muhim, qo'shimcha ma'lumot yo'q. Kanon
ustuvorlikuchun shuni tanlagan. - Lookup jadval — qiymatlarni admin panel orqali boshqarish kerak, o'zbekcha nomi yoki rangi bor, qiymat o'chirilishi mumkin.
CHECK— juda oddiy holat, 2–3 qiymat, o'zgarmaydi (valyuta ~ '^[A-Z]{3}$'kabi format tekshiruvi ham shu).
Tajriba jadvallarini tozalaymiz:
DROP TABLE t39_tolov, t39_kurs, t39_holat_lookup;
DROP TYPE t39_holat;DROP TABLE
DROP TYPE5. Ko'p uchraydigan xatolar
1. Pul float/real/double precision da. Xato yig'iladi, hisobotlar mos kelmaydi. Tuzatish: numeric(19,4) yoki bigint eng kichik birlikda.
2. Valyutasiz summa. narx ustuni — qaysi valyutada? Ikkinchi valyuta kelgan kuni hamma eski qatorlar shubhali. Tuzatish: valyuta char(3) (ISO 4217).
3. Bugungi kurs bilan eski to'lovni o'girish. O'tgan oy hisoboti har kuni o'zgaradi. Tuzatish: kurs tarixi va to'lov kunidagi kurs.
4. Har qadamda yaxlitlash. Oraliq natijalar yaxlitlanib, xato yig'iladi. Tuzatish: to'liq aniqlik bilan hisoblab, faqat oxirida yaxlitlang; bo'lishda qoldiqni taqsimlang.
5. money turi. Lokalga bog'liq, valyutasiz. Tuzatish: numeric + valyuta.
6. Tez o'zgaradigan ro'yxat uchun enum. Har yangi holat — migratsiya, o'chirish — imkonsiz. Tuzatish: lookup jadval.
7. Enum qiymatini qo'shib, o'sha tranzaksiyada ishlatish. unsafe use of new value. Tuzatish: migratsiyani ikki qadamga bo'ling.
6. Mashqlar
Mashqlar istalgan bazada (sxemaga bog'liq emas). Jadval yaratadiganlari — BEGIN … ROLLBACK ichida.
1-mashq (oson)
«Bahor» menyusi: t39_menyu (nom PK, narx bigint, narx > 0) — osh 35 000, lag'mon 28 000, manti 30 000, ko'k choy 5 000 (butun so'm). 2 ta osh va 3 ta ko'k choyli buyurtma summasini chiqaring (jami). Ishora: buyurtmani VALUES bilan "jadval" qiling va menyuga birlashtiring (JOIN).
Yechim
BEGIN;
CREATE TABLE t39_menyu (
nom text PRIMARY KEY,
narx bigint NOT NULL CHECK (narx > 0)
);
INSERT INTO t39_menyu VALUES
('osh', 35000), ('lag''mon', 28000), ('manti', 30000),
('ko''k choy', 5000);
SELECT sum(m.narx * b.soni) AS jami
FROM (VALUES ('osh', 2), ('ko''k choy', 3)) AS b(nom, soni)
JOIN t39_menyu m ON m.nom = b.nom;
ROLLBACK;BEGIN
CREATE TABLE
INSERT 0 4
jami
-------
85000
(1 row)
ROLLBACK2 × 35 000 + 3 × 5 000 = 85 000. Faqat so'm va narxlar butun — bigint yetarli va eng tez. Real buyurtma jadvalida narx buyurtma qatoriga ham nusxalanadi (snapshot).
2-mashq (o'rta)
Ikki to'lov — 2026-10-19 va 2026-10-21 kunlari, har biri 10.00 dollar. Kurslar: 19-oktyabr — 11 950, 20-oktyabr — 12 000 (21-oktyabr kursi yo'q). Har to'lovni o'z kunidagi (yoki undan oldingi eng so'nggi) kurs bilan so'mga o'giring: sana, miqdor, kurs, som_da. Ishora: «Kurs tarixi» bo'limidagi LEFT JOIN LATERAL; to'lovlarni VALUES bilan bering.
Yechim
BEGIN;
CREATE TABLE t39_kurs (
valyuta char(3), sana date, kurs numeric(19,4),
PRIMARY KEY (valyuta, sana)
);
INSERT INTO t39_kurs VALUES
('USD', '2026-10-19', 11950), ('USD', '2026-10-20', 12000);
SELECT t.sana, t.miqdor, k.kurs, round(t.miqdor * k.kurs, 2) AS som_da
FROM (VALUES (date '2026-10-19', 10.00),
(date '2026-10-21', 10.00)) AS t(sana, miqdor)
LEFT JOIN LATERAL (
SELECT kurs FROM t39_kurs
WHERE valyuta = 'USD' AND sana <= t.sana
ORDER BY sana DESC LIMIT 1
) k ON true
ORDER BY t.sana;
ROLLBACK;BEGIN
CREATE TABLE
INSERT 0 2
sana | miqdor | kurs | som_da
------------+--------+------------+-----------
2026-10-19 | 10.00 | 11950.0000 | 119500.00
2026-10-21 | 10.00 | 12000.0000 | 120000.00
(2 rows)
ROLLBACK21-oktyabr kursi yo'q — oxirgi ma'lumi (20-oktyabr) olindi. Agar kurs umuman topilmasa, LEFT JOIN tufayli qator qoladi va kurs NULL bo'ladi — ilova buni "kurs noma'lum" deb ko'rsatishi kerak, jim 0 emas.
3-mashq (qiyin)
100 000 so'mni 3 kishiga butun so'mlarda, qoldiqsiz bo'ling: qoldiq birinchi kishilarga bittadan beriladi. kishi, ulush ni chiqaring, keyin ulushlar yig'indisi 100 000 ekanini tekshiring. Ishora: butun bo'lish — 100000 / 3 (int), qoldiq — % (Ifodalar); kishilar — generate_series(1, 3).
Yechim
SELECT n AS kishi,
100000 / 3 + CASE WHEN n <= 100000 % 3 THEN 1 ELSE 0 END
AS ulush
FROM generate_series(1, 3) AS n;
SELECT sum(100000 / 3 + CASE WHEN n <= 100000 % 3 THEN 1 ELSE 0 END)
AS jami
FROM generate_series(1, 3) AS n; kishi | ulush
-------+-------
1 | 33334
2 | 33333
3 | 33333
(3 rows)
jami
--------
100000
(1 row)100000 / 3 = 33 333 (butun bo'lish), qoldiq 100000 % 3 = 1 — u birinchi kishiga. Jami aniq 100 000. Bu "eng katta qoldiq" usulining eng oddiy shakli; ulushlar teng bo'lmasa (masalan, 50 %, 30 %, 20 %), qoldiq eng katta kasr qismli ulushga beriladi.
7. SQL qadami
Bu dars — faqat tajriba, sxema o'zgarmaydi: holat 38 da qolamiz. vazifalar da pul yo'q, shuning uchun kanon tajribasi alohida bazada «Bahor» va to'lov misollarida bajarilgan.
Kanon qarori ustuvorlik haqida: enum qoladi — 3 qiymat, kamdan-kam o'zgaradi, tartib muhim (ro'yxatda "yuqori" birinchi). Agar keyinroq foydalanuvchilar o'z ustuvorlik darajalarini yaratishi kerak bo'lsa (rang va nom bilan) — lookup jadvalga ko'chiriladi; bu migratsiya (ALTER COLUMN … TYPE text USING ustuvorlik::text + tashqi kalit) rejalashtirilgan ish bo'ladi.
Commit yo'q.
8. Real ishda
- To'lov tizimlari. Click va Payme API'larida summa ko'pincha tiyinda (butun son) uzatiladi — hujjatlarini o'qiganda birligiga e'tibor bering (hujjat bo'yicha; biz ularning API'sini sinamadik). Stripe ham eng kichik birlikda ishlaydi (sent).
- Buxgalteriya va bank.
numeric, valyuta, kurs tarixi, qoldiqni taqsimlash — har kungi ish. Markaziy bank kursi har kuni e'lon qilinadi — kurs jadvali aynan shu ma'lumot. - Statuslar. Buyurtma holatlari (
yangi,tolangan,yetkazilmoqda) ko'pincha lookup jadval yokitext+CHECKbo'ladi — chunki biznes tez-tez yangi holat qo'shadi. - Intervyuda: "pulni qanday saqlaysiz?" — klassik savol. Javob:
floatemas;numericyoki eng kichik birlikdabigint; valyuta ustuni; yaxlitlash va qoldiq qoidasi.
Xulosa
floatpulni yaxlitlaydi va xato yig'iladi: 1 mln × 0.1 → 100000.00000133288.- Pul —
numeric(19,4)yoki eng kichik birlikdabigint; faqat so'm bo'lsa —bigintso'm. - Pul yonida doim
valyuta; boshqa valyutaga — to'lov kunidagi kurs bilan (kurs tarixi + LATERAL). - Yaxlitlash — oxirida; bo'lishda qoldiqni aniq qoida bilan taqsimlang.
moneyturi — yo'q. - Enum — ixcham va tartibli, lekin qiymat o'chirilmaydi va yangi qiymat o'sha tranzaksiyada ishlatilmaydi; tez o'zgaradigan ro'yxat — lookup jadval.
Keyingi dars: Amaliyot: real loyiha sxemasini loyihalash — talablardan yakuniy sxemagacha: vazifalar bazasini review qilamiz va A bosqichni yakunlaymiz.
Manbalar
- PostgreSQL 18 hujjati: "Numeric Types", "Monetary Types", "Enumerated Types", "ALTER TYPE" — postgresql.org/docs/18, 2026-10-24 da ko'rildi.
- ISO 4217 — valyuta kodlari standarti.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!