Ma'lumot turlari — INT, VARCHAR, TEXT, DATE, BOOLEAN, ENUM, JSON

~20 daq · MySQL · Kirish va O'rnatish

Muammodan boshlaylik

Excel da istalgan katakka istalgan narsani yozish mumkin: narx ustuniga "kelishiladi", sana ustuniga "ertaga", telefon ustuniga "Azizning ukasi". Keyin "narxi 100 000 dan arzon mahsulotlar" ni filtrlashga urinasiz — va hech narsa ishlamaydi.

MySQL da har bir ustunning qat'iy turi bor. Narx ustuniga faqat son, sana ustuniga faqat sana yoziladi. Bu cheklov emas — bu kafolat: bazadagi ma'lumot har doim ishlatishga yaroqli.

To'g'ri tur tanlash uchta narsaga ta'sir qiladi: to'g'rilik (noto'g'ri ma'lumot kirmaydi), hajm (diskda kam joy), tezlik (kichik turlar tezroq qidiriladi).


Butun sonlar

Tur Hajmi Diapazon (SIGNED) UNSIGNED
TINYINT 1 bayt -128 … 127 0 … 255
SMALLINT 2 bayt -32 768 … 32 767 0 … 65 535
MEDIUMINT 3 bayt ~ ±8 mln 0 … ~16 mln
INT 4 bayt ~ ±2.1 mlrd 0 … ~4.2 mlrd
BIGINT 8 bayt ~ ±9.2 × 10¹⁸ 0 … ~1.8 × 10¹⁹

UNSIGNED — faqat musbat sonlar, diapazon ikki baravar katta:

CREATE TABLE mahsulotlar (
    id      INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    soni    SMALLINT UNSIGNED NOT NULL DEFAULT 0,   -- ombordagi soni, 65 mingdan oshmaydi
    narx    INT UNSIGNED NOT NULL,                  -- so'mda
    reyting TINYINT UNSIGNED                         -- 1-5
);

Qanday tanlash:

  • id — INT UNSIGNED (4 mlrd yozuv) yoki juda katta jadvallar uchun BIGINT UNSIGNED
  • Yosh, reyting, foiz — TINYINT UNSIGNED
  • Pul (so'mda) — INT UNSIGNED yoki BIGINT (milliardlab summa bo'lsa)

[!INFO] INT(11) dagi 11 — hajm emas, eski "ko'rsatish kengligi". MySQL 8 da u eskirgan va hech narsaga ta'sir qilmaydi. Shunchaki INT yozing.


Kasr sonlar

Tur Aniqlik Qachon
DECIMAL(M, D) Aniq Pul, foiz, hisob-kitob
FLOAT Taxminiy (~7 raqam) Ilmiy o'lchovlar
DOUBLE Taxminiy (~15 raqam) Koordinatalar, statistika
narx      DECIMAL(12, 2),   -- 12 ta raqam, shundan 2 tasi verguldan keyin: 9 999 999 999.99
kenglik   DOUBLE,           -- GPS: 41.311081

Nima uchun pul uchun FLOAT emas?

SELECT CAST(0.1 AS FLOAT) + CAST(0.2 AS FLOAT);   -- 0.30000000447034836
SELECT CAST(0.1 AS DECIMAL(5,2)) + CAST(0.2 AS DECIMAL(5,2));   -- 0.30

FLOAT ikkilik tizimda taxminiy saqlaydi. Million tranzaksiyadan keyin tiyinlar "yo'qolib" yoki "paydo bo'lib" qoladi. Pul — faqat DECIMAL yoki butun son (tiyinlarda).


Matn turlari

Tur Maksimal hajm Xususiyati
CHAR(n) 255 belgi Qat'iy uzunlik, bo'sh joylar bilan to'ldiriladi
VARCHAR(n) 65 535 bayt O'zgaruvchan uzunlik — faqat kerakli joy
TEXT 64 KB Uzun matn
MEDIUMTEXT 16 MB Juda uzun matn
LONGTEXT 4 GB Ulkan matn
CREATE TABLE mijozlar (
    id          INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    ism         VARCHAR(100) NOT NULL,
    email       VARCHAR(255) NOT NULL,
    telefon     VARCHAR(20),          -- son emas! "+998 90 ..." va boshidagi 0
    viloyat_kod CHAR(2),              -- har doim 2 belgi: 'TK', 'SM'
    izoh        TEXT
);

Qoidalar:

  • Ko'pchilik holatda — VARCHAR(n). n — belgilar soni, bayt emas
  • Uzunligi doim bir xil (kodlar, xeshlar) — CHAR(n)
  • Maqola matni, tavsif — TEXT
  • Telefon, pasport, indeks — VARCHAR, son emas. Ular bilan hisob-kitob qilinmaydi, boshida 0 yoki + bo'lishi mumkin

Kodlash — utf8mb4

CREATE DATABASE dokon CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
  • utf8mb4 — to'liq Unicode: lotin, kirill, arab, emoji 😊
  • utf8 (yoki utf8mb3) — eski va cheklangan, emoji saqlay olmaydi. Ishlatmang
  • MySQL 8 da utf8mb4 — standart

Collation — matnlarni solishtirish va saralash qoidasi:

  • _ai — accent insensitive: e = é
  • _ci — case insensitive: Ali = ali
  • _bin — baytma-bayt, harfga sezgir

utf8mb4_0900_ai_ci bilan WHERE email = 'ALI@MAIL.UZ' kichik harfli emailni ham topadi.


Sana va vaqt

Tur Format Diapazon Qachon
DATE 2026-11-02 1000 – 9999 Tug'ilgan kun, muddat
TIME 14:30:00 Ish vaqti
DATETIME 2026-11-02 14:30:00 1000 – 9999 Hodisa vaqti
TIMESTAMP 2026-11-02 14:30:00 1970 – 2038 Tizim vaqt belgilari
YEAR 2026 1901 – 2155 Ishlab chiqarilgan yil
CREATE TABLE buyurtmalar (
    id           INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    yetkazish    DATE,
    yaratilgan   DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    yangilangan  DATETIME NULL ON UPDATE CURRENT_TIMESTAMP
);

DATETIME va TIMESTAMP farqi

DATETIME TIMESTAMP
Vaqt mintaqasi Yozilganidek saqlaydi UTC ga o'giradi, o'qishda sessiya mintaqasiga qaytaradi
Diapazon 1000 – 9999 1970 – 2038-yil 19-yanvar

TIMESTAMP ning 2038-yil chegarasi bor. Yangi loyihalarda ko'pincha DATETIME tanlanadi va vaqt UTC da saqlanadi (ilova darajasida).


BOOLEAN

MySQL da haqiqiy mantiqiy tur yo'q. BOOLEAN — bu TINYINT(1) ning taxallusi:

CREATE TABLE foydalanuvchilar (
    faol BOOLEAN NOT NULL DEFAULT TRUE
);

INSERT INTO foydalanuvchilar (faol) VALUES (TRUE), (FALSE);
SELECT faol FROM foydalanuvchilar;   -- 1, 0

TRUE = 1, FALSE = 0. Ilovada (PHP, Node) siz 1/0 olasiz — kerak bo'lsa bool ga aylantiring.


ENUM — cheklangan ro'yxat

CREATE TABLE buyurtmalar (
    holat ENUM('yangi', 'tolangan', 'yolda', 'yetkazildi', 'bekor') NOT NULL DEFAULT 'yangi'
);

INSERT INTO buyurtmalar (holat) VALUES ('tolangan');   -- ✅
INSERT INTO buyurtmalar (holat) VALUES ('payed');      -- ❌ Data truncated for column 'holat'

Afzalligi: noto'g'ri qiymat kira olmaydi, diskda 1-2 bayt.

Kamchiligi: yangi qiymat qo'shish uchun ALTER TABLE kerak — katta jadvalda bu sekin. Qiymatlar tez-tez o'zgarsa — alohida jadval (holatlar) va foreign key yaxshiroq.


JSON

MySQL 5.7 dan boshlab — haqiqiy JSON turi:

CREATE TABLE mahsulotlar (
    id            INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    nom           VARCHAR(200) NOT NULL,
    xususiyatlar  JSON
);

INSERT INTO mahsulotlar (nom, xususiyatlar) VALUES
    ('Telefon', '{"rang": "qora", "xotira": 128, "5g": true}'),
    ('Futbolka', '{"rang": "oq", "olcham": ["S", "M", "L"]}');

SELECT nom, xususiyatlar->>'$.rang' AS rang FROM mahsulotlar;
-- Telefon  | qora
-- Futbolka | oq

SELECT nom FROM mahsulotlar WHERE xususiyatlar->>'$.xotira' >= 128;
  • MySQL JSON ni saqlashdan oldin tekshiradi — buzilgan JSON kirmaydi
  • -> — JSON qiymat, ->> — oddiy matn sifatida

Qachon ishlatish: har xil mahsulotlarning har xil xususiyatlari (telefonda xotira, kiyimda o'lcham). Qachon ishlatmaslik: muntazam qidiriladigan, filtrlanadigan asosiy maydonlar uchun — ular oddiy ustun bo'lsin.


NULL — "qiymat yo'q"

NULL — bu 0 ham emas, '' ham emas. Bu "noma'lum" yoki "kiritilmagan".

telefon VARCHAR(20) NULL,       -- kiritilmagan bo'lishi mumkin
email   VARCHAR(255) NOT NULL,  -- majburiy

Qoida: ustun majburiy bo'lsa — doim NOT NULL yozing. NULL lar so'rovlarda nozik xatolarga olib keladi (10-darsda IS NULL ni ko'ramiz).


Nima uchun shunday?

Nima uchun turni oldindan aniq belgilash kerak — PHP va JavaScript kabi dinamik bo'lsa qulay emasmi?

Ilovadagi o'zgaruvchi bir necha millisekund yashaydi. Bazadagi ma'lumot esa yillar davomida yashaydi va uni o'nlab dastur, yuzlab dasturchi o'qiydi. Agar narx ustunida bir marta "kelishiladi" degan matn paydo bo'lsa — keyingi 5 yil davomida har bir hisobot, har bir so'rov buni hisobga olishi kerak bo'ladi. Qat'iy turlar — bazani ishonchli haqiqat manbai ga aylantiradi. Bundan tashqari, MySQL turini bilsa — uni ixcham saqlaydi va tez qidiradi.


Xulosa

Eslab qoling:

  • Butun son: TINYINT, INT, BIGINT; manfiy bo'lmasa UNSIGNED
  • Pul: DECIMAL(12,2) yoki tiyinda INT — hech qachon FLOAT
  • Matn: VARCHAR(n) asosiy tanlov; telefon va kodlar ham VARCHAR
  • Kodlash: doim utf8mb4
  • Sana: DATE, DATETIME; TIMESTAMP 2038-yilda tugaydi
  • BOOLEAN = TINYINT(1)
  • ENUM — kichik, kam o'zgaradigan ro'yxat; JSON — moslashuvchan xususiyatlar
  • Majburiy ustun — NOT NULL

Keyingi dars

5-dars: CREATE DATABASE, CREATE TABLE — sintaksis va qoidalar