Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MySQL

MySQL LIKE Query กับ Dynamic Array: ค้นหาในคอลัมน์ CSV

สถานการณ์: คอลัมน์เก็บค่าหลายค่าคั่นด้วย Comma

ตาราง demo74: user_names VARCHAR(250) เก็บ "John Smith1,John Smith2,John Smith3"

ไวยากรณ์ LIKE พร้อม Wildcard

SELECT * FROM yourTable
WHERE yourColumn LIKE CONCAT('%', searchValue, '%')
ORDER BY id ASC
LIMIT limitValue;

ตัวอย่างข้อมูล

INSERT INTO demo74 (user_names) VALUES
('John Smith1,John Smith2,John Smith3'),
('John Smith1'),
('David Smith1'),
('John Smith1,John Smith2,John Smith3,John Smith4');

คำสั่งค้นหา "John Smith1"

SELECT * FROM demo74
WHERE user_names LIKE '%John Smith1%'
ORDER BY user_id ASC
LIMIT 100;

ผลลัพธ์ (3 แถว)

+---------+-------------------------------------------------+
| user_id | user_names                                      |
+---------+-------------------------------------------------+
| 1       | John Smith1,John Smith2,John Smith3             |
| 2       | John Smith1                                     |
| 4       | John Smith1,John Smith2,John Smith3,John Smith4 |
+---------+-------------------------------------------------+

ปัญหาของ LIKE '%value%'

  • False Positives: ค้นหา "John" จะเจอ "Johnson", "Johnathan"
  • Full Table Scan: ไม่ใช้ INDEX ได้
  • CSV Boundary: "John Smith1" match "John Smith10" (หากไม่มี Delimiter)

วิธีแก้: ใช้ Delimiter ใน LIKE

WHERE CONCAT(',', user_names, ',') LIKE '%,John Smith1,%'

วิธีที่ดีกว่า: FIND_IN_SET()

SELECT * FROM demo74
WHERE FIND_IN_SET('John Smith1', user_names) > 0;
  • จัดการ CSV Boundary อัตโนมัติ
  • เร็วกว่า LIKE (Internal Optimization)
  • แต่: ต้องไม่มี Space หลัง Comma (ต้องเป็น 'A,B' ไม่ใช่ 'A, B')

แนวทางแก้รากฐาน: Normalization

แทน CSV ใน 1 คอลัมน์ ให้สร้างตารางความสัมพันธ์:

CREATE TABLE user_names (
    user_id INT,
    name VARCHAR(100),
    PRIMARY KEY (user_id, name),
    FOREIGN KEY (user_id) REFERENCES users(id)
);

Query แล้ว JOIN:

SELECT u.* FROM users u
JOIN user_names un ON u.id = un.user_id
WHERE un.name = 'John Smith1';

ประสิทธิภาพเปรียบเทียบ

วิธีความเร็วความแม่นยำใช้ Index
LIKE '%val%'ช้าต่ำ (False +)ไม่ได้
LIKE '%,val,%'ช้าปานกลางไม่ได้
FIND_IN_SETปานกลางสูง (CSV)ไม่ได้
Normalized + JOINเร็วสูงสุดได้ ✅
FULLTEXT INDEXเร็วสูง (Text)ได้ ✅

Spring Boot / Application Layer

ใน Application ให้ Parse CSV → List → ใช้ IN clause หรือ ANY (PostgreSQL) / MEMBER OF (Oracle) แทน