Skip to content

5.1 Schema Contracts

ลองนึกภาพ: ทีม A ส่ง CSV มาให้ทีม B ทีม B เปิดแล้วพบว่า student_id เป็นตัวเลข (leading zeros หาย), phone มีตัวอักษรปน, price เป็น float แทน decimal — ทุกอย่างพัง ถ้ามี “สัญญา” กำกับไว้ตั้งแต่แรก ปัญหาเหล่านี้จะไม่เกิด

เวลาที่ใช้: ~12 นาที

Type contract คือ เอกสารหน้าเดียว ที่ระบุ:

  • ชื่อ column ทั้งหมด
  • data type ที่ถูกต้องของแต่ละ column
  • nullable หรือไม่
  • constraints หรือหมายเหตุพิเศษ

ถ้าทุกคนที่สร้าง อ่าน หรือ import ข้อมูล ทำตามสัญญานี้ — ไม่มีอะไรพัง

ตัวอย่าง Type Contract: ตาราง students

Section titled “ตัวอย่าง Type Contract: ตาราง students”
ColumnTypeRequiredหมายเหตุ
student_idVARCHAR(6)Yesleading zeros! ห้ามเก็บเป็นตัวเลข
nameVARCHAR(100)Yes
phoneVARCHAR(20)Noอนุญาตเฉพาะ digits + '+'
priceNUMERIC(10,2)Yes>= 0, ห้ามใช้ float
enrolled_onDATEYesISO 8601 เท่านั้น (YYYY-MM-DD)
activeBOOLEANYesdefault TRUE
noteTEXTNo

Type Contract ใน 4 เครื่องมือ

Section titled “Type Contract ใน 4 เครื่องมือ”

Google Sheets ไม่มี schema enforcement ในตัว — ทุกอย่างเป็น “ใส่อะไรก็ได้”

วิธีสร้าง contract ใน Sheets:

  1. สร้าง sheet แยกชื่อ _schema เก็บตาราง contract ไว้
  2. ใช้ Data Validation เป็น guard:
    • student_id: Custom formula =AND(LEN(A2)=6, ISNUMBER(VALUE(A2)))
    • price: ตั้ง >= 0
    • enrolled_on: ตั้ง format เป็น Date
    • active: Dropdown → TRUE / FALSE
// ตรวจ student_id ว่า 6 หลักและเป็นตัวเลข
=AND(LEN(A2)=6, ISNUMBER(VALUE(A2)))
// ตรวจ phone ว่ามีแค่ตัวเลขกับ +
=REGEXMATCH(B2, "^[0-9+]+$")

ทำไม Type Contract ถึงสำคัญ

Section titled “ทำไม Type Contract ถึงสำคัญ”
ทีม A สร้าง CSV Type Contract ทีม B import เข้า Sheets ทีม C import เข้า pandas ทีม D load เข้า SQL ข้อมูลถูกต้อง

ถ้า ไม่มี contract:

  • ทีม B เปิด CSV ใน Sheets → leading zeros หาย
  • ทีม C อ่านด้วย pandas → student_id กลายเป็น int64
  • ทีม D load เข้า SQL → price เป็น REAL แทน NUMERIC

ผลลัพธ์: ข้อมูล 3 ที่ ไม่ตรงกัน

  1. เขียน type contract สำหรับตาราง orders ที่มี columns เหล่านี้:

    • order_id (เลข 8 หลัก มี leading zeros)
    • customer_name
    • total_amount (จำนวนเงิน)
    • order_date
    • shipped (จัดส่งแล้วหรือยัง)
  2. ลองเขียน CREATE TABLE statement ใน SQL ที่ตรงกับ contract

  3. ลองเขียน pandas dtype dictionary ที่ตรงกับ contract

ดูเฉลย

Type Contract:

ColumnTypeRequiredหมายเหตุ
order_idVARCHAR(8)Yesleading zeros, ห้ามเป็น int
customer_nameVARCHAR(100)Yes
total_amountNUMERIC(12,2)Yes>= 0
order_dateDATEYesISO 8601
shippedBOOLEANYesdefault FALSE

SQL:

CREATE TABLE orders (
order_id VARCHAR(8) NOT NULL,
customer_name VARCHAR(100) NOT NULL,
total_amount NUMERIC(12,2) NOT NULL CHECK (total_amount >= 0),
order_date DATE NOT NULL,
shipped BOOLEAN NOT NULL DEFAULT FALSE
);

pandas:

ORDER_DTYPES = {
'order_id': 'string',
'customer_name': 'string',
'total_amount': 'Float64',
'order_date': 'string',
'shipped': 'boolean',
}
df = pd.read_csv('orders.csv', dtype=ORDER_DTYPES, parse_dates=['order_date'])