2.1 char vs string in Practice
ใน Module 0 เราเรียนว่า char คือตัวอักษรเดียว string คือ list ของ characters ตอนนี้ถึงเวลาเอามาใช้จริง — และดูว่าเรื่องนี้สร้างปัญหาอะไรเวลาข้อมูลเดินทางข้ามเครื่องมือ
ทบทวนจาก Module 0
Section titled “ทบทวนจาก Module 0”| คำ | ความหมาย | ตัวอย่าง |
|---|---|---|
| char | ตัวอักษร 1 ตัว | 'A', 'ก', '5' |
| string | ลำดับของ characters | "Hello", "00123", "สวัสดี" |
| fixed-width | จองพื้นที่ตายตัว | C: char[5], SQL: CHAR(5) |
| variable-width | ใช้พื้นที่ตามจริง | C: char*, SQL: VARCHAR(100) |
ปัญหาจริง: ข้อมูลย้ามเครื่องมือ
Section titled “ปัญหาจริง: ข้อมูลย้ามเครื่องมือ”สมมติคุณมี country code "TH" ที่เก็บแบบนี้:
- Python:
country = "TH"— 2 chars, variable - SQL column:
CHAR(5)— เก็บเป็น"TH "(เติม 3 spaces)
เวลา Python ส่ง "TH" ไปเก็บใน SQL CHAR(5) แล้ว query กลับมา → อาจได้ "TH " (5 chars) แทน "TH" (2 chars) — JOIN กับ Python data อาจล้มเหลว!
Sheets ถือว่า text ทุกชิ้นเป็น variable-width — ไม่มีความแตกต่าง char กับ string:
| เซลล์ | ค่า | =LEN(...) | หมายเหตุ |
|---|---|---|---|
| A1 | A | 1 | ตัวอักษร 1 ตัว |
| A2 | Hello | 5 | 5 ตัวอักษร |
| A3 | TH (มี 3 spaces ต่อท้าย) | 5 | Sheets เก็บ spaces ด้วย |
| A4 | TH | 2 | ไม่มี spaces |
ลองทำ:
=A3=A4 → FALSE (!) — "TH " ≠ "TH"=TRIM(A3)=A4 → TRUE — TRIM ตัด trailing spacesKey insight: Sheets ไม่เติม spaces ให้อัตโนมัติ — แต่ถ้าข้อมูลมาจาก SQL CHAR(n) column, spaces จะติดมา และ Sheets ไม่ตัดให้
ใน C ความแตกต่างระหว่าง char กับ string ชัดเจนที่สุด:
#include <stdio.h>#include <string.h>
int main() { // char = ตัวอักษร 1 ตัว (1 byte) char c = 'A'; printf("char: '%c' (size: %zu byte)\n", c, sizeof(c)); // char: 'A' (size: 1 byte)
// string = array ของ chars + null terminator char greeting[] = "Hello"; printf("string: \"%s\" (sizeof: %zu, strlen: %zu)\n", greeting, sizeof(greeting), strlen(greeting)); // string: "Hello" (sizeof: 6, strlen: 5) // sizeof = 6 เพราะรวม '\0'
// fixed-width char country_fixed[5]; strcpy(country_fixed, "TH"); printf("fixed: \"%s\" (sizeof: %zu, strlen: %zu)\n", country_fixed, sizeof(country_fixed), strlen(country_fixed)); // fixed: "TH" (sizeof: 5, strlen: 2) // จองพื้นที่ 5 bytes แต่ใช้จริงแค่ 3 (T, H, \0)
// variable-width (pointer) char *country_var = "TH"; printf("var: \"%s\" (strlen: %zu)\n", country_var, strlen(country_var)); // var: "TH" (strlen: 2)
// เปรียบเทียบ printf("fixed == var? %d\n", strcmp(country_fixed, country_var) == 0); // 1 (TRUE) — C เปรียบเทียบถึง \0 ไม่สนใจ bytes หลัง \0
return 0;}Key insight: ใน C sizeof บอกพื้นที่ที่จอง strlen บอกความยาวจริง — เหมือน CHAR(n) vs LENGTH() ใน SQL
Python ไม่แยก char กับ string — ทุกอย่างเป็น str:
# Python: char คือ string ที่มี 1 ตัวอักษรc = 'A's = "Hello"print(type(c)) # <class 'str'>print(type(s)) # <class 'str'> — ชนิดเดียวกัน!
# ไม่มี fixed-widthcountry = "TH"print(len(country)) # 2 — ไม่มี padding
# แต่ถ้าข้อมูลมาจาก SQL CHAR(5)...from_sql = "TH " # 5 chars (trailing spaces ติดมา)print(len(from_sql)) # 5 (!)print(country == from_sql) # False (!)
# ต้อง strip เองprint(country == from_sql.strip()) # True
# pandas อ่านจาก SQLimport pandas as pd# สมมติอ่านจาก SQL column CHAR(5)df = pd.DataFrame({'country': ['TH ', 'US ', 'JP ']})print(df['country'].str.strip())# 0 TH# 1 US# 2 JPKey insight: Python ไม่สนใจ width แต่เวลารับข้อมูลจากเครื่องมือที่สนใจ (เช่น SQL CHAR(n)) ต้อง .strip() เสมอ
-- สร้างตาราง 2 columns: fixed vs variableCREATE TABLE countries ( code_fixed CHAR(5), code_var VARCHAR(5));
INSERT INTO countries VALUES ('TH', 'TH');
-- ดูความแตกต่างSELECT code_fixed, code_var, LENGTH(code_fixed) AS fixed_len, LENGTH(code_var) AS var_len, code_fixed = code_var AS are_equal;ผลลัพธ์ (ขึ้นอยู่กับ dialect):
PostgreSQL:
code_fixed | code_var | fixed_len | var_len | are_equalTH | TH | 2 | 2 | truePostgreSQL LENGTH() ไม่นับ trailing spaces ของ CHAR(n) — และเปรียบเทียบโดยตัด trailing spaces ให้อัตโนมัติ
MySQL:
code_fixed | code_var | fixed_len | var_len | are_equalTH | TH | 2 | 2 | 1MySQL ก็ตัด trailing spaces เวลาเปรียบเทียบ
แต่ระวัง! เวลา export ไปเครื่องมืออื่น (CSV, Python) trailing spaces อาจติดไปด้วย
-- ทดสอบกับ LIKESELECT * FROM countries WHERE code_fixed LIKE 'TH%'; -- ✅ เจอSELECT * FROM countries WHERE code_fixed LIKE 'TH'; -- ✅ เจอ (SQL ตัด spaces)SELECT * FROM countries WHERE code_fixed LIKE 'TH '; -- ❓ ขึ้นอยู่กับ dialectเมื่อไหร่ที่ char vs string สำคัญ
Section titled “เมื่อไหร่ที่ char vs string สำคัญ”| สถานการณ์ | สำคัญไหม | ทำไม |
|---|---|---|
| ทำงานแค่ใน Sheets | ไม่ | Sheets ไม่มี fixed-width |
| ทำงานแค่ใน Python | ไม่ | Python ไม่มี char type |
| Python → SQL | ใช่ | SQL อาจ pad spaces ถ้าใช้ CHAR(n) |
| SQL → Python/Sheets | ใช่ | trailing spaces ติดมา ต้อง strip |
| เขียน C | ใช่ | sizeof ≠ strlen, buffer overflow ถ้าจอง bytes ไม่พอ |