ภาพรวม
Data Type SET ใน MySQL เก็บค่าจากชุดที่กำหนดไว้ล่วงหน้า (สูงสุด 64 ค่า) ใช้ร่วม FIND_IN_SET() เพื่อค้นหาได้ง่าย
ไวยากรณ์ SET
SET('value1', 'value2', 'value3', ...)
-- สูงสุด 64 ค่า, เก็บเป็น Bitmap (Bitmask) ภายใน
ตัวอย่างสมบูรณ์
1. สร้างตาราง SET
CREATE TABLE DemoTable (
CountryName SET('US', 'UK', 'AUS')
);
2. Insert ข้อมูล
INSERT INTO DemoTable VALUES ('US');
INSERT INTO DemoTable VALUES ('UK');
3. ข้อมูลในตาราง
SELECT * FROM DemoTable;
+-------------+
| CountryName |
+-------------+
| US |
| UK |
+-------------+
4. ค้นหาด้วย FIND_IN_SET()
SELECT * FROM DemoTable
WHERE FIND_IN_SET('UK', CountryName) > 0;
5. ผลลัพธ์
+-------------+
| CountryName |
+-------------+
| UK |
+-------------+
คุณสมบัติของ SET
- เก็บได้หลายค่าในคอลัมน์เดียว (Multiple values)
- ค่าต้องอยู่ในรายการที่ Define ไว้เท่านั้น
- เก็บภายในเป็น Bitmask (Integer) → ประหยัดพื้นที่ เร็ว
- เรียงลำดับตามที่ Define (ไม่ใช่ลำดับ Insert)
- ไม่รองรับค่าซ้ำ (Distinct โดยอัตโนมัติ)
การใช้งาน SET เพิ่มเติม
Insert หลายค่า
INSERT INTO DemoTable VALUES ('US,UK');
INSERT INTO DemoTable VALUES ('UK,AUS,US');
ค้นหาหลายค่า (OR)
SELECT * FROM DemoTable
WHERE FIND_IN_SET('US', CountryName) > 0
OR FIND_IN_SET('UK', CountryName) > 0;
ค้นหาที่มีทั้งสองค่า (AND)
SELECT * FROM DemoTable
WHERE FIND_IN_SET('US', CountryName) > 0
AND FIND_IN_SET('UK', CountryName) > 0;
SET vs ENUM vs Normalized Table
| คุณสมบัติ | ENUM | SET | Normalized (Many-to-Many) |
|---|---|---|---|
| จำนวนค่าต่อแถว | 1 ค่า | หลายค่า (0-64) | ไม่จำกัด |
| เพิ่มค่าใหม่ | ALTER TABLE | ALTER TABLE | INSERT แถวใหม่ |
| Index/Performance | ดี | พอใช้ (Full Scan) | ดีที่สุด (Index) |
| Query ความซับซ้อน | ง่าย | ปานกลาง | ซับซ้อน (JOIN) |
| Data Integrity | สูง | ปานกลาง | สูงสุด (FK) |
ข้อควรระวัง
FIND_IN_SET()ไม่ใช้ Index → ช้าในตารางใหญ่- เปลี่ยนรายการค่า ต้อง
ALTER TABLE(Lock Table) - ไม่รองรับค่าที่มีจุลภาคภายใน
- MySQL 8.0+ แนะนำใช้ JSON หรือ Normalized Table แทน
สรุป
SET + FIND_IN_SET() ใช้สำหรับข้อมูลหมวดหมู่เล็ก คงที่ ไม่มากกว่า 64 ค่า และตารางไม่ใหญ่มาก สำหรับ Production ควร Normalize