MySQL / JSON өгөгдөл MySQL-д

JSON өгөгдөл MySQL-д

MySQL 5.7.8-аас JSON өгөгдлийн төрлийг дэмжиж эхэлсэн. Бүтэц нь тогтмол биш өгөгдөл — хэрэглэгчийн тохиргоо, бараанд нэмэлт шинж чанар, лог зэргийг хадгалахад тохиромжтой.

JSON column үүсгэх

sql
CREATE TABLE products (
  id         INT PRIMARY KEY AUTO_INCREMENT,
  name       VARCHAR(200) NOT NULL,
  price      DECIMAL(10,2),
  attributes JSON
);

INSERT INTO products (name, price, attributes) VALUES
  ('Зөөврийн компьютер', 2500000, '{
    "brand": "Dell",
    "ram": 16,
    "storage": "512GB SSD",
    "colors": ["цагаан", "хар"],
    "warranty": {"years": 2, "type": "full"}
  }'),
  ('Утас', 1200000, '{
    "brand": "Samsung",
    "ram": 8,
    "storage": "256GB",
    "colors": ["цэнхэр", "ногоон", "улаан"],
    "warranty": {"years": 1, "type": "limited"}
  }');

MySQL нь JSON-г хадгалахдаа формат шалгаж, буруу JSON бол алдаа буцаана.

JSON_EXTRACT — утга унших

sql
-- JSON_EXTRACT(багана, '$.зам')
SELECT name, JSON_EXTRACT(attributes, '$.brand') AS брэнд
FROM products;

-- Богино хэлбэр: -> оператор
SELECT name, attributes->'$.brand' AS брэнд
FROM products;

-- Хашилтгүй богино хэлбэр: ->> оператор (хамгийн түгээмэл)
SELECT name, attributes->>'$.brand' AS брэнд
FROM products;
код
name              | брэнд
------------------|------
Зөөврийн компьютер | Dell
Утас              | Samsung

-> нь "Dell" (хашилттай), ->>' нь Dell (хашилтгүй) буцаана — харьцуулалтад ->>' ашиглах нь дээр.

Nested object ба array

sql
-- Дотоод объект
SELECT name, attributes->>'$.warranty.years' AS баталгааны_жил
FROM products;

-- Array-н элемент (0-оос эхэлнэ)
SELECT name, attributes->>'$.colors[0]' AS эхний_өнгө
FROM products;

-- Array-н бүх элемент
SELECT name, JSON_EXTRACT(attributes, '$.colors') AS өнгөнүүд
FROM products;

WHERE дотор JSON

sql
-- JSON утгаар шүүх
SELECT name, price
FROM products
WHERE attributes->>'$.brand' = 'Dell';

-- Тоон харьцуулалт
SELECT name
FROM products
WHERE CAST(attributes->>'$.ram' AS UNSIGNED) >= 16;

-- Array-д тодорхой утга байгаа эсэх
SELECT name
FROM products
WHERE JSON_CONTAINS(attributes->'$.colors', '"хар"');

JSON_SET — утга өөрчлөх

sql
-- Нэг утга өөрчлөх
UPDATE products
SET attributes = JSON_SET(attributes, '$.ram', 32)
WHERE id = 1;

-- Олон утга нэгэн зэрэг өөрчлөх
UPDATE products
SET attributes = JSON_SET(
  attributes,
  '$.ram', 32,
  '$.storage', '1TB SSD',
  '$.updated', NOW()
)
WHERE id = 1;

| Функц | Утга | | -------------- | ------------------------------------------------ | | JSON_SET | Утга тавих (байгаа бол дарна, байхгүй бол нэмнэ) | | JSON_INSERT | Зөвхөн байхгүй key нэмнэ | | JSON_REPLACE | Зөвхөн байгаа key-г өөрчлөнө | | JSON_REMOVE | Key устгана |

sql
-- Key устгах
UPDATE products
SET attributes = JSON_REMOVE(attributes, '$.warranty')
WHERE id = 2;

JSON_OBJECT ба JSON_ARRAY үүсгэх

sql
-- JSON объект үүсгэх
SELECT JSON_OBJECT(
  'нэр', 'Болд',
  'нас', 25,
  'хот', 'Улаанбаатар'
) AS хэрэглэгч;
-- Үр дүн: {"нас": 25, "нэр": "Болд", "хот": "Улаанбаатар"}

-- JSON array үүсгэх
SELECT JSON_ARRAY('улаан', 'ногоон', 'цэнхэр') AS өнгөнүүд;
-- Үр дүн: ["улаан", "ногоон", "цэнхэр"]

-- Хүснэгтийн мөрүүдийг JSON array болгох
SELECT JSON_ARRAYAGG(name) AS бараанууд FROM products;
-- Үр дүн: ["Зөөврийн компьютер", "Утас"]

Virtual column — JSON дээр index

JSON баганад шууд index тавих боломжгүй. Virtual column ашиглан шийднэ:

sql
ALTER TABLE products
  ADD COLUMN brand VARCHAR(50)
    GENERATED ALWAYS AS (attributes->>'$.brand') VIRTUAL;

-- Virtual column дээр index
CREATE INDEX idx_brand ON products (brand);

-- Одоо index ашиглан хурдан хайна
SELECT name, price FROM products WHERE brand = 'Dell';

GENERATED ALWAYS AS нь утгыг автоматаар тооцоолно — гараар оруулах шаардлагагүй. VIRTUAL нь дискэнд хадгалдаггүй, STORED нь хадгалдаг.

JSON бусад хэрэгтэй функцүүд

sql
-- JSON хүчинтэй эсэх шалгах
SELECT JSON_VALID('{"key": "value"}');  -- 1
SELECT JSON_VALID('{key: value}');      -- 0

-- JSON-н гүн
SELECT JSON_DEPTH(attributes) FROM products;

-- Key байгаа эсэх
SELECT JSON_CONTAINS_PATH(attributes, 'one', '$.warranty') AS warranty_байгаа
FROM products;

-- JSON хэвлэх (унших ойлгомжтой болгох)
SELECT JSON_PRETTY(attributes) FROM products WHERE id = 1;

Хэзээ JSON column ашиглах вэ?

JSON column тохиромжтой:

  • Бараа бүрт өөр өөр шинж чанар (утас → чадал, ном → зохиогч, хувцас → хэмжээ)
  • Хэрэглэгчийн тохиргоо, хандалт
  • Гуравдагч талын API-н хариу хадгалах

JSON column тохиромжгүй:

  • Байнга шүүгддэг, JOIN хийгддэг өгөгдөл → ердийн багана дээр
  • Гүйцэтгэл чухал том хүснэгт → ердийн бүтэц хурдан

Дараагийн хичээлд:

Full-text search — FULLTEXT index ашиглан монгол болон бусад текст дотор хурдан хайлт хийх аргыг үзнэ.