Basic Database System Part 2 - Relational Database Model

Basic Database System Part 2 - Relational Database Model

ในตอนที่แล้วเราได้รู้ว่า Database , Database Model , DBMS คืออะไรกันไปแล้ว ในตอนนี้เราจะมาลงรายละเอียดเกี่ยวกับ Relational Database Model กัน

Relation คืออะไร

ถ้าคุณไปถามคนในวงการคอมพิวเตอร์ว่า Relation คืออะไรในเนื้อหาเกี่ยวกับ Database บางคนอาจจะบอกว่ามันคือความสัมพันธ์ ซึ่งอยากจะบอกว่ามันไม่ใช่นะครับ ตามนิยามแล้ว Relation คือ Subset ของ Cartesian product ของ Domain ( Subset of the Cartesian product of domains ) ซึ่งผมเชื่อว่าหลายคนอ่านแล้วอาจจะไม่เข้าใจ ตอนผมเรียนตอนปี 3 ผมฟังครั้งแรกก็ไม่เข้าใจเหมือนกันครับ ดังนั้นเรามาดูตัวอย่างเพื่อทำความเข้าใจกันดีกว่า

กำหนดให้มี Domain ดังต่อไปนี้ (จะมองว่า Domain คือ Column ก็ได้นะครับ)

Domain : Name มีค่าที่เป็นไปได้คือ : { Wasinee , Sunisa , Thanaporn }

Domain : Subject มีค่าที่เป็นไปได้คือ : { Math , Physic }

Domain : Status มีค่าที่เป็นไปได้คือ : { PASS , FAIL }

Cartesian product ของ Domain ก็คือเอาทุกค่าของแต่ละ Domain มารวมกันในทุกความเป็นไปได้ ซึ่งจะเห็นว่ามีทั้งหมด 12 แบบซึ่งเกิดจาก 3 x 2 x 2 ดังภาพ

Cartesian product ของ Domain

ถ้าสังเกตจะเห็นว่าค่ามันอาจจะดูแปลกๆในความเป็นจริงที่ Wasinee จะสอบผ่านและสอบตกวิชา Physic พร้อมกัน อีกทั้งคนหนึ่งคนไม่จำเป็นต้องสอบทุกวิชาหรือบางคนอาจไม่สอบสักวิชาเลยก็ได้ ซึ่งข้อมูลที่เกิดขึ้นจริงที่จะคือ

ข้อมูลที่เกิดขึ้นจริง

ซึ่งจะเห็นว่าข้อมูลที่เกิดขึ้นจริงนั้นเป็น Subset ของ Cartesian product ของ Domain (คุ้นๆไหม) ดังนั้นข้อมูลที่เกิดขึ้นจริงก็คือ Relation นั่นเอง

คราวนี้คุณก็เข้าใจแล้วนะครับว่า Relation คืออะไร ทำไมต้องเป็น Subset ของ Cartesian product ของ Domain

( อันนี้เรื่องตลกนะครับรู้ไว้เอาฮาไม่รู้ก็ไม่เป็นไร เวลารุ่นพี่รุ่นน้องเด็กวิศวคอมลาดกระบังเจอกันแล้วไม่รู้จักกัน คำถามหนึ่งที่สามารถถามกันเพื่อเช็คว่าเฮ้ยเอ็งใช่รุ่นพี่หรือรุ่นน้องจริงรึเปล่าวะคำถามหนึ่งคือ Relation คืออะไร ซึ่งเด็กวิศวคอมลาดกระบังที่เรียน Database แล้วจะตอบแนวๆนี้หมดครับ )

Relational Database Table

เรารู้แล้วว่า Relation คืออะไร แต่เราจะแสดง Relation ให้คนดูยังไงให้เข้าใจ วิธีที่จะแสดง Relation ให้คนเข้าใจก็คือเอาไปแสดงเป็น Table นั่นเอง จริงๆ Relation มันจะไม่มีการบอกว่าค่าแต่ล่ะค่ามาจาก Domain (Column) อะไร ตัวอย่าง Relation แบบไม่แสดงในตารางจะเป็นแบบด้านล่าง (จริงๆ Relation แสดงได้ด้วยสมการทางคณิตศาสตร์เลยนะครับ)

1
2
3
4
5
Relation = { 
(Wasinee, Math, PASS) ,
(Thanaporn, Math, PASS) ,
(Thanaporn, Physic, FAIL)
}

ดังนั้นเพื่อให้คนทั่วไปเข้าใจ Relation ได้ง่ายขึ้นเขาจึงทำให้มันอยู่ในรูปแบบของ Table ดังภาพที่คุณเห็นตัวอย่างที่ผมอธิบายที่มีหัวตารางเป็นการบอกว่าค่านี้มาจาก Domain (Column) ไหนเพื่อให้เข้าใจง่ายขึ้น คราวนี้ Table ที่แสดง Relation ได้นั้นจะต้องมีคุณสมบัติดังต่อไปนี้

  1. Row ต้องไม่ซ้ำ

  2. ลำดับของ Row ไม่มีความสำคัญ ว่าง่ายๆคือ Row 1 กับ Row 2 สลับที่กันก็ไม่มีความสำคัญ

  3. ลำดับของ Column ไม่มีความสำคัญ ว่าง่ายๆคือ จะสลับ Column 1 กับ Column 2 กันก็ไม่มีผลอะไร

  4. ค่าใน Column นั้นต้องเป็นค่าที่อยู่ใน Domain เดียวกัน ไม่ได้มาจากหลากหลาย Domain

  5. ค่าใน Column ต้องเป็นค่าค่าเดียวไม่ใช่ Set หรือ List

กฎของ Relational Database

ในส่วนที่แล้วเรารู้แล้วว่า Relation คืออะไร หน้าตาเป็นอย่างไร ซึ่งเป็นหนึ่งในส่วนประกอบของ Database model ส่วนต่อมาที่เราต้องรู้คือกฎของ Database นั่นเอง

The Entity Integrity : Primary key must not be NULL

ก็ตามนั้นเลยครับ Primary key ต้องไม่มีค่าเป็น NULL คราวนี้คุณอาจจะสงสัยว่า Primary key คืออะไร NULL คืออะไร เรามาทำความเข้าใจกันทีละตัวครับ เริ่มจาก NULL ก่อน

NULL

สำหรับ NULL นั้นแปลว่าไม่มีค่าหรืออาจจะแปลว่าไม่รู้ก็ได้ครับ ตัวอย่างเช่น Relation ดังภาพด้านล่าง

ตัวอย่างการเก็บค่า NULL

จะเห็นว่า Row : Wasinee นั้นมีค่า Salary เป็น NULL ซึ่งแปลว่าเราไม่รู้ว่าค่า Salary ของ Wasinee เป็นเท่าไหร่

Primary key

ก่อนรู้จัก Primary key เรามารู้จัก Super key ก่อน Super key คือกลุ่มของ Column ที่ใช้เป็นใช้อ้างถึง Row นั้นได้เพียง Row เดียว (ภาษาไทยอธิบายยาก ภาษาอังกฤษเขานิยามไว้แบบนี้น่าจะเข้าใจมากกว่า : A super key is a set of attribute whose value uniquely identifies a tuple ) ผมว่าอ่านที่ผมอธิบายแล้วน่าจะไม่เข้าใจ ดังนั้นดูตัวอย่างน่าจะเข้าใจง่ายกว่า

ตัวอย่าง Table : USER

จากภาพด้านบนเราจะเห็นว่า Table (ขอเรียก Relation เป็น Table เลยนะครับ) นี้มี 3 Column คือ USERNAME , EMAIL , DATE OF BIRTH ถ้าดูตอนนี้เราจะพบว่ามี Super key ทั้งหมดคือ

  1. USERNAME , EMAIL , DATE OF BIRTH

  2. USERNAME , EMAIL

  3. USERNAME , DATE OF BIRTH

  4. EMAIL , DATE OF BIRTH

  5. USERNAME

  6. EMAIL

วิธีพิสูจน์ว่าจริงไหมให้คุณเอาค่าจากกลุ่ม Column เหล่านี้ไปหาใน Table ครับ เวลาเอาค่าไปหามันจะอ้างถึงแค่ Row เดียวเสมอ ซึ่งจะเห็นว่า DATE OF BIRTH Column เดียวไม่สามารถอ้างถึง Row ได้แค่ Row เดียวดูได้จากถ้าอ้างด้วย 1990-05-16 จะอ้างถึงได้ 2 Row

ต่อไปเรามารู้จัก Candidate Key ซึ่งก็คือ Super key ที่ไม่มี Super key อื่นเป็น Subset (นิยามภาษาอังกฤษน่าจะเข้าใจง่ายกว่า : A candidate key is defined as a superkey which has no other superkeys as a subset (or has no superkeys as its proper subset) ) ก็ตามเดิมครับอ่านแล้วไม่เข้าใจมาดูตัวอย่างกันดีกว่า เรามาไล่พิจารณาจาก Super key ที่เราหาได้จากตัวอย่างที่แล้วว่ามีอันไหนเป็น Candidate Key ได้บ้าง

  1. USERNAME , EMAIL , DATE OF BIRTH

    ไม่เป็น Candidate key เพราะมี Super key อื่นเป็น Subset ดูได้จาก Super key { USERNAME , EMAIL } ที่เป็น Subset

  2. USERNAME , EMAIL

    ไม่เป็น Candidate key เพราะมี Super key อื่นเป็น Subset ดูได้จาก Super key { USERNAME } ที่เป็น Subset

  3. USERNAME , DATE OF BIRTH

    ไม่เป็น Candidate key เพราะมี Super key อื่นเป็น Subset ดูได้จาก Super key { USERNAME } ที่เป็น Subset

  4. EMAIL , DATE OF BIRTH

    ไม่เป็น Candidate key เพราะมี Super key อื่นเป็น Subset ดูได้จาก Super key { EMAIL } ที่เป็น Subset

  5. USERNAME

    เป็น Candidate key เพราะไม่มี Super key อื่นเป็น Subset

  6. EMAIL

    เป็น Candidate key เพราะไม่มี Super key อื่นเป็น Subset

ทั้งหมดที่อธิบายนั้นปูทางมาเพื่ออธิบายว่า Primary key คือตัวหลักที่ใช้อ้างอิงถึง Row นั้นโดยเราจะเลือกตัวอ้างอิงหลักนี้มาจาก Candidate key ( การแปลเป็นไทยมันยากมาก ผมว่าอ่านนิยามภาษาอังกฤษเข้าใจง่ายกว่า The primary key is the principle identifier of the relation; and is simply defined as a selected by candidate key ) ถ้าจากตัวอย่างด้านบนเราสามารถกำหนด Primary key ได้จาก USERNAME หรือ EMAIL ซึ่งเป็น Candidate key ครับ

สมมติถ้าเราเลือก USENAME เป็น Primary key Column USERNAME จะต้องไม่มีค่าเป็น NULL ครับ นี่คือ กฎที่ว่า Primary key must not be NULL

ตรงนี้อาจจะมีคนสงสัยว่าทำไมต้องห้าม Primary key มีค่าเป็น NULL ลองอ่านกฎข้อต่อไปครับจะเข้าใจ

The Referential Integrity : Foreign key values must match primary key values or be null

Foreign key is defined as nonkey attribute(s) in a relation which is the primary key of other relation or the same relation. A non key attribute is define as an attribute which is not a candidate key.

ผมว่าเริ่มด้วยนิยาม Foreign key แบบภาษาอังกฤษเลยดีกว่าถ้าเข้าใจแล้วจะได้ไม่ต้องเสียเวลามาอ่านภาษาไทยที่ผมพยายามจะอธิบาย หากใครอ่านไม่เข้าใจลองมาอ่านที่ผมอธิบายดูครับ

เริ่มจาก non key attribute คือ Column หรือกลุ่มของ Column ที่ไม่ได้เป็น Candidate key (จริงๆ Column มันคือ Attribute นั่นแหละ ถ้าตามทฤษฎีเราต้องเรียก Column ว่า Attribute เรียก Row ว่า Tuple แต่ขอละเป็น Column ละกันนะ)

Foreign key คือ Column หรือ กลุ่มของ Column ที่ไม่ได้เป็น Candidate key ของ Relation ปัจจุบัน (ที่ Foreign key นี้อยู่ ) ซึ่ง Column หรือกลุ่มของ Column นั้นต้องอ้างอิงถึง Primary key ของ Relation อื่นหรือ Relation เดียวกัน อ่านแล้วอาจจะงง (แน่นอนผมก็งง) ลองไปดูตัวอย่างดีกว่าครับ ของแบบนี้ดูตัวอย่างน่าจะเข้าใจง่ายกว่า

ตัวอย่าง Foreign key

จากภาพด้านบนเราจะเห็นว่ามี Table : Book ที่เก็บข้อมูลเกี่ยวกับการยืมหนังสือ คราวนี้สังเกตที่ Column : Borrow By ที่เป็น Column ที่บอกว่าใครเป็นคนยืม โดยตัว Column นี้ต้องการอ้างอิงถึง Primary key ของ Table : User ที่เก็บข้อมูลผู้ใช้ ดังนั้นเมื่อต้องการอ้างอิงแบบนี้ตัว Column : Borrow By จะกลายเป็น Foreign key

คราวนี้เรามาลองตรวจดูว่า Column : Borrow By เป็น Foreign key ได้หรือไม่

  1. Column หรือ กลุ่มของ Column ไม่ได้เป็น Candidate key

    จากตัวอย่างจะเห็นว่า Column : Borrow By นี้ไม่ได้เป็น Candidate key (ดูได้จากถ้าหา Row ด้วยค่าของ Column นี้จะผลลัพธ์ออกมามากกว่า 1 Row )

  2. อ้างอิงถึง Primary key ของ Relation อื่นหรือ Relation ตัวเอง

    จากตัวอย่าง Column : BORROW BY อ้างอิงถึง Column : USERNAME ซึ่งเป็น Primary key ของ Table : USER

ถ้าเราเลือก Column : Borrow By จะเป็น Foreign key ดังนั้นค่าที่อยู่ใน Column : Borrow By จะต้องมีค่าจริงๆอยู่ใน Table : USER Columnn : USERNAME หรือไม่ก็มีค่าเป็น NULL ซึ่งจากในตัวอย่างจะเห็นว่าค่าใน Column : Borrow By มีค่าตรงกับ Column : USERNAME หรือไม่ก็มีค่า NULL นี่แหละครับ นี่คือตัวอย่างของกฎที่ว่า Foreign key values must match primary key values or be null

สำหรับใครที่สงสัยว่าทำไมกฎข้อแรกบอกว่า Primary key ห้ามมีค่าเป็น NULL ตรงนี้น่าจะเข้าใจแล้วนะครับ เพราะถ้าเรายอมให้ค่า Primary key มีค่าเป็น NULL ได้ เวลามี Row นั้นไม่มีได้ต้องการอ้างอิงถึงอีก Table เช่นถ้าจากตัวอย่างคือหนังสือเล่มนี้ไม่ได้ถูกยืม พอไม่ถูกยืมเลยจะกำหนดค่า BORROW BY เป็น NULL คราวนี้ถ้าเรายอมให้ Primary key มีค่าเป็น NULL ได้มันก็กลายเป็นว่าจะอ้างอิงถึง Row ที่ Primary key มีค่าเป็นค่า NULL ซึ่งนั่นไม่ใช่สิ่งที่เราต้องการ เราต้องการบอกว่าหนังสือไม่มีคนยืมไม่ใช่อ้างอิงถึงหนังสือที่ Primary key มีค่าเป็น NULL ดังนั้นจึงต้องมีการกำหนดให้ Primary key ต้องไม่มีค่าเป็น NULL

ภาษาที่ใช้กับ Relational Database Model

สำหรับภาษาที่นิยมนำมาใช้กับ Relational Database Model นั้นคือภาษา Structured Query Language (SQL) โดยเราสามารถแบ่งภาษา SQL ออกเป็นประเภทตามการใช้งานได้ดังต่อไปนี้

  1. Data Definition Language (DDL)

    คำสั่งประเภทนี้จะเกี่ยวข้องกับการกำหนดโครงสร้างต่างๆของ Database เช่น ทำการสร้าง Database , สร้าง Table แก้ไข Table ลบ Table เป็นต้น โดยคำสั่งพวกนี้จะมี Key word ประมาณ CREATE , ALTER , DROP เรามาดูตัวอย่างคำสั่งเหล่านี้กันครับ

    ตัวอย่างการสร้าง Database

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    CREATE DATABASE PRESIDENT;
    ```

    ตัวอย่างการสร้าง Table

    ```sql
    CREATE TABLE IF NOT EXISTS PRESIDENT (
    `PRES_NAME` VARCHAR(128) ,
    `BIRTH_YR` INT,
    `YRS_SERV` INT,
    `DEATH_AGE` INT ,
    `PARTY` VARCHAR(128) ,
    `STATE_BORN` VARCHAR(128)
    );
  2. Data Manipulation Language (DML)

    คำสั่งเหล่านี้จะเป็นคำสั่งเกี่ยวกับการ ค้นหา เพิ่ม ลบ แก้ไข ข้อมูล เช่น ต้องการค้นหาข้อมูลใน Table ภายใต้เงื่อนไขต่างๆ หรือ ต้องการเพิ่มข้อมูลเข้าไปใน Table โดยคำสั่งประเภทนี้จะมี Key word ประมาณ SELECT , UPDATE , DELETE , INSERT

    ตัวอย่าง คำสั่ง INSERT ที่ต้องการเพิ่มข้อมูล Table PRESIDENT

    1
    2
    3
    4
    INSERT INTO PRESIDENT VALUES
    ('Washington G',1732,7,'67','Federalist','Virginia'),
    ('Adams J',1735,4,'90','Federalist','Massachusetts'),
    ('Jefferson T',1743,8,'83','Demo-Rep','Virginia');

    ตัวอย่าง คำสั่ง SELECT ที่ทำการค้นหาข้อมูลที่ใน Table : PRESIDENT ภายใต้เงื่อนไขที่ว่า PARTY = ‘Federalist’

    1
    2
    3
    SELECT *
    FROM PRESIDENT
    WHERE PARTY = 'Federalist';

    ตัวอย่าง คำสั่ง UPDATE ทำการแก้ไขข้อมูล YRS_SERV ที่ ROW ที่มีค่า PRES_NAME = ‘Washington G’

    1
    2
    3
    UPDATE PRESIDENT 
    SET YRS_SERV = 5
    WHERE PRES_NAME = 'Washington G';

    ตัวอย่าง คำสั่ง DELETE ลบข้อมูล ROW ที่มีค่า PRES_NAME = ‘Washington G’

    1
    2
    DELETE FROM PRESIDENT
    WHERE PRES_NAME = 'Washington G';

    สำหรับใครอยากเรียนเกี่ยวกับคำสั่ง SQL ประเภท Data Manipulation Language ในส่วนของการ SELECT ผมมีทำคลิปสอนไว้ คุณสามารถไปดูได้ตาม Link นี้เลยครับ

  3. Data Control Language (DCL)

    คำสั่งจำพวกนี้จะเป็นคำสั่งเกี่ยวกับการกำหนดสิทธิ์ เช่น กำหนดสิทธิ์ให้สามารถทำอะไรกับ Database ได้บ้าง เช่น SELECT ข้อมูลใน Table ได้ไหม DELETE ข้อมูลใน Table ได้ โดย Key word ของคำสั่งประเภทนี้จะเป็น GRANT , REVOKE

  4. Transaction Control Language (TCL)

    คำสั่งประเภทนี้เป็นคำสั่งที่เกี่ยวกับ Transaction ซึ่งจะเกี่ยวกับการสั่งให้ตัว Database บันทึกข้อมูลทั้งหมดที่ได้ทำไป หรือ ทำการคืนค่าทั้งหมดที่เคยกลับไปเหมือนไม่มีอะไรเกิดขึ้น (นิยามของ Transaction ไม่ใช่ที่ผมพูด ผมแค่ยกตัวอย่างว่ามันเอาไปใช้งานยังไง นิยาม Transaction จริงๆเดี๋ยวจะอธิบายในตอนอื่นครับ) โดยคำสั่งประเภทนี้จะมี Keyword ประมาณ COMMIT , ROLLBACK , SET AUTO COMMIT OFF เรามาดูตัวอย่างกันดีกว่า

    ถ้าสมมติเราต้องการแก้ไขค่าข้อมูลของ Table : PRESIDENT โดยทำการแก้ไขข้อมูลโดยต้องการทำการเปลี่ยน YRS_SERV ของ Washington G เป็น 4 และ Jefferson T เป็น 5 เราจะได้คำสั่ง SQL ประมาณนี้

    1
    2
    3
    4
    5
    6
    7
    8

    UPDATE PRESIDENT
    SET YRS_SERV = 4
    WHERE PRES_NAME = 'Washington G';

    UPDATE PRESIDENT
    SET YRS_SERV = 5
    WHERE PRES_NAME = 'Jefferson T';

    ถ้าเราสั่งคำสั่ง SQL แบบนี้ทุกครั้งจะทำการบันทึกทันทีหลังทำการสั่ง คราวนี้คนที่สั่งเราพึ่งค้นพบว่าเขาบอกข้อมูลผิดแล้วอยากให้เราแก้กลับเป็นค่าเดิมก่อนแก้ไข ซึ่งถ้าเราต้องการอะไรแบบนี้เราสามารถทำได้โดยสั่ง SET AUTO COMMIT OFF ตรงนี้จะเป็นการสั่งว่า คำสั่งที่สั่งไปจะยังไม่ถูกบันทึกลง Database แบบสมบูรณ์ (จริงๆมันบันทึกครับแต่บันทึกให้สามารถย้อนกลับได้) จนกว่าจะสั่ง COMMIT ดังนั้นถ้าได้รับคำสั่งให้แก้ไขข้อมูลแล้วเผื่อให้ย้อนกลับได้ถ้ายังไม่ COMMIT เราสามารถสั่งแบบนี้

    1
    2
    3
    4
    5
    6
    7
    8
    9
    SET AUTO COMMIT OFF;

    UPDATE PRESIDENT
    SET YRS_SERV = 4
    WHERE PRES_NAME = 'Washington G';

    UPDATE PRESIDENT
    SET YRS_SERV = 5
    WHERE PRES_NAME = 'Jefferson T';

    คราวนี้เมื่อสั่งเสร็จคุณอาจจะรอ Confirm กับคนสั่งอีกรอบ ถ้าคนสั่งตรวจทานแล้วข้อมูลถูกต้องแน่นอนคุณก็แค่สั่ง COMMIT ข้อมูลจะถูกบันทึกลง Database แบบสมบูรณ์

    1
    COMMIT;

    แต่ถ้าคนสั่งเขาตรวจอีกรอบแล้วข้อมูลไม่ถูกต้องเขาบอกให้เราแก้ไขข้อมูลกลับไปก่อนมีการแก้ไขเราก็แค่สั่ง ROLLBACK ข้อมูลจะถูกย้อนกลับไปตอนหลังสั่ง SET AUTO COMMIT OFF;

    1
    ROLLBACK;

สรุป

สำหรับตอนนี้เราได้ลงรายละเอียดของ Relational Database Model ตั้งแต่ Relation คืออะไร เราจะเห็นข้อมูลของ Relation ในรูปแบบไหน กฎของ Relational Database model ว่ามีอะไรบ้าง Primary key คืออะไร Foreign key และสุดท้ายมาจบด้วยภาษา SQL ที่ใช้ทำงานกับ Relational Database Model ในตอนถัดไปเรามาพูดถึงเรื่อง Normalization ว่ามันคืออะไร สำคัญอย่างไรกันครับ

Ref

  • นิยามที่เป็นภาษาอังกฤษทั้งหมดเอามาจาก หนังสือ Relational database systems : language, conceptual modeling and design for engineers ผมแนะนำเป็นอย่างยิ่งให้ไปหาเล่มเต็มมาอ่าน อธิบายดีกว่าที่ผมเขียนเยอะมากครับ

Basic Database System Part 1 - Database , Database model , DBMS คืออะไร

Basic Database System Part 1 - Database , Database model , DBMS คืออะไร

เกริ่นก่อนเข้าเรื่อง

ก่อนจะเริ่มอ่านสิ่งที่ผมเขียนในตอนนี้และตอนต่อๆไป ผมอยากออกตัวก่อนเลยว่าสิ่งที่ผมเขียนอาจจะไม่ถูกต้อง 100% ตามทฤษฎี เพราะผมก็ไม่ใช่อาจารย์ที่สอนวิชานี้โดยตรง (ผมเป็นแค่โปรแกรมเมอร์ธรรมดา) แต่สิ่งที่ผมสอนผมอ้างอิงจากหนังสือกับความรู้ที่เคยเรียนกับอาจารย์ตั้งแต่อยู่สมัยปี 3 แต่ความรู้ที่อาจารย์สอนตอนนั้นเป็นความรู้ที่สามารถเอามาใช้ได้ถึงปัจจุบัน

ส่วนทำไมถึงมาเขียนหัวข้อนี้คือผมอยากจะใช้มันสอนเด็กที่เรียนคอมพิวเตอร์ที่จะต้องมาทำงานด้วยและเป็นแหล่งความรู้ให้กับคนที่อยากเรียนรู้เกี่ยวกับ Database ได้มาเรียนรู้ ผมเห็นคอร์สสอนบางคอร์สมีราคาหลายพันบาทเด็กหรือคนหลายๆคนอาจจะไม่มีเงินพอไปซื้อคอร์สเรียน ผมก็เลยคิดว่าทำเนื้อหานี้ขึ้นมาน่าจะมีประโยชน์กับคนเหล่านี้

Database คืออะไร

ถ้าพูดถึงนิยาม Database นี่ยากเลยครับ แต่ถ้าตามหนังสือที่ผมอ่าน Database นั้นคือที่ที่เก็บข้อมูล โดยข้อมูลที่เก็บนั้นจะเป็นความจริง ความจริงในที่นี้หมายถึงสิ่งที่เราคิดว่ามันจริง เช่น เราเก็บข้อมูลวันเกิดของ User ที่กรอก เราไม่รู้ว่ามันจริงแบบจริงไหม แต่ถ้าเก็บลง Database เราเชื่อว่าจริง ( กรอกข้อมูลผิดมาเราก็เชื่อว่าจริง App แปลงค่าผิดเราก็คิดว่ามันจริง ) ถามว่าทำไมต้องเก็บแต่ความจริง คือถ้าเราเก็บเรื่องไม่จริงเนี่ยมันจะเก็บได้ไม่มีวันหมดครับ เช่น ถ้าเราเก็บเรื่องไม่จริงของวันเกิดผมเนี่ย คุณจะสามารถใส่ตั้งแต่ 1 January 1970 ไปจนจักรวาลแตกดับได้เลยซึ่งแน่นอนว่ามันไม่มีทางเก็บได้และที่สำคัญจะเก็บไปทำไม

เมื่อเราเก็บข้อมูลแล้ว คำถามคือเราจะให้ข้อมูลนั้นแสดงให้เราเห็นแบบไหนและเราจะใช้งานมันและปรับเปลี่ยนแก้ไขมันยังไง ลองนึกภาพตามนะครับ ถ้าคุณบอกคุณเก็บข้อมูลวันเกิดผมไว้คำถามคือ ตอนที่คุณเรียกมันมาดูมันจะแสดงเป็นแบบไหน เป็นกราฟ เป็น text ยาวๆ เป็นไฟล์ คราวนี้ถ้าอยากแก้ไขข้อมูลวันเกิดผมคุณจะแก้มันยังไง แก้ตรงไหน หากคุณคิดตามคุณจะเห็นสิ่งที่เกี่ยวข้องกับ Database อย่างแรกคือ 1. เราเห็นข้อมูลยังไง หน้าตาแบบไหน ภาษาทางเทคนิคจะเรียกมันว่า Database model 2. เวลาเราจะจัดการกับ Database เราจะสั่งมันยังไงหรือเรียกง่ายๆว่าภาษาในการคุยกับ Database 3. กฏของ Database model นั้น แต่อธิบายจะเข้าใจยากดูเอาในตัวอย่างดีกว่าครับ

เรามายกตัวอย่าง Database ที่มี Database model ชนิดต่างๆกัน

  1. Hierarchy database

    ภาพจาก theintactone.com

    Database ประเภทนี้จะแสดงข้อมูลเป็นแบบลำดับชั้น อย่างตัวอย่างในภาพเนี่ยจะมีชั้น College ซึ่ง College ก็จะเก็บข้อมูลของ Department ตัว Department ก็จะเก็บข้อมูล Course , Teacher , Students ซ้อนไปเป็นลำดับชั้น เวลาจะหาข้อมูลก็ต้องเข้าไปหาผ่านแต่ละชั้นลงไปเช่น ถ้าอยากจะหาข้อมูล Students ก็ต้องไล่หาจาก College -> Department -> Students ส่วนภาษาที่ใช้กับ Hierarchy database จะเป็นการสั่ง traverse ไปหาข้อมูลตามชั้น ส่วนกฏของ Database model นี้คือ ตัวชั้นลูกจะไม่สามารถมาเป็นชั้นพ่อของชั้นที่อยู่เหนือกว่าได้ตัวอย่างเช่น ชั้น Students จะไม่สามารถมาเป็นพ่อของชั้น Department ได้

  1. Graph Database

    ภาพจาก neo4j.com

    Database ประเภทนี้จะแสดงข้อมูลให้เราเห็นเป็น Graph ซึ่งก็คือจะมี Node ซึ่งจะมี Attribute ต่างๆ แล้วแต่ละ Node สัมพันธ์กันยังไงดูได้จากภาพที่มี Node ที่เป็น Person : Dan , Person : Ann , Car : Volvo มีความสัมพันธ์ Loves กัน คราวนี้ถ้าต้องการหาข้อมูลเช่น อยากหาว่า Person : Dan เนี่ยมีความสัมพันธ์แบบ Loves กับ Node ไหน เราก็มีภาษาในการเข้าถึงข้อมูลประมาณภาพด้านล่างซึ่งเป็นภาษาชื่อ Cypher (โดยหากท่านใดสนใจลงรายละเอียดเกี่ยวกับภาษานี้สามารถกด Link นี้เพื่อไปดูรายละเอียดเพิ่มเติม )

    ภาพจาก neo4j.com

    กฎของ Database model นี้คือทุกความสัมพันธ์จะต้องมีความสัมพันธ์กับ Node ที่มีอยู่จริงจะไม่สามารถให้ Node มีความสัมพันธ์กับ Node ที่ไม่มีจริงได้ เช่น Node Person : DAN เวลาบอกว่ามีความสัมพันธ์แบบ Loves กับ Node ที่มีอยู่จริงเช่น Node Person : Ann จะไม่สามารถบอกว่ามีความสัมพันธ์แบบ Loves กับ Node Person : Wasinee ที่ไม่มีอยู่ใน Database ได้

  2. Relational Database

    ภาพจาก codecademy.com

    Database model นี้จะแสดงข้อมูลให้เราเห็นเป็น Relation ต่างๆ หรือจะให้เข้าใจง่ายๆคือเห็นเป็น “ตาราง” “Table” ( เดี๋ยวเราค่อยอธิบายว่า Relation ในตอนต่อๆไปว่ามันคืออะไร ตอนนี้เข้าใจว่าเป็นตารางไปก่อน ) ดังภาพ จะเห็นว่ามี Table : Product ซึ่งเราดูก็เข้าใจได้เลยว่า Table นี้เก็บข้อมูลของ Product โดยข้อมูลของ Product ประกอบไปด้วย ModelNumber , ProductName , ProductPrice , UnitCost ซึ่งก็คือ Column ส่วน Row ก็คือข้อมูลจริงๆที่ถูกเก็บไว้

    ส่วนภาษาที่เราใช้กับ Database ชนิดนี้คือภาษา SQL ( Structured Query Language ) โดยถ้าเราอยากหาข้อมูล Product ที่มี ProductPrice น้อยกว่า 200.00 ก็จะสามารถเขียนได้เป็นแบบนี้

    1
    2
    3
    SELECT *
    FROM Product
    WHERE ProductPrice < 200.00

    กฏของ Database model นี้คือ Primary key จะต้องไม่มีค่าเป็น NULL ( NULL ในที่นี้คือค่าชนิดหนึ่งที่บอกว่าไม่มีค่า ) หรือว่าง่ายๆคือ Primary key จะต้องมีค่า และ Primary key ต้องไม่มีค่าซ้ำ ส่วน Primary key คืออะไร Primary key คือค่าที่บอกว่า Row นี้แตกต่างจาก Row อื่นและเป็นคนละ Row กัน ถ้าเทียบกับในชีวิตจริงที่เห็นได้ง่ายๆคือ เลขประจำตัวประชาชน 13 หลักที่เราใช้กันนั่นแหละ กฏอีกข้อคือ Foreign Key ที่เชื่อมกันระหว่างตารางนั้นถ้ามีค่าจะต้องเป็นค่าที่มีอยู่จริง ถ้าไม่มีค่าจะต้องเป็นค่า NULL ตัวอย่างในภาพ Table : Sales มี Foreign Key ที่ Column : ModelNumber กับ Column : ModelNumber ที่ Table : Product ดังนั้น ค่า Column : ModelNumber ของ Table : Sales จะต้องมีค่าตรงกับ Column : ModelNumber ที่ Table : Product หรือไม่ก็มีค่า NULL ซึ่งจากภาพตัวอย่างจะเห็นว่าค่าตรงกันหมด

Database model ยังมีอีกมายมาย ไม่ว่าจะเป็นแบบ Object , Key-Value , Document ซึ่งแต่ละชนิดก็มีกฎและภาษาที่ใช้ต่างกัน อีกทั้ง Database model เดียวกันนั้นสามารถเข้ามีภาษาเข้าถึงได้หลายภาษา เช่น Relational Database สามารถใช้ภาษา SQL ในการเข้าถึงข้อมูล แต่จริงๆแล้วเราสามารถใช้ Relational Algebra ในการเข้าถึงข้อมูลก็ได้ แล้วก็สิ่งสำคัญที่สุดก็คือ ไม่มี Database model ไหนดีที่สุดนะครับ แต่ละ Database model ต่างมีข้อดีข้อเสียและเหมาะสมในการใช้งานในงานที่แตกต่างกันไป เช่น ถ้าคุณต้องการทำงานกับที่แสดงผลแบบ Graph แล้วเข้าใจง่าย หรืองานที่เวลาจะหาข้อมูลก็ก็ต้องการหาประมาณว่าต้องการหา Node ที่มีความสัมพันธ์ A กับ Node ที่มีความสัมพันธ์ B ที่มีความสัมพันธ์ C อย่างน้อย 3 Node ถ้าเป็นความต้องการประมาณนี้ Graph Database น่าจะตอบโจทย์กว่า ดังนั้นจะเลือกใช้งาน Database model ไหนก็ขอให้ดูความเหมาะสมและข้อจำกดต่างๆในการตัดสินใจ อย่าไปเชื่อใครที่มาบอกคุณว่า Database Model แบบ Document ดีที่สุด แบบ Graph ดีที่สุด แบบ Relational ดีที่สุด (เพราะส่วนใหญ่จะมาขายของ)

อีกเรื่องที่อยากให้รู้ไว้คือ Database model ที่เราเห็นนั้นไม่จำเป็นต้องเก็บแบบที่เราเห็นจริงๆนะครับ ในความเป็นจริงตัว DBMS จะแปลงตัว Database model ที่เราเห็นไปเก็บในรูปแบบอีกรูปแบบหนึ่งที่มีประสิทธิภาพในการ เพิ่ม ลบ แก้ไข และ ดึง อย่างรวดเร็ว ดังนั้นอย่าเข้าใจผิดว่าการลบข้อมูล Node ใน Graph Database นั้นจะต้องค่อยๆวิ่งไปใน Graph แล้วหา Node ที่ตรงเงื่อนไขแล้วลบ ในความเป็นจริง DBMS อาจจะมี Hash map ที่รู้อยู่แล้วว่า Node ที่ต้องการลบอยู่ไหนแล้วทำการลบเลยก็ได้

DBMS : Database Management System คืออะไร

ในส่วนที่แล้วเราพูดถึงว่า Database คืออะไร Database model คืออะไร คราวนี้เราสมมติว่าเราเขียนโปรแกรมเก่งมาก เราสามารถเขียนโปรแกรมที่ให้เก็บข้อมูลและแสดงผล Database model ได้ตามที่ต้องการ ทุกอย่างเหมือนจะเรียบร้อยแต่จริงๆแล้วมันยังไม่จบครับ เพราะจะมีความต้องการอื่นๆเพิ่มขึ้นมาเช่น ต้องรองรับการใช้งานจากผู้ใช้หลายคน แล้วถ้ามี User หลายคนก็ต้องเพิ่มการ Authentication เข้าไป ทีนี้แต่ละ User ก็อาจเห็นไม่เหมือนกัน ดังนั้นก็ต้องแบ่งสิทธิ์ให้เห็นไม่เท่ากันอีก คราวนี้ถ้ามีคนใช้งานเยอะๆใช้งาน Database พร้อมๆกันก็จะเกิดปัญหาเรื่องใช้การใช้งานพร้อมกัน คนนึงสั่ง Delete คนนึงสั่ง Update ตกลงจะให้อันไหนทำงาน คุณก็ต้องเขียนส่วนที่มาจัดการเรื่องนี้อีก

คราวนี้ลองคิดว่าถ้าคุณจะเขียน Application อะไรสักอย่างขึ้นมา คุณต้องมาเขียนส่วนที่เกี่ยวกับ Database แบบนี้ตลอดทุกครั้งมันก็ดูจะเป็นเรื่องที่ดูแปลกๆที่ต้องมาเขียนอะไรซ้ำๆแบบนี้ทุกครั้ง ดังนั้นเขาเลยแยกส่วนที่เกี่ยวกับการจัดการ Database ออกมาเป็น Application โดยเฉพาะ ดังนั้น Database Management System (DBMS) ก็คือ Application ที่ทำหน้าที่บริหารจัดการเกี่ยวกับ Database คราวนี้พอจะเรียกใช้งานอะไร Database ก็มาเรียกที่ DBMS แทนแล้ว DBMS ไปจัดการต่อให้

โดยหน้าที่หลักๆของ DBMS ส่วนใหญ่จะมีดังต่อไปนี้

  1. บริหารจัดการเก็บข้อมูลและแสดงผลข้อมูลตาม Database model ที่กำหนด เช่น DBMS ที่ใช้ Database model เป็น Relational Database model ก็ต้องรองรับการสั่งผ่านภาษา SQL ได้ เมื่อเรียกให้แสดงข้อมูลก็ต้องแสดงออกมาแบบที่เราสั่งเก็บไปจากตัวอย่างก็ต้องแสดงข้อมูลใน Table ออกมาให้ดูได้

  2. จัดการเรื่องสิทธิ์ของการเข้าถึงข้อมูลต่างๆใน Database ของ User ซึ่งแต่ละ User อาจจะมีสิทธิ์ไม่เท่ากัน เช่น User : Shopping Application อาจจะเข้าถึง Table ที่เกี่ยวกับสินค้าได้เท่านั้นไม่สามารถเข้าถึง Table ที่เกี่ยวกับการจ่ายเงินได้ ส่วน User : Payment application อาจจะเห็นข้อมูลเกี่ยวกับ Table : Payment เท่านั้น หรือ User บางพวกมีสิทธิ์ SELECT ดูข้อมูลอย่างเดียวไม่มีสิทธิ์แก้ไขเป็นต้น

  3. จัดการปัญหาการใช้งานข้อมูลเดียวกันพร้อมๆกันหลายคนได้ว่าจะให้คนเรียกคนไหนทำงานสำเร็จไม่สำเร็จ ถ้าถูกเรียกระหว่างการแก้ไขข้อมูลจะเห็นข้อมูลแบบไหน ในส่วนนี้ทางเทคนิคจะเรียกว่า Transaction Processing (เรื่องนี้คุยกันยาวมากครับ เดี๋ยวผมเขียนเป็นตอนใหม่อธิบาย)

  4. ทำ Query optimization ได้ ตรงนี้เราต้องมาทำความเข้าใจก่อนว่าภาษาที่สั่งให้ Database ไปทำงานนั้นบางภาษานั้นเป็นการสั่งแบบ Declarative คือสั่งว่าอยากได้อะไร ไม่ได้สั่งว่าให้ทำแบบไหน ตัวอย่างเช่น ภาษา SQL ดังตัวอย่าง

    1
    2
    3
    SELECT *
    FROM Product
    WHERE ProductPrice < 200.00

    จะเห็นว่าเป็นการสั่งให้ไปเอาข้อมูลที่มีค่า ProductPrice < 200.00 กลับมา ไม่ได้บอกว่าให้ไปเอามาอย่างไร ดังนั้นตัว DBMS จึงมีหน้าที่ไปทำให้การเข้าถึงข้อมูลได้ดีที่สุดโดยที่ผู้ใช้ไม่ได้ต้องรู้ (เรื่องนี้ก็คุยได้ยาวเหมือนกันเดี๋ยวผมเขียนแยกเป็นอีกตอนครับ)

  5. สามารถตั้งกฎและบังคับให้เก็บข้อมูลตามกฎที่กำหนดไว้ได้ ตัวอย่างเช่น ถ้าคุณตั้งกฎไว้ว่า field นี้จะต้องมีค่าไม่ซ้ำกันเลยตัว DBMS จะทำการ Check ให้ว่า field นั้นจะต้องไม่ซ้ำกันเลยใน Database หรือ ถ้าตั้งกฎว่าค่า field ที่เก็บเกี่ยวกับเงินจะต้องมีค่ามากกว่าหรือเท่ากับ 0 ตัว DBMS ก็จะทำการ Check ให้

DBMS ที่มีให้ใช้กันนั้นมีมากมายแต่ละตัวก็จะบอกว่า DBMS ของตนนั้นมี Database Model อะไร ดังนั้นเมื่อคุณคุยกันทางเทคนิคคุณอาจจะต้องลงรายละเอียดกับคนที่คุณคุยด้วยว่าเขาใช้ DBMS อะไร

ตัวอย่างอย่าง DBMS ที่มี Database model เป็นแบบ Relational Database

  • MySQL
  • MariaDB
  • DB2
  • PostgresSQL
  • Oracle Database

สรุป

สำหรับตอนนี้เราได้รู้ว่า Database , Database Model , DBMS คืออะไร ซึ่งมันจะเป็นพื้นฐานทำให้เข้าใจว่าสิ่งนี้มีไปทำไม มีไปเพื่ออะไร ในตอนถัดไปเราจะไปศึกษาเกี่ยวกับ Relational Database ซึ่งถือว่าเป็น Database model พื้นฐานที่โปรแกรมเมอร์ทุกคนควรรู้เพราะถ้าเป็นงานทั่วๆไปก็มักจะใช้ Database model ชนิดนี้

แนะนำหนังสือ

Relational database systems : language, conceptual modeling and design for engineers

หากท่านหาหนังสือเกี่ยวกับ Database ตั้งแต่เริ่มต้นมาอ่าน ผมขอแนะนำหนังสือเล่มนี้เลยครับในหนังสือจะอธิบายว่าทำไมเพราะอะไรถึงเป็นแบบนั้น สอนการใช้งานภาษา SQL ตั้งแต่พื้นฐานจนสามารถ Query ได้ทุกรูปแบบ (ผมใช้โจทย์จากหนังสือเล่มนี้สามารถ Query ได้เกือบทุกอย่างตาม Standard SQL92) สอนออกแบบ Database ด้วยวิธีต่างๆ สอนการทำ Normalization บอกเลยว่าอ่านจบก็สามารถนำความรู้ที่ได้ไปใช้ทำงานได้เลยครับ

ผัวเดียวเมียเดียว - อาณานิคมครอบครัวในสยาม

ผัวเดียวเมียเดียว - อาณานิคมครอบครัวในสยาม

ผัวเดียวเมียเดียว - อาณานิคมครอบครัวในสยาม

ตอนเด็กผมมักนั่งดูละครกับที่บ้าน ละครหลายๆเรื่องที่ผมดูมักจะพูดถึงความรักของตัวพระเอกนางเอกที่รักกันไม่เปลี่ยนใจจากกันแต่ที่สำคัญที่สุดของทุกเรื่องคือทั้งสองฝ่ายจะต้องรักเดียวใจเดียว ในบางเรื่องจะมีตัวละครที่จะเป็นคนที่ไม่ได้รักเดียวใจเดียวและพยายามมีแฟนหลายคนหรือมีภรรยาหลายคน ซึ่งตัวละครเหล่านี้นั้นมีจุดจบไม่ค่อยดีสักเท่าไหร่บางทีก็ตายไม่ก็หมดตัวไม่เหลืออะไร

ตอนเด็กผมก็ไม่คิดอะไรผมก็จดจำเหมือนโดนสอนว่าถ้าอยากมีชีวิตดีๆจะต้องเป็นคนรักเดียวใจเดียวอย่าคิดจะมีมากกว่า 1 ทันที แต่เมื่อโตขึ้นผมก็เริ่มเกิดคำถามว่า “ทำไมคนที่เขามีภรรยาหลายคนนี่มันเป็นคนเลว คนชั่ว เพียงเพราะมีภรรยาหลายคนจริงเหรอ” เมื่อมีคำถามผมก็เริ่มหาว่ามันมีใครที่มีภรรยาหลายคนบ้างไหม ซึ่งผมก็เห็นว่าบนโลกนี้มันมีคนที่มีภรรยาหลายคนครับ และคนที่มีภรรยาหลายคนเขาก็ไม่ได้เป็นอาชญากร ไม่ได้จับภรรยามาทรมาน ข่มขืน ถ้าคุณหาไม่เจอคุณลองศึกษาศาสนาอิสลามก็ได้ครับ ศาสนานี้อนุญาตให้มีภรรยาได้ 4 คน แต่การจะมีได้นั้นผู้ชายจะต้องเลี้ยงดูภรรยาทุกคนให้เท่าเทียมกัน อีกทั้งการจะมีคนที่ 2 ได้นั้น ภรรยาคนแรกต้องยินยอม ถ้าคุณอ่านถึงตรงนี้คุณเริ่มเห็นอะไรไหมครับ การมีภรรยาหลายคนไม่ได้ตัวบ่งชี้ว่าคนคนนั้นเป็นคนไม่ดี และ การที่จะมีภรรยาหลายคนสามารถมีได้ถ้าทั้งหมดตกลงกันได้ (คุณจะเห็นได้ว่าศาสนาอิสลามบังคับว่าต้องเลี้ยงดูให้เท่าเทียม และ ภรรยาที่มีอยู่ก่อนต้องอนุญาต)

อีกคำถามที่น่าสนใจคือ ศีลธรรม(ค่านิยม) ที่ให้การมีภรรยานั้นถูกต้องมาตั้งแต่แรกหรือมันพึ่งเกิดขึ้นขึ้นมา ถ้ามันไม่ใช่สิ่งที่มีมาแต่แรก มันเริ่มตอนไหนและทำไมคนส่วนใหญ่ในสังคมถึงนำมันมาใช้แทนค่านิยมเก่า

ทั้งหมดเป็นคำถามที่ผมสงสัยและผมมักจะพยายามถามคนที่รู้จักว่าเคยสงสัยอะไรประมาณนี้ไหม รู้ไหมครับสิ่งที่ผมได้จากการตั้งคำถามคือ “โห ถามแบบนี้อยากเป็นคนมักมาก” “ไอคนเลว ทำร้ายจิตใจผู้หญิง” “โหถามแบบนี้โคตรเห็นแก่ตัว” ผมนี่แบบอะไรวะเนี่ยกูผิดอะไร

ผมเก็บความสงสัยนี้มาเรื่อยๆจนวันหนึ่งตอนไปเดินห้องสมุด TK park ผมเหลือบไปเห็นหนังสือเล่มนี้เข้า เฮ้ยหนังสืออะไรวะชื่อ “ผัวเดียวเมียเดียว” ด้วยความสงสัยผมจึงหยิบมาอ่านซึ่งขอบอกเลยว่าผมได้เจอคำตอบของคำถามที่ผมสงสัยมาหลายปีในหนังสือเล่มนี้

หนังสือเล่มถูกแก้ไขจากวิทยานิพนธ์

ผู้เขียนบอกว่าหนังสือเล่มนี้นั้นถูกแก้ไขจากวิทยานิพนธ์ของเขาซึ่งได้รวบรวมข้อมูลเนื้อหาจากแหล่งข้อมูลที่น่าเชื่อถือต่างๆมาสรุป ซึ่งเมื่อมันเป็นงานวิทยานิพนธ์มันจึงเป็นงานเขียนที่เป็นกลางไม่เอาอารมณ์ผู้แต่งมาเป็นตัวตัดสิน ซึ่งหาได้ยากมากในการอ่านหนังสือประวัติศาสตร์หรือเล่าเรื่อง เพราะส่วนใหญ่ผู้เขียนจะชอบเอาตัวเองมาตัดสินว่ามันถูกมันผิด หลักฐานจะเอนเอียงจะเข้าข้างสิ่งที่ตัวเองเชื่อ แต่หนังสือเล่มนี้ไม่ใช่อย่างนั้นครับ หนังสือเล่มนี้เขียนเป็นกลางเอามากๆ ไม่ได้บอกว่า “ผัวเดียวหลายเมีย” เป็นเรื่องแย่ หรือ “ผัวเดียวเมียเดียว” เป็นเรื่องดี หนังสือเล่มนี้หาหลักฐานที่มาของการเปลี่ยนแปลงว่าทำไม เหตุใด อะไรเป็นตัวสนับสนุน ด้วยวิธีการใดและมีการตอบโต้ระหว่างสองฝั่งอย่างไร ซึ่งผมรู้สึกชอบมากเพราะมันปล่อยให้คุณได้ทำความเข้าใจ ไม่มีการเอาสีขาวสีดำมาป้ายว่ามันถูกหรือผิด (แล้วพอเป็นวิทยานิพนธ์มันต้องมีหลักฐานอ้างอิงซึ่งเขามีหลักฐานอ้างอิงให้คุณไปหาอ่านต่อได้ ไม่ได้มาลอยๆแบบหนังสือบางเล่ม)

ประเทศเราในอดีตไม่ได้มีค่านิยมผัวเดียวเมียเดียว

คุณอ่านไม่ผิดครับ (ไม่ต้องทำท่าขยะแขยงครับ หลายๆประเทศที่เจริญแล้วก็เป็น “ญี่ปุ่น” เป็นต้น ) ประเทศไทยของเราไม่ได้มีค่านิยมที่ผู้ชายจะต้องมีผัวเดียวเมียเดียว ในอดีตประเทศเราอนุญาตให้ฝ่ายชายมีเมียกี่คนก็ได้ครับ ในหนังสือเล่าถึงหลักฐานมากมายที่บอกว่า ผู้ดีมีเงินมีอันจะกินนั้นจะมีเมียมากกว่า 1 คน ซึ่งเหตุผลที่มีนั้นไม่ได้มาจากความมักมากในกามอารมณ์เป็นที่ตั้ง แต่มาจากการแสดงความมีหน้ามีตาในสังคม อีกทั้งการได้ผู้หญิงมาเป็นเมียนั้นก็ไม่ได้มาจากการปล้นฆ่าแย่งมา บางส่วนสมัครใจมาเป็นเมียเอง (คุณอ่านไม่ผิดครับ เขายินยอมมาเป็นภรรยาที่ 2 3 4 5 เอง) แต่ในทางที่เลวร้ายหน่อยคือพ่อแม่ขายลูกสาวเพื่อแลกเงิน อันนี้คือเรื่องผัวเมียในประชาชนคนธรรมดา

ส่วนในระดับผู้ปกครองประเทศนั้นการมีภรรยาหลายคนนั้นมาจากการที่ต้องการสร้างความสัมพันธ์ทางการเมืองของคนในชนชั้นผู้ปกครอง มองง่ายๆ ถ้าคุณเป็นญาติทางฝ่ายภรรยาผม ผมจะกล้าทำอะไรที่ไม่ดีไหม เช่นกัน ถ้าผมเป็นสามีพี่สาวคุณ คุณจะกล้าทำเรื่องไม่ดีกับผมเหรอมันก็จะออกมาประมาณนี้ครับ

อีกเรื่องที่คุณควรรู้นะครับ ถ้าใครบอกว่าศาสาพุทธมีภรรยาได้คนเดียวขอบอกเลยว่า “ผิด” นะครับ และคนนั้นควรโดนด่าด้วยว่าโคตรมั่ว ในหนังสือมีหลักฐานว่า ศาสนา “พุทธ” ไม่เคยห้ามให้มี ผัวเดียวเมียเดียว คุณจะมีหลายเมียก็ได้ไม่ผิด (คุณไม่เชื่อไปหามาอ่านได้เลยครับ)

การเปลี่ยนแปลงเป็นค่านิยมผัวเดียวเมียเดียว

หนังสืออธิบายว่าการเปลี่ยนค่านิยมเป็นผัวเดียวเมียเดียวนั้นไม่ได้มาจากปัจจัยเดียว แต่มันเกิดจากหลายๆปัจจัยร่วมกันซึ่งมีหลายอย่างแต่ตรงนี้ผมจะอธิบายแค่ไม่กี่ปัจจัยเพื่อให้คุณไปหาอ่านเอาเองว่ามีอะไรบ้าง

การเข้ามาของมหาอำนาจตะวันตก

เมื่อประเทศมหาอำนาจตะวันตกไม่ว่าจะเป็นอังกฤษ ฝรั่งเศส ได้เข้ามาที่ไทย ซึ่งก็แน่นอนประเทศเหล่านี้ย่อมพาวัฒนธรรม ความเชื่อ ค่านิยมมาเผยแพร่ในประเทศไทยด้วย ซึ่งค่านิยมของประเทศเหล่านี้คือ “ผัวเดียวเมียเดียว” ซึ่งเมื่อค่านิยมไม่เหมือนกัน ประเทศมหาอำนาจเหล่านี้ก็ย่อมจะต้องชี้ให้เห็นว่าทำไมค่านิยม “ผัวเดียวเมียเดียว” ของเขาดีกว่าอย่างไร พร้อมกับชี้ให้เห็นโทษหรือเรื่องไม่ดีของ “ผัวเดียวหลายเมีย” ในมุมมองของเขา อีกทั้งด้วยความที่เขามีวิทยาการด้านทางทหารสูงกว่าเขาจึงใช้อำนาจนั้นทำให้ประเทศไทยต้องทำสนธิสัญญาที่ไทยเสียเปรียบ และจะยอมยกเลิกสนธิสัญญาก็ต่อเมื่อทำตามเงื่อนไขบางอย่างตามที่ประเทศเหล่านั้นกำหนด ซึ่งหนึ่งในเงื่อนไขนั้นคือต้องเขียนกฎหมายว่าด้วยเรื่องครอบครัวให้เสร็จ ซึ่งนั่นเป็นอีกหนึ่งตัวเร่งที่ทำให้ไทยต้องเขียนกฎหมายครอบครัวซึ่งนั่นเป็นการรีบให้ประเทศเราต้องตัดสินใจว่าจะเลือก “ผัวเดียวเมียเดียว” หรือ “ผัวเดียวหลายเมีย”

สื่อสิ่งพิมพ์

ในยุคนั้นเทคโนโลยีการพิมพ์เริ่มเป็นที่แพร่หลายและมันก็กลายเป็นสื่อในการเผยแพร่ความรู้ แนวคิด ความเชื่อต่างๆให้กับผู้อ่าน ซึ่งไม่นานมันก็ถูกใช้เป็นตัวปลูกฝังค่านิยม ซึ่งดูได้จากนิยายที่มีในสมัยนั้น เริ่มแต่งให้คนที่มีคนจำพวก “ผัวเดียวหลายเมีย” มีการใช้ชีวิตหรือจุดจบในนิยายเป็นไปในด้านไม่ดี และแต่งให้คนที่มีค่านิยมแบบผัวเดียวมีเดียวมีชีวิตที่สุข (คุณเห็นความคล้ายอะไรไหมครับและคุณเริ่มเข้าใจรึยังว่าทำไมถึงมีการแบนสิ่งพิมพ์ ทำ List หนังสือต้องห้าม)

อ่านแล้วได้อะไร

สำหรับผมหนังสือเล่มนี้ช่วยทำให้ผมเข้าใจว่าค่านิยมผัวเดียวเมียเดียวเนี่ยมันมาจากไหนแล้วด้วยปัจจัยอะไรเหตุผลอะไรทำให้ประเทศไทยของเราถึงเปลี่ยนจากค่านิยมผัวเดียวหลายเมียมาเป็นผัวเดียวเมียเดียว (มันไม่ใช่เพราะค่านิยมแบบนี้มันบริสุทธิ์ โรแมนติก ใสสะอาดนะครับ ) อีกทั้งมันทำให้ผมเข้าใจว่าทำไมคนถึงไปตีตราคนที่มีหลายเมียว่าเป็นคนไม่ดี คนเลว และสุดท้ายหนังสือเล่มนี้ก็ทำให้ผมได้คำตอบของคำถามที่ว่า “คนมีเมียหลายคนเป็นคนเลวจริงๆเหรอ” ส่วนคุณจะได้คำตอบอย่างไรใช่หรือไม่ใช่ผมแนะนำให้ลองไปอ่านดูครับรับรองว่าได้ความรู้แน่นอน (แถมอ่านสนุกมากๆ)

Node-RED - ตอนที่ 3 - Connect MySQL Database และตัวอย่างการใช้งาน

Node-RED - ตอนที่ 3 - Connect MySQL Database และตัวอย่างการใช้งาน

ตอนนี้เรามาทำให้ Node-RED ติดต่อกับ Database ได้กัน ถ้าถามว่าทำไมต้องต่อ Database ก็เพราะในบางงานเราอยากจำข้อมูลบางอย่างที่ยิงมาที่ Server เช่น เราอยากให้ Return Error : Duplicate กับ Transaction ที่มีเลข Reference ซ้ำเช่นตัวอย่างด้านล่าง

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

การส่งครั้งแรก

# Request

{
"transactionRef" : "TX00001"
}

# Response
{
"status" : "SUCCESS"
}


การส่งครั้งที่สอง

# Request

{
"transactionRef" : "TX00001"
}

# Response
{
"status" : "DUPLICATE"
}

ซึ่งถ้าเราไม่เก็บข้อมูลไว้ว่า transactionRef ไหนใช้ไปแล้วบ้างเราจะไม่สามารถ Return Error Duplicate กลับไปให้ได้เลย ดังนั้นเราเลยต้องทำตัวที่เก็บข้อมูลซึ่งตัวเก็บข้อมูลที่เป็นที่นิยมก็คือ MySql นั่นเอง

ลง Node ที่ใช้เชื่อมต่อกับ Database

สามารถทำตามภาพด้านล่างได้เลย

ทำการ set ค่าให้ node-mysql

ส่วนนี้จะเป็นการทำการ config ให้ node สามารถเชื่อมต่อกับ Database ได้ โดยมีขั้นตอนดังต่อไปนี้

ในส่วนนี้คือการ Config เกี่ยวกับ Database

Host : ที่อยู่ของ database ของผมคือ 192.168.56.101

Port : Port ของ Database ของผมคือ 3306

User : User ที่ใช้ Login เข้า Database

Pass : Pass ที่ใช้ Login เข้า Database

Database : Database ที่ต้องการใช้งาน ของผมคือ Database ที่ชื่อ Node red

จากนั้นกด Deploy ถ้าเชื่อมต่อสำเร็จตัว node จะขึ้นคำว่า connected

สร้าง Table : payment_transaction เพื่อเก็บข้อมูล

ให้นำ sql script ที่สร้าง table ด้านล่างไปสร้าง table

1
2
3
4
5
CREATE TABLE `payment_transaction` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`transactionRef` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

ส่ง Query ไปให้ Database ทำงาน

สั่ง Insert

ตัว node mysql นั้นจะรับคำสั่ง SQL เพื่อส่งไป Database ผ่าน msg.topic โดยถ้าสมมติจะ INSERT ข้อมูลลง Database ด้วยคำสั่ง

1
INSERT INTO payment_transaction VALUES(NULL, 'TX00001');

เราก็สามารถ set ค่า msg.topic ด้วย SQL ด้านบนได้เลย โดยเราจะใช้ Node : Inject ในการส่งค่า msg.topic เข้าไปตามภาพ

  1. ทำการเลือก Node : Inject (Node Injdect นั้นจะทำการสร้าง object : msg ตามที่เรากำหนด ว่าง่ายๆ มีไว้สร้าง msg และส่งไปให้ node ต่อไป ส่วนใหญ่ inject จะมีไว้ใช้ทดลองว่าถ้าได้รับ msg แบบนี้ ตัว flow ของเรานั้นทำงานถูกต้องหรือไม่ )

  2. ลาก Node : Inject เข้าไปใน Flow

  3. ทำการเปิด Node : Inject และกำหนดค่าในส่วนของ Topic ด้วยคำสั่ง SQL ที่เราต้องการ

  4. ทำการกด Done

  1. ทำการลากเส้นเชื่อมระหว่าง inject กับ mysql

  2. ทำการกด Deploy เพื่อ update ตัว node-RED

  3. ทำการกดปุ่มที่ node inject เพื่อให้ inject ส่งค่า

จากนั้นลองไปดูที่ Database ก็จะพบว่าข้อมูลที่เราสั่ง Insert ไป

สั่ง Select

ในส่วนที่แล้วเราสามารถสั่งให้ Insert ข้อมูลได้แล้ว สิ่งที่ขาดอยู่คือการ select เพื่อหาข้อมูล ซึ่งก็ไม่ยากเลยเพราะเรารู้แล้วว่าตัว Node mysql รับคำสั่ง sql ผ่าน msg.topic เราก็แค่เปลี่ยนคำสั่ง INSERT เป็นคำสั่ง SELECT ก็สามารถทำการ SELECT ข้อมูลได้แล้ว โดยเราจะ SELECT ข้อมูลง่ายๆแบบ

1
SELECT * FROM payment_transaction;

  1. ทำการแก้ไข msg.topic ของ node inject เป็น sql ที่เราต้องการ

  2. ทำการกด Done

  1. ทำการนำ Node : debug เข้ามาใน Flow จากนั้นลากเส้นเชื่อมระหว่าง node mysql กับ debug

  2. กด Deploy เพื่อ Update ตัว NodeRed

  1. ทำการกดปุ่มที่ Node inject เพื่อส่งค่าเข้าไป

  2. ลองดูผลลัพธ์จากการ Debug

จากดูที่ช่อง Debug เราจะพบว่าตัว Node sql หลังจากได้รับคำสั่ง SELECT จากจะ Return ผลลัพธ์ SELECT ออกมาเป็น array ของ object ซึ่งแต่ละ object จะมีค่า key ตามการ select ซึ่งอันนี้เรา select * มันเลยได้ key เป็นชื่อ column

จากภาพจะเห็นว่าผลลัพธ์ที่ออกมาเป็น array ที่มี object เดียว เพราะใน database เรามี row อยู่ row เดียว

แล้วจะ Dynamic Query ยังไง

จากความรู้ที่จากหัวข้อที่แล้วพอจะคิดคร่าวได้ประมาณว่า รับ http request มาจากนั้นทำ Query select เพื่อหาข้อมูลว่ามี transactionRef ใน DB ไหม ถ้าไม่มีทำการ insert ข้อมูลลง DB และทำการ Return SUCCESS แต่ถ้ามีแล้วทำการ Return DUPLICATE ปัญหาคือเราจะทำให้คำสั่ง SQL ของเรา Dynamic ได้ยังไง

ภาพร่างคร่าวๆของ flow ที่จะทำ

คราวนี้เราจะ dynamic query ยังไง ตรงส่วนนี้เราทำได้ 2 วิธี

  1. เราใช้ node : function เพื่อทำการสร้าง msg.topic ด้วย code ที่เราต้องการ เช่น
1
2
msg.topic = `SELECT * FROM payment_transaction  WHERE transactionRef = '${msg.payload.transactionRef}'`
return msg;

ซึ่งเมื่อเราต่อ httpin เข้า function แล้วลอง debug จะเห็นว่าคำสั่ง sql ที่ msg.topic จะได้ค่าตาม transactionRef ที่รับมา

ซึ่งถ้าเราเอาลากเส้นต่อเข้าไปที่ node mysql เราก็จะสามารถ select ได้

  1. ใช้ binding param ของ node mysql

ตัว node mysql นั้นมี feaure binding param ให้เราโดยในส่วนของ msg.topic เรากำหนดสร้าง param ขึ้นมาเพื่อจะนำค่าไปแทนที่ได้เช่น

1
INSERT INTO payment_transaction VALUES(NULL, :transactionRef);

ซึ่งถ้าเรา set แบบนี้ตัว transaction จะกลายเป็น param เพื่อเอาค่าไปแปะ ซึ่งคำถามคือจะเอาค่าจากไหนไปแปะ คำตอบคือตัว node mysql จะเอาค่าจาก msg.payload ไปแปะให้ตัวอย่างเช่น ถ้า payload คือ

1
2
3
{
"transactionRef" : "Tx000WASINEE"
}

sql ที่จะได้คือ

1
INSERT INTO payment_transaction VALUES(NULL, 'Tx000WASINEE');

โดยเราสามารถใช้ Node inject ทดสอบดูว่าสามารถทำได้จริงหรือไม่โดยทำการ Set ดังภาพ

ซึ่งเมื่อเราสั่งให้ Inject ทำงานและเข้าไปดูใน Database เราจะพบข้อมูล Tx000WASINEE อยู่ใน Database

เรามาสร้าง Flow ทั้งหมดกัน

จากความรู้ของเราทั้งหมดที่เราได้รู้มาเราจะมาสร้าง Flow ที่เราต้องการกันตอนแรก โดย Flow ของผมนั้นอาจจะเหมือนที่คุณเขียนก็ได้ เพราะเราอาจจะใช้คนละวิธี ใช้คน Component กัน ดังน้ันไม่ต้องตกใจถ้า Flow ของผมไม่เหมือน Flow ของคุณ

ภาพรวมของ Flow

Flow ของผมหน้าตาประมาณนี้เดี๋ยวผมจะลงรายละเอียดบางจุดเท่านั้น ส่วนจุดอื่นๆที่ผมอธิบายไปแล้วหรือคิดว่าง่ายนั้นผมจะข้ามไปเลย หากใครสนใจทั้ง Flow สามารถ Download ได้จากตรงนี้เลย Link อย่าลืมเปลี่ยน config ตรง node mysql ด้วยนะครับ

เตรียมค่าสำหรับ Select

ตรงนี้ผมจะเขียนเป็น Function โดยการทำการ copy ค่า payload ไปใส่ใน copyPayload ซึ่งที่ต้องทำแบบนี้นั้นต้องทำเพราะเวลาเราทำการ Select ผ่าน Node mysql แล้วจะทำให้ค่า payload นั้นหายไป ดังนั้นเราต้องทำการเก็บค่า payload ไว้เพื่อใช้ในการ Insert

1
msg.copyPayload = msg.payload

เช็คว่ามีค่าใน DB ไหม

อันนี้ตามภาพเลยว่ามีข้อมูลไหม ถ้ามีไปทางด้านบน ถ้าไม่มีก็ไปทางด้านล่าง

ย้ายค่า copyPayload ไปเป็น payload

มาลอง Test กันดูว่าใช้งานได้จริงไหม

เราจะทดลองยิงกันโดยเราจะยิงโดยใช้ Body ด้านล่างโดยจะลองยิงสองครั้งเพื่อดูว่าได้ Response แบบที่คิดไหมและใน DB ได้เก็บข้อมูลลงไปไหม

1
2
3
{
"transactionRef" : "TX-SUNISA"
}

ลองยิงครั้งแรก

จากการยิงครั้งแรกจะเห็นว่ายิงแล้วได้ SUCCESS

ลองยิงครั้งที่สอง

จากการยิงครั้งนี้จะเห็นว่ายิงแล้วได้ DUPLICATE

ตรวจสอบ Database ว่ามีข้อมูลไหม

จากภาพจะเห็นว่ามีข้อมูลอยู่ใน Database จริงๆ

สรุป

สำหรับตอนนี้เราได้เรียนรู้วิธีที่จะให้ Node-RED ต่อกับ Database แล้ว โดยในตัวอย่างเราใช้ทั้ง SELECT และ INSERT ส่วน UPDATE นั้นก็ไม่น่าจะยากครับ ผมเชื่อว่าถ้าคุณทดลองทำตามที่ผมทำในตอนนี้ผมเชื่อว่าคุณจะสามารถทำการ UPDATE ได้แน่นอนครับ สำหรับตอนนี้ขอจบเพียงเท่านี้สวัสดีครับ

ปรัชญาแมว ปรัชญาเหมียว - แมวและความหมายของชีวิต

ปรัชญาแมว ปรัชญาเหมียว - แมวและความหมายของชีวิต

ปรัชญาแมว ปรัชญาเหมียว

ก่อนที่จะเข้าเรื่องผมขอออกตัวก่อนเลยว่า ผมไม่ใช่คนรักแมว ไม่ได้เป็นทาสแมว ไม่ได้นั่งสังเกตุแมว ไม่เคยได้เลี้ยงแมวจริงๆจังๆ จะเคยเลี้ยงก็แต่แมวจรที่มาทำท่าทางน่าสงสารจนใจอ่อนให้ข้าวและสุดท้ายก็มานั่งรอกินข้าวทุกวัน ดังนั้นผมอาจจะไม่ค่อยเข้าใจความเป็นแมวที่หนังสือพยายามสื่อให้เห็น ดังนั้นผมเลยอาจจะไม่เข้าใจความสุดยอดของหนังสือเล่มนี้อย่างลึกซึ้ง

ผมได้หนังสือเล่มนี้มาอ่านจากน้องในบริษัท ตอนแรกผมคาดหวังไว้ว่าเขาจะมาพูดถึงปรัชญาของแมวในทางทฤษฎีหรือทำให้เราเข้าใจความเป็นแมวมากขึ้น แต่พอเริ่มอ่านแล้วนี่ไม่ใช่เลย หนังสือเล่มนี้มันคือการพูดถึงการใช้ชีวิตของมนุษย์เทียบกับแมว โดยยกให้แมวนั้นดูจะเหนือกว่ามนุษย์ในมุมมองของผู้เขียน พอเขาทำแบบนี้ผมเลยเริ่มรู้สึกอึดอัดกับแนวทางการเขียนของเขา ผมอ่านแล้วรู้สึกว่าเขาจะโมเมเชิงคิดเอาเองเลยว่าแมวมันมีความสุข มันหลุดพ้น มันต่างๆนาๆ ซึ่งเขายกเอาบางเหตุการณ์มาเหมารวมว่ามันดีแบบนั้นแบบนี้ โดยเขาไม่ได้เทียบมันแบบจริงๆจังๆ ซึ่งเมื่อผมเคยเจอคนละเหตุการณ์แบบที่เขาเจอผมก็รู้สึกว่ามันไม่น่าจะใช่แล้วแหละ ดังนั้นพอยิ่งอ่านมันเลยรู้สึกไม่น่าเชื่อถือขึ้นเรื่อยๆจนถึงจุดที่คิดว่าควรเลิกสนใจแมวเลยละกัน ซึ่งพอทำแบบนั้นก็ทำให้ผมสามารถเข้าใจว่าหนังสือเล่มนี้ต้องการบอกอะไร

การรู้ว่าตัวเองคือตัวเอง

การรู้ว่าตัวเองคือตัวเองเป็นความสามารถที่สัตว์จำนวนหนึ่งมี ตัวอย่างเช่น มนุษย์ ลิง ซึ่งนักวิทยาศาสตร์สามารถทดลองว่าสัตว์มีความสามารถเหล่านี้หรือไม่ได้ด้วยการให้มันส่องกระจก ถ้าสัตว์พวกนั้นรู้ว่าสิ่งที่อยู่ในกระจกคือตัวเอง พวกมันจะเริ่มลองจับสิ่งนั้นสิ่งนี้ของตัวเอง อย่างลิงเนี่ยมันจะมีการจัดขนตัวเองเลียขนตัวเองให้ดูดี อ่านถึงตรงนี้คงสงสัยว่าแล้วมันเกี่ยวกับปรัชญายังไง การที่เรารู้ว่าตัวเองคือตัวเองเป็นจุดเริ่มต้นของการรู้ว่าเรามีตัวตน เราต่างจากคนอื่น จากนั้นเราเริ่มมีความรู้สึกว่าเราอยากเป็นที่ตัวตนที่ดีขึ้น ดีกว่าเดิม หรืออย่างน้อยก็รักษาสิ่งที่ตัวเองคิดว่าดีไว้ ซึ่งนี่เป็นหนึ่งปัจจัยจากอีกหลายๆปัจจัยที่ทำให้ ศาสนา ค่านิยม ศีลธรรม ต่างๆนาๆในสังคมทีมักจะบอกว่าให้ทำสิ่งนั้นสิ่งนี้เพื่อให้เป็นสิ่งที่ดีกว่าหรือคงความดีไว้ (ผมใช้คำว่าเป็นปัจจัยหนึ่งเพราะมันไม่ใช่มีแค่การรู้ตัวเองแล้วจะทำให้เกิดศาสนา ค่านิยม ศีลธรรมขึ้นมา มันมีอีกหลายๆปัจจัยร่วมกันจึงทำให้เกิด) ซึ่งนั่นก็มีผลเสียสร้างความวุ่นวายปั่นป่วนให้กับมนุษย์อย่างเราให้ต้องขวนขวายให้ได้มาซึ่งการเป็นสิ่งที่ดีกว่าและรักษามันไว้ ในหนังสือเปรียบเทียบว่าแมวไม่รู้ว่าตัวเองคือตัวเอง (แต่เขาไม่กล้าฟันธงนะเขาบอกว่ามันอาจรู้แต่ไม่สนใจ ผมเลยสงสัยว่า เอ้า คุณยังไม่มั่นใจมันเลยแล้วจะมายกย่องมันได้อย่างไร) ดังนั้นมันจึงไม่ต้องขวนขวายอะไร มันใช้ชีวิตไปเรื่อยๆ ตามสัญชาตญาณ เหตุกาณณ์ฉพาะหน้า อยากทำอะไรก็ทำ มันไม่สนใจว่ามันควรจะทำให้ตัวเองดีขึ้นหรือคงความดีไว้ไหม

ความหมายของชีวิต

ความตายเป็นสิ่งที่น่ากลัว (แต่บางคนก็ไม่กลัว) ทำไมมันถึงน่ากลัวก็คงมีหลายเหตุผลแต่เหตุผลที่หนังสืออธิบายไว้คือการที่คุณจะหายไปจากโลกนี้และถูกลืมเลือน ซึ่งแน่นอนว่าหลายๆคนคงไม่ชอบ (ผมคือหนึ่งในนั้น) ดังนั้นหลายๆคนจึงพยายามทำบางสิ่งบางอย่างทิ้งไว้เพื่อให้เหมือนตัวเองไม่ได้หายไปจากโลก ตัวอย่างง่ายๆที่เราเห็นคงเป็นการทำป้ายหลุมศพ การเอาชื่อตัวเองไปเป็นสถานที่ ใส่ชื่อตัวเองเป็นผู้ร่วมสร้างอะไรบางอย่าง หรือบางคนทำให้ตัวเองเป็นที่โด่งดังเพื่อเป็นที่จดจำด้วยวิธีการต่างๆ ส่วนอีกเหตุผลหนึ่งคือเมื่อเรารู้ว่าเราต้องตายแล้วการมีชีวิตอยู่นี้คืออะไร มันมีความหมายอะไร ถ้าเราคิดแบบง่ายๆว่าแบบวิชาชีววิทยาว่า “เราก็แค่เกิดมามีชีวิตสืบพันธุ์แล้วก็ตาย” ซึ่งมันก็อาจจะดูไม่มีความหมายสูงส่งอะไร (หากคุณไม่ให้ค่าการทำให้เผ่าพันธุ์ของเราไม่สูญพันธุ์) ด้วยความที่มันดูไร้ค่าแบบนี้คนเราจึงพยายามหาความหมายของชีวิตให้กับตนเอง ไม่ว่าจะเป็นต้องเป็นคนดี ต้องช่วยเหลือคนอื่น ต้องเป็นที่หนึ่ง ต้องแต่งเติมเรื่องราวต่างๆให้กับชีวิตตนเองเพื่อให้ชีวิตนั้นมีความหมาย ซึ่งสิ่งนี้ต่างจากแมวที่ผู้เขียนอ้างว่าแมวไม่ได้สนใจความหมายของชีวิตมันจึงไม่ต้องมาทนทุกข์ในการพยายามหาความหมายให้กับชีวิตดังนั้นแมวจึงไม่ต้องวุ่นวายและน่าจะมีความสุขและอิสรภาพมากกว่าคน (แต่เขาถ้าเขาคิดสักนิดว่าถ้าความสุขของคนคนหนึ่งคือการหาความหมายให้ชีวิตเขาอาจจะมีความสุขเท่ากับหรือมากกว่าแมวก็ได้)

สรุป

สำหรับผมเล่มนี้อาจแล้วอึดอัดในระดับหนึ่งเพราะมันเขียนยกสิ่งหนึ่งให้ดีกว่าสิ่งหนึ่งโดยไม่ได้ให้เหตุผลหรือหลักการที่ดีมากพอ แถมบางทีมันก็เล่าเรื่องผ่านนิยายที่เขียนเกี่ยวกับแมวแล้วโยงมาบอกว่าแมวเป็นแบบนั้นแบบนี้ซึ่งดูจะไม่ค่อยเกี่ยวกับปรัชญาสักเท่าไหร่ แถมบางกรณีมันไม่ตรงกับแมวที่ผมเคยเลี้ยงด้วยสิ เพราะแมวที่ผมเคยเลี้ยงมันจะพยายามคลอเคลียจนกว่ามันจะได้ข้าว ไม่ใช่ทำยิ่งยโสโอหังว่าจะให้ไม่ให้ก็เรื่องของคุณ ซึ่งผมก็พอเข้าใจว่าเขาคงเขียนขายเจาะจงไปในกลุ่มคนเลี้ยงแมวมันเลยออกมาในแนวนี้ แต่หากตัดเรื่องการเปรียบเทียบและใช้เหตุผลที่ไม่ค่อยครอบคลุมทุกกรณีทิ้งไป หนังสือเล่มนี้ก็ชี้ให้เห็นว่าคนอย่างเรานี่พยายามทำในเรื่องแปลกๆกว่าสิ่งมีชีวิตที่เรียกว่าแมว ไม่ว่าการพยายามทำให้ตัวเองเป็นตัวตนที่ดีขึ้น การพยายามสร้างความหมายให้กับชีวิตตัวเอง ซึ่งสิ่งเหล่านี้ที่เราพยายามทำมันเป็นตัวสร้างปัญหาอื่นขึ้นมามากมายไม่ว่าจะเรื่องเล็กระดับบุคลเช่นการขัดใจตนเองไม่ให้ทำสิ่งที่ตัวเองอยากทำเพื่อต้องการเป็นตัวเองที่ดีกว่าหรือเรื่องใหญ่ระดับโลกเช่นสงครามเพื่อทำให้โลกนี้เป็นโลกที่ดีกว่าทำให้คนทุกคนเป็นคนที่ดีกว่าหรือจะให้ตัวเองเป็นที่ถูกจดจำว่าเป็นคนทำให้โลกดีขึ้น

ก็สำหรับใครที่ชื่นชอบเกี่ยวกับแมวแล้วอยากได้ความรู้เรื่องปรัชญาผมก็แนะนำให้อ่านเลยครับ รับรองว่าคุณจะรู้สึกเพลิดเพลินไปกับมันอย่างแน่นอน (ยกยอแมวซะขนาดนั้น) แต่หากใครสนใจปรัชญาเพียวๆหรือชอบการอ่านอะไรที่มีเหตุผลหนักแน่นผมก็ไม่ค่อยแนะนำให้อ่านครับ

Node-RED - ตอนที่ 2 - สร้าง Response ตามเงื่อนไขที่ต้องการและสร้าง webhook เพื่อใช้ในการ Test

Node-RED - ตอนที่ 2 - สร้าง Response ตามเงื่อนไขที่ต้องการและสร้าง webhook เพื่อใช้ในการ Test

ในตอนที่แล้วเราทำการสร้าง Mock server ด้วย Node-RED โดยตัวอย่างที่แล้วจะเป็นการสร้าง Transaction Reference และ Response กลับไปให้เพื่อใช้ในการ Test แต่ในการ Test นั้นมีหลายกรณี เช่น กรณีที่ถูกต้อง กรณีที่เกิดปัญหา หรือกรณีต่างๆตามเงื่อนไขที่ Application ต้องการ อีกทั้งใน Appllication บางประเภทนั้นไม่ได้มีแค่การ Response ข้อมูล แต่จะมีการยิง Http request ไปหา URL ที่ตกลงกันไว้หรือที่เรียกกันว่า Webhook ดังนั้นตอนนี้เราจะมาทำสิ่งที่ว่ามาด้วย Node-RED กัน

สิ่งที่เราจะทำกัน

สมมติว่าเราจะเขียน Application ขายของที่เมื่อลูกค้าเลือกของเรียบร้อยแล้วจะส่งไปให้ Payment application (ซึ่งก็คือ Mock server ที่จะใช้ Node-RED สร้าง) ที่ทำหน้าหักเงินจากบัญชีลูกค้าแล้วจากนั้นตัว Payment application จะยิง Request กลับไปหา Server ของเราโดยมี Flow ตามนี้

โดย Request ที่ต้องการหักเงินลูกค้า (1) ของเราจะมีหน้าตาแบบนี้

1
2
3
4
5
6
{
"transactionId" : "4d74cb8f-b3a6-42ba-8383-4f60339fd84b",
"accountNo" : "10110",
"ref" : "ABCDEFG",
"amount" : 300
}

ส่วน Response ที่กลับมาจาก Payment Application (2) จะมีหน้าตาแบบนี้

1
2
3
4
{
"transactionId" : "4d74cb8f-b3a6-42ba-8383-4f60339fd84b",
"status" : "PROCESSING"
}

ส่วน Request ที่ยิงกลับไปที่ Webhook (3) จะมีหน้าตาแบบนี้

1
2
3
4
5
6
{
"transactionId" : "4d74cb8f-b3a6-42ba-8383-4f60339fd84b",
"status" : "SUCCESS",
"amount" : 300,
"errorMessage" : null
}

สร้างกรณีสำเร็จและหาบัญชีไม่เจอ

ในการทำงานของ Application นั้นไม่ได้เขียนรองรับกรณีที่สำเร็จอย่างเดียว เราจะต้องเขียนกรณีที่เกิดปัญหาด้วยซึ่งเมื่อต้องการ Test ว่าเมื่อเกิดกรณีที่เกิดปัญหาแล้ว Application ของเราจะทำงานได้อย่างที่คิดไหม ดังนั้นเราจึงต้อง Mock ตัว Payment Application ส่ง Response ที่มีปัญหากลับมาคือหาบัญชีไม่เจอ โดยจะให้กรณีนี้เกิดขึ้นเมื่อส่งค่า accountNo เป็น UNKNOWN โดยตัว Payment application จะตอบ Http response status เป็น 404 กลับมา ดังนั้นเมื่อจะทำการ Test กรณีนี้ก็แค่ตอนส่งค่าไปก็ set ค่า accountNo เป็น UNKNOWN

ตัวอย่าง Http request ที่ยิงไปแล้วจะเกิดปัญหา

1
2
3
4
5
6
{
"transactionId" : "4d74cb8f-b3a6-42ba-8383-4f60339fd84b",
"accountNo" : "UNKNOWN",
"ref" : "ABCDEFG",
"amount" : 300
}

สร้าง Flow Node-Red สำหรับกรณีทั่วไป

  • ในขั้นนี้ไม่ทำอะไรมากครับเราจะสร้าง component http in เข้าไปโดยกำหนด path เป็น /payment

  • ในส่วนถัดไปเราจะทำการกำหนด Response เพื่อตอบกลับโดยในตอนที่แล้วเราใช้ component : function สร้าง แต่ตอนนี้เราจะลองใช้ Component : change ในการกำหนดค่า Response โดยมีขั้นตอนดังต่อไปนี้

    1. ทำการลาก Component : change ลงไปใน Flow

    2. ทำการเชื่อม Http in กับ Change เข้าด้วยกัน

    3. ทำการคลิกที่ Component : change จากนั้นดูที่ด้านขวาในส่วนนี้จะเป็นการบอกว่าเราจะทำการเปลี่ยนค่า msg อะไรบ้าง โดยเราจะแก้ไขข้อมูล msg.payload.status เป็น PROCESSING เพื่อให้ตรงกับ Response ที่เราต้องการ เราจึงเลือก type ของการเปลี่ยนเป็น set จากนั้นเลือกค่าเป็น PROCESSING

    4. ทำการกด Add เพื่อเพิ่มการแก้ไขข้อมูลของ msg

    5. ทำการเลือก type เป็น Delete เพื่อลบ accountNo, ref, amount

    6. กด done

  • ในส่วนถัดไปการลาก Component : http response จากนั้นลากเชื่อมระหว่าง change เข้ากับ http response

  • เปิด Postman เพื่อทดลอง

    เลือก set endpoint ให้ยิงไปที่ http://your-nodered-endpoint/payment ( Node-RED ของผมคือ http://192.168.56.101:1880) และ payload เป็น

    1
    2
    3
    4
    5
    6
    {
    "transactionId" : "4d74cb8f-b3a6-42ba-8383-4f60339fd84b",
    "accountNo" : "10110",
    "ref" : "ABCDEFG",
    "amount" : 300
    }

    จากนั้นลองยิงซึ่งจะได้ผลลัพธ์ดังภาพ

จากการ setting ทั้งหมดเราจะได้ mcok server ที่ตอบกลับในกรณีที่สำเร็จแล้ว

สร้าง Flow Node-RED ในกรณีไม่สำเร็จ

ในขั้นตอนที่แล้วเราได้กรณีที่สำเร็จแล้ว ในตอนนี้เราจะสร้างกรณีที่ไม่สำเร็จโดยมีขั้นตอนดังต่อไปนี้

  • ทำการสร้างเงื่อนไขให้ Flow ด้วย Component : change

    1. ทำการดึง Component : change เข้ามาใน Flow

    2. ดูตรงส่วน Property ตรงส่วนนี้จะเป็นการบอกว่าให้ทำการตรวจสอบ property ไหนโดยจากที่เราจะทำกันคือเราจะตรวจสอย property : accountNo ที่อยู่ใน request ดังนั้นค่าจึงเป็น msg.payload.request (payload คือ request ที่ยิงเข้ามา)

    3. ส่วนนี้เป็นเงื่อนไขที่เราจะตรวจสอบโดยที่เราจะทำกันจะเช็คว่าหากค่า accountNo จะเข้าเงื่อนไข error

    4. ส่วนอันนี้เป็นเงื่อนไขกรณีที่ไม่ตรงกับเงื่อนไขอื่นๆเราจะให้ทำอะไร

  • ทำการสร้าง component : Http respones และกำหนดให้ return http status เป็น 404 เพื่อใช้เป็นการตอบกลับกรณีไม่สำเร็จ

  • ทำการแก้ไขการเชื่อมต่อ

    1. ทำการลากเส้นจาก switch ที่เป็นเงื่อนไขแรกไปที่ component : http response ตัวใหม่ เพื่อให้เวลาเจอกรณีไม่สำเร็จให้ไปออก response 404

    2. ทำการลากเส้นจาก switch ที่เป็นเงื่อนไขที่ 2 ไปที่ component เดิม เพื่อให้กรณีสำเร็จไปส่งไปที่เงื่อนไขเดิม

  • ทดสอบยิงด้วย Postman

    จากภาพจะเห็นว่าถ้า accountNo เป็น UNKNOWN http status ที่กลับมาจะเป็น 404

    แต่กรณีที่ accountNo ไม่ใช่ UNKNOWN ข้อมูลจะตอบกลับมาปกติ

สร้างกรณียิง Http request ไปที่ webhook

ในส่วนนี้เราจะทำการจำลองให้ตัว payment application ยิง Request กลับไปที่ webhook ที่เรากำหนด โดยการยิงเนี่ยเราจะทำการหน่วงเวลาเพื่อให้สมจริงคือจะหน่วงเวลาทิ้งไว้สัก 5 วินาทีจากนั้นค่อยยิงไป โดยเรามีขั้นตอนการทำดังต่อไปนี้

  • ทำการสร้างตัวหน่วงเวลาโดยการดึง component : delay

  • ทำการสร้าง Component : change และกำหนดค่าเพื่อให้ได้ response ตามที่เราต้องการคือให้ status เป็น success เพื่อ field errorMessage และลบ field อื่นที่ไม่ต้องการออก

  • ทำการส่ง Http request ไปที่ url ที่กำหนด

    1. เนื่องจากเราไม่ได้เขียน My application จึงไม่มีที่ให้ตัว Node-RED ยิงไปหาดังนั้นเราจะใช้ตัว web hook online แทน โดยเราจะทำการเข้า web https://webhook.site/ ซึ่งเมื่อเข้าแล้วให้เรา copy ตรงส่วน url ไว้ และเปิดหน้านี้ทิ้งไว้

    2. ทำการสร้าง Component : http reqeust จากนั้น set ค่า Method เป็น POST และ set ค่า URL เป็น URL ที่เราทำการ Copy จากส่วนขั้นตอนที่แล้ว

  • ทำการเชื่อม flow ดังภาพ

    1. เชื่อมให้ข้อมูลที่มาจากกรณีสำเร็จไหลไปเข้า component : delay เพื่อทำการหน่วงเวลา

    2. เชื่อมข้อมูลจาก component : delay ไปหา component : change เพื่อทำการแก้ไขค่าให้เป็นไปตาม Response ที่เราต้องการ

    3. เชื่อมข้อมูลจาก component : change ไปที่ http request เพื่อยิง http request ไปที่ url ที่ต้องการ

  • ทำการทดลองส่งข้อมูลด้วย Postman เพื่อทดสอบว่าใช้งานได้จริงหรือไม่

  1. เลือก set endpoint ให้ยิงไปที่ http://your-nodered-endpoint/payment ( Node-RED ของผมคือ http://192.168.56.101:1880) และ payload เป็น

    1
    2
    3
    4
    5
    6
    {
    "transactionId" : "4d74cb8f-b3a6-42ba-8383-4f60339fd84b",
    "accountNo" : "THANAPORN",
    "ref" : "ABCDEFG",
    "amount" : 300
    }

  1. จากนั้นเข้าไปดูที่ webhook.site ที่เปิดไว้ในขั้นตอนก่อนหน้านี้จะเห็นว่ามี Request เข้ามาแล้วซึ่งนั่นหมายความว่าตัว Node-RED ของเรายิง http request ออกมาแล้ว

สรุป

สำหรับตอนนี้เราได้ทำการสร้าง Flow ของ Node-RED ให้สามารถ Response ได้ตามเงื่อนไขที่เราต้องการและทำตัวยิง Http request ไปยัง endpoint ที่เราต้องการได้ ซึ่งทั้งสองเป็นสิ่งที่เป็นเรื่องพื้นฐานที่เราจะเจอเวลาที่ต้องทำการ Test ให้ครบ Loop

ความทรงจำปี 2022

ปี 2022 ที่ผ่านมา

ตอนมาเขียนสรุปปี 2022 เนี่ยยังนึกถึงตอนที่ยังนอนป่วยอยู่โรงพยาบาลเมื่อปีที่แล้วอยู่เลย ไม่ทันไรก็ได้ก็สิ้นปีแล้วซึ่งมองย้อนกลับไปแล้วรู้สึกว่าปีนี้นั้นเป็นปีที่ว่างเปล่าเสียเหลือเกิน เหมือนว่าเราไม่ได้โตขึ้นหรือเก่งขึ้นเลย

งาน

ปีนี้เป็นปีที่งานน่าเบื่อมากๆอาจจะเรียกได้ว่าได้ทำงานที่เหี้ยที่สุดที่เคยทำมา ผมไม่เคยคิดว่าชีวิตจะได้มาทำงานที่เหี้ยได้ขนาดนี้ มันถึงขนาดที่ไม่มีคนให้ Requirement เลยว่าจะให้ทำอะไร เราทำงานแบบเสี่ยงดวงมากๆว่าสิ่งที่เราทำไปนั้นเขาจะให้ผ่านไหม และที่แย่มากๆคือเราแทบไม่เห็นคุณค่าจากสิ่งที่เราทำเลย Third party ที่ร่วมงานด้วยก็เหี้ยคือเขาไม่ได้มองจุดหมายของการทำงานเลย ทำงานแบบไอเหี้ยจะขึ้น Production สัปดาห์หน้ามึงยังไม่มีเครื่องที่สมบูรณ์พร้อมผ่านการติดตั้งที่เรียบร้อยมาให้เลย แต่ก็โชคดีที่ถึงงานจะเหี้ยแต่ก็มีเพื่อนร่วมงานที่ดีมากๆที่พร้อมจะช่วยกันอยู่ตลอดแม้จะไม่ใช่หน้าที่ของเขา พร้อมจะพาไอ Project เส็งเคร็งนี่ไปให้ถึงจุดหมาย

ในส่วนของเนื้องานปีนี้ได้ทำ Application ที่เป็นระดับที่ผู้ใช้ทั่วไปที่ไม่ใช่ Enterprise มาใช้แล้ว ซึ่งถามว่าภูมิใจไหมก็บอกเลยว่า “ไม่” เพราะมันน่าจะดีได้มากกว่านี้ เร็วได้มากกว่านี้ (ถ้าผมเขียนโปรแกรมได้ดีกว่านี้) ทำเงินได้มากกว่านี้ แต่อย่างว่าแค่แม่งขึ้น Production แล้วขายของได้เงินเกือบ 20 ล้าน โดยที่ไม่เคยมีใครมาให้ Requirement (จริงๆแม่งมาให้ 1 สัปดาห์ก่อนขึ้น Production มึงจะมาทำควยอะไร แถมมาก็ติ ไม่บอกว่าดีคืออะไรด้วย ถ้ากูอยู่วันนั้นแม่งน่าจะโดนกูยัดด้วยคำถามแล้วต้อนแม่งให้จนแบบที่โสคราตีสทำแน่) แม่งก็ปาฏิหารย์ขนาดไหนละ

ในด้านเทคนิคปีนี้ได้ k8s แบบขึ้น Production สักที เรียกว่าเริ่มจาก Beginer ที่เรียนคอร์สแค่คอร์สเดียวแล้วลุยเดี่ยวกับ Vendor ที่แม่งตอบแบบ เฮ้ย เอาจริงดิ มันใช่จริงเหรอวะ กูทำตาม Manual ที่มึงบอกแล้วมันไม่ได้นะ ถึงขนาดที่ต้องไปแกะ template config ของแม่งจนรู้ว่า set ผิดแล้วต้องมา override ทับแม่ง ซึ่งถ้ามองว่าเป็นข้อดีก็ดีแหละจาก k8s ประมาณ 10/100 ตอนนี้น่าจะได้สักประมาณ 40/100 ละ

ส่วนเรื่องทีม ปีนี้มีคนออกเยอะมาก ทีมผมนี่แทบจะออกกันหมดเลย ซึ่งผมก็พอเข้าใจเหตุผลของทุกคนออกไป ถ้าเราเจองานที่ดีกว่าถูกใจกว่าสบายใจที่จะทำกว่ามันก็เป็นเรื่องปกติที่จะต้องเลือกทางนั้น ส่วนคนที่อยู่ก็ต้องปรับปรุงที่ที่เราอยู่เนี่ยให้มันดีขึ้น น่าอยู่ขึ้น เพื่อที่จะให้คนเก่าที่ยังอยู่นั้นยังคิดว่ามันดีกว่าที่อื่นและรองรับคนใหม่ที่กำลังจะเข้ามาให้เขารู้สึกว่าการมาอยู่ที่นี่นั้นดีและเหมาะกับเขา

ความรัก

สำหรับปีนี้เรื่องความรักก็ยังวนอยู่ที่เดิม ในเรื่องของตัวบุคคลก็คือกลับไปคุยกับคนที่เคยจีบไปเมื่อสองสามปีที่แล้ว ซึ่งต้นเหตุที่กลับไปคุยกันก็เพราะเราดันไปเจอป้ายโฆษณาวงเกาหลี ก็เลยถ่ายส่งไปให้เขาดูว่ามันมีป้ายอย่างใหญ่เลยนะน้องมาถ่ายรึยัง จากเหตุการณ์นั้นก็เลยลองกลับไปคุยกันอีกรอบ ได้ไปดูหนังได้ไปกินข้าวด้วยกัน (แต่เราไม่เคยถ่ายรูปคู่ด้วยกันสักครั้งเลย) แต่ทุกอย่างมันก็จบแบบเดิมคือเหมือนลักษณะการใช้ชีวิตของสองคนไม่เหมือนกัน ชอบคนละอย่าง ใช้ชีวิตคนละแบบ อีกทั้งน้องเขาเองก็มีตัวเลือกที่น่าสนใจกว่าผมด้วย ส่วนตัวผมเองก็ยังไม่สามารถก้าวข้ามเส้นการตัดสินใจเรื่องความรักได้ ผมไม่สามารถนิยามได้ว่าสิ่งที่ผมรู้สึกมันคือความรักแบบที่ควรจะมี หรือเป็นแค่ความต้องการทางของร่างกายเฉยๆ ซึ่งด้วยทั้งหมดทั้งมวลมันก็มาจบที่น้องเขาก็เลือกตัวเลือกที่ถูกใจกว่า
ส่วนผมก็ยอมรับการตัดสินใจและอยู่กับคำถามเรื่องความรักของผมต่อไป ส่วนในเรื่องของทัศนคติก็เป็นเหมือนที่ได้อ่านไป ผมยังคงวนเวียนอยู่กับการนิยามคำว่ารัก รักที่ถูกที่ควรมันคืออะไร ซึ่งจริงๆมันอาจจะไม่ยุ่งยากถ้าผมไปให้สุดไม่ต้องสนใจอะไร หาผู้หญิงสักคนคุยด้วยพอถูกคอแล้วก็ขอเป็นแฟนไป ได้ก็ดีถือว่าได้ลอง ไม่ได้ก็ช่างแม่ง แต่ก็เสือกคิดเยอะ คิดว่ามันเหมาะมันควรแล้วเหรอที่จะใช้คำว่ารักโดยที่ไม่รู้ว่ามันคืออะไร หรือเราบอกว่ารักโดยที่อีกฝ่ายไม่รู้ว่ารักของเรากับรักของเขาตรงกันไหม แล้วพาทั้งเขาและเราไปเสียเวลาในความรักที่ทั้งคู่เห็นไม่ตรงกัน

ตอนนี้ก็เลยเคว้งคว้างไม่รู้จะเอายังไง ซึ่งจริงๆก็มีคนที่เราชอบอยู่ เป็นน้องที่น่ารัก คุยเก่ง อยากจะลองจีบอยู่เหมือนกัน แต่พอคิดถึงเรื่องที่ต้องเจอแล้วก็ไม่อยากจีบเหมือนกัน และก็เหมือนว่าน้องเขาจะมีคู่หรือคนมาจีบอยู่แล้วก็เลยดูอยู่ห่างๆ แสดงความรักแบบห่างๆ ต่อไปละกัน

อารมณ์

อารมณ์ปีนี้นี่คือเหวี่ยงสุดๆเป็นได้ทั้งคนดีที่สุดสุขมที่สุดไปจนถึงคนที่พร้อมจะบวกเอาให้แหลกเอาให้ยับ ซึ่งดูเหมือนอย่างหลังจะเกิดบ่อยกว่าอย่างแรก ตอนนี้ก็คงได้แค่พยายามลดความเดือดของตัวเองซึ่งก็น่าจะยากคงจะต้องเป็นใช้เหตุผลให้มากขึ้น เพราะผมเชื่อว่าถ้ามีเหตุผลต่อให้มันดุเดือดแค่ไหนมันก็จบได้ถ้าเราใช้เหตุผล

สุขภาพ

ปีนี้เริ่มรู้สึกว่าร่างกายเริ่มแย่อาจจะเพราะผ่านไปครึ่งชีวิตละ ไม่ว่าจะปวดหัวเข่า เหนื่อยง่าย คิดช้า ตอบสนองได้ไม่ไวเหมือนแต่ก่อน ก็เลยคิดว่าถ้าปล่อยไว้แบบนี้น่าจะตายไว (คุณอาจจะไม่รู้ แต่ผมอยากเป็นอมตะไม่ตาย) ดังนั้นก็เลยหันมาเริ่มออกกำลังกายแบบง่ายๆจำพวกยกดัมเบล วิดพื้น เดินแกว่งแขน โยคะง่ายๆ เพื่อให้ร่างกายได้ทำงาน ซึ่งก็ไม่รู้ว่าจะทำให้ผมมีชีวิตรอดไปจนถึงวันที่มีเทคโนโลยีอมตะไหม

ตามศิลปิน

ปีนี้ก็ยังตามศิลปินอยู่เหมือนเดิม ตอนแรกว่าจะน้อยลงแต่ดันไปเจอศิลปินที่ชอบคนใหม่ๆขึ้นมาอีก แต่ก็มีหลายคนที่เลิกเป็นศิลปินไป บางคนเลิกแล้วก็หายไปเลย (ซึ่งก็หาเจอแต่เห็นแล้วรู้ว่าเขาต้องการความส่วนตัวมากๆ) บางคนก็ย้ายไปทำอย่างอื่น ปีนี้ก็น่าจะยังตามอยู่แต่คิดว่าไม่น่าจะหาเพิ่มละคงเป็นศิลปินคนเก่าๆที่ได้ตาม

อ่านหนังสือ

หลังจากเริ่มอ่านหนังสือพวกปรัชญา นิยาย มาได้หลายปีก็ได้เจอปัญหาหนังสือล้นบ้าน แม่เริ่มบ่นว่าห้องรกไม่มีที่จะวางของ ซึ่งทำให้ต้องหาวิธีหาหนังสือมาอ่านแทนการซื้อ ซึ่งวิธีแก้ปัญหาก็คือการไปสมัครสมาชิกห้องสมุดนั่นเอง ซึ่งผมไปสมัครเป็นสมาชิกรายปีกับห้องสมุด TK Park ซึ่งถือว่าเป็นการตอบโจทย์ดีเกินคาด เพราะผมได้อ่านหนังสือเยอะขึ้นโดยไม่ต้องเสียเงินซื้อหนังสือ แถมยังสามารถอ่านหนังสือบางเล่มที่ไม่ได้ตีพิมพ์อีกแล้ว ซึ่งผมสามารถยืมหนังสือได้หลากหลายประเภทมากๆไม่ว่าจะเป็นปรัชญา วรรณกรรมคลาสิคของประเทศต่างๆ ซึ่งพอได้อ่านแล้วรู้สึกได้เห็นโลกในมุมมองใหม่ๆ ได้เห็นเทคนิคการเขียน การเล่าเรื่อง ความรู้ในศาสตร์ต่างๆที่แตกต่างออกไป สำหรับใครที่ชอบอ่านหนังสือและอยู่ในกรุงเทพ ผมแนะนำให้ลองสมัครสมาชิก TK Park ดูครับรับรองว่าคุ้มแน่นอน

งานอดิเรก

ปีนี้ยังคงทำช่อง Youtube กับ Blog เหมือนเดิม โดยช่องจะเพิ่มเนื้อหาสอนทำโจทย์จากเว็บ programming.in.th ส่วน podcast ที่ว่าจะทำสัปดาห์ละตอน แต่พอทำไปเรื่อยๆเหมือนจะหมดเรื่องพูดเลยหยุดทำไปนานพอสมควร ก็เลยเปลี่ยนเป็นอยากพูดเมื่อไหร่ค่อยทำ ส่วน Blog ก็ลงเกี่ยวกับการเขียนโปรแกรมบ้าง แต่ปีนี้จะลงเกี่ยวกับหนังสือซะส่วนใหญ่เพราะอยาก Review หนังสือที่คิดว่าดีให้คนอื่นไปลองอ่านบ้างบวกกับอยากทำเป็น Gallery บันทึกว่าตัวเองเคยอ่านอะไรไปบ้าง

ปีนี้มีกลับไปเขียนนิยายที่เคยเขียนไว้แต่เขียนไม่จบต่อ แต่เขียนไปแล้วรู้สึกว่าจะห่างไปนานน่าจะเขียนไม่จบแน่ๆเลยปล่อยมันไว้ก่อน ตอนนี้เลยเปลี่ยนไปเขียนเรื่องสั้นเป็นตอนแทนๆโดยตอนนี้ลงไป 2 ที่ยอดคนอ่านเป็น 0 เลย ซึ่งก็พอเข้าใจเพราะเรื่องสั้นที่เขียนเนี่ยเป็นเรื่องที่อ่านแล้วชวนหงุดหงิด อ่านแล้วอยากจะต่อยคนที่เขียน แถมไม่ใช่แนวที่เป็นที่นิยมด้วย ตอนแรกว่าจะเป็นงานอดิเรกที่สร้างรายได้ แต่ไปๆมาๆก็กลับมาอยู่ในหมวดงานอดิเรกไม่สร้างรายได้ซะแล้ว

เป้าหมายเมื่อปีที่แล้ว

  • ทำ podcast ทุกสัปดาห์

    อันนี้คือไม่ได้ทำเพราะหมดเรื่องพูด ตอนนี้เป็นทำเมื่ออยากทำแทนละ

  • อ่านหนังสือทุกวัน

    อันนี้ทำได้และเหมือนจะกลายเป็นนิสัยไปละคือถ้าไม่ได้อ่านจะเหมือนชีวิตขาดอะไรไป

  • เล่นกีต้าร์

    อันนี้เหมือนเดิมเลยคือเอากีต้าร์ไว้บริษัท พอ Work From Home ก็เลยไม่ได้จับเลย

  • หาอาชีพเสริมที่ได้เงินแบบจริงๆจังๆ

    อันนี้กลับไปเขียนนิยายแล้วก็เขียนเรื่องสั้นละ แต่ดูเหมือนจะไม่ตอบโจทย์สักเท่าไหร่ อาจจะต้องไปหัดเขียนนิยายแบบที่คนปกติเขาชอบกันบ้าง

  • ลองเล่น IOT

    อันนี้ไม่ได้เล่นเลยเพราะไม่ใส่ใจเองแล้วก็ไม่รู้จะเอาไปประยุกต์กับอะไรด้วย คงจะต้องอยากลองทำอะไรที่เป็น Hareware จริงๆดูถึงจะได้ลองทำ

ปี 2023 ทำอะไรดีล่ะ

  • หาอาชีพเสริม

    เรื่องนี้ก็ยังเป็นเรื่องหลักที่อยากทำ อย่างแรกคงจะลองเขียนเรื่องสั้นต่อไปสัก 10 - 20 ตอน แล้วเปลี่ยนไปเขียนนิยายดูสักเรื่องสัก 10 - 20 ตอน หรือไม่ก็อาจจะลองเป็นติวเตอร์สอนเขียนโปรแกรมดูสักครั้ง

  • ทำช่อง Youtube เป็นช่องสอนเขียน Code

    จริงๆเริ่มทำแล้วแต่ขาดความต่อเนื่องและความจริงจังในการทำ ปีหน้าก็เลยกะทำแบบจริงจังละ เผื่อว่าถ้าทำได้ดีจะได้เป็นช่องให้ความรู้กับคนอยากเขียนโปรแกรมกับเป็นผลงานที่ใช้บอกความสามารถของตัวเอง

  • ออกกำลังกาย

    ปีหน้าจะออกกำลังกายเป็นประจำทุกวัน อาจจะเป็นการออกกำลังกายเล็กๆน้อยๆแบบ วิดพื้น ซิตอัพ เล่นดัมเบล เล่นโยคะแบบง่ายๆเพื่อบิดตัว ยืดร่างกาย โดยหวังว่าน่าจะทำให้ร่างกายยังแข็งแรงเหมือนเดิม

ถึงปีนี้จะเป็นปีที่ว่างเปล่าแต่มันก็เป็นปีที่เต็มไปด้วยเรื่องราวต่างๆไม่ว่าจะเรื่องดี เรื่องร้าย ซึ่งทุกอย่างมันผ่านไปแล้วไม่สามารถกลับไปแก้ไขอะไรได้ แต่มันจะเป็นความทรงจำบทเรียนที่จะอยู่กับผมไปตลอดไป และสุดท้ายหวังว่า “เราคงจะได้พบกันอีก”

เพลงที่ได้ฟังในปีนี้

Nobody knows
ถ้าเธอ
Not Ready to Lose You
สมมติว่าเรา
คืนวันศุกร์
ชอบอยู่คนเดียว
705
Call Center
เหตุผลง่ายๆ
เฮอร์ไมโอน้อง ในจักรวาลอนิเมะ
 I Ain’t Worried
Top Gun Anthem
24/7 You
แก้ตัว
ไปต่อไม่ไหว
SIGH
Soudane
ファンサ(Fansa) cover by Baifern
BFF
คนหรือไมโครเวฟ (Microwave)

Node-RED - ตอนที่ 1 - ทำ Mock Server ด้วย Node-RED

Node-RED - ทำ Mock Application Server ด้วย Node-RED

ปัญหาในการใช้งาน Application Server ที่ต้องทำงานด้วย

ปัญหาหนึ่งที่เจอในเวลาเขียน Program ก็คือเราต้องการใช้งาน Application Server ที่ต้องทำงานด้วย แต่เราไม่สามารถติดต่อมันได้ด้วยเหตุผลบางอย่างเช่น

  • Application Server นั้นเป็นของ Third party เขาไม่เปิดให้ใช้งานจนกว่าจะทำข้อตกลงทางกฎหมายหรือต้องตกลงบางอย่างให้เสร็จก่อน
  • Application Server นั้นยังพัฒนาไม่เสร็จ จะเสร็จก่อนกำหนดเวลา 1 สัปดาห์
  • การเรียกใช้งานนั้นต้องเสียเงิน ตัวอย่างเช่น เรียกใช้งาน SMS Provider ที่ใช้ส่ง OTP ให้ลูกค้า

ซึ่งด้วยปัญหาต่างๆเหล่านี้มักทำให้เราไม่สามารถเขียนโปรแกรมต่อได้ ทางเหล่าผู้พัฒนาก็เลยแก้ปัญหากันโดยกำหนด Spec ในการใช้งานตัว Application Server ขึ้นมา ตัวอย่างเช่น API ใช้งาน Board Trello , CAT FACE เพื่อบอกให้รู้ว่า Application Server มี Request Response อย่างไร เพื่อให้ทีมพัฒนาที่จะมาใช้ด้วยเนี่ยสามารถไปเขียนโปรแกรมก่อนได้

แต่ปัญหามันไม่ได้ถูกแก้เพราะต่อให้เราได้ spec ของ Application Server ที่เราต้องติดต่อด้วยมาแล้ว แต่เราก็ไม่สามารถยิงไปหามันจริงๆได้ ทำให้เราไม่สามารถ Test code ที่เราเขียนขึ้นมาได้ตาม Flow ตัวอย่างเช่น ถ้าคุณต้องเขียน App ซื้อของออนไลน์ Flow การทำงานตั้งแต่ต้นจนจบคือเลือกสินค้าและจ่ายเงิน ในส่วนการเลือกสินค้านั้นเป็นส่วนของเราที่เขียน แต่ส่วนที่เป็นส่วนจ่ายเงินนั้นเป็นส่วนที่คนอื่นเขียนและเราไม่สามารถใช้งานได้ พอไม่สามารถใช้งานได้เราก็ Test ทั้ง Flow ไม่ได้ วิธีแก้ปัญหาที่ไม่ค่อยดีอย่างหนึ่งที่ Developer จำนวนหนึ่งมักใช้คือทำการแก้ Code ตรงที่เรียกให้มันผ่านตลอดหรือมีผลตามที่อยากได้ ซึ่งมันก็ตอบโจทย์การ Test ให้ผ่านไปได้ แต่ปัญหาคือ Developer มักจะลืมกลับไปแก้ Code ตรงนั้นหลังจาก Test เสร็จ ซึ่งมันก็จะลืมไปจนขึ้น Production และเกิดปัญหานั่นเอง

ดังนั้นมันจะมีดีกว่าไหมถ้าเราสามารถติดต่อไป Application Server ที่เราสามารถกำหนด Response ที่ Application Server นั้นตอบกลับได้อย่างที่เราต้องการ โดยไม่ต้องใส่ Logic ให้เหมือนจริง ซึ่งก็ขอดีใจด้วยครับ ชาว Developer ได้สร้างสิ่งนี้ขึ้นมาให้เราแล้วมากมายมันเรียก Mock Server ซึ่งมีอยู่หลายเจ้า โดยเจ้าที่ผมจะเอามาสอนวิธีใช้คือ Node-RED

จริงๆ Node-RED สามารถทำได้มากกว่า Mock server นะครับ มันสามารถทำได้หลายอย่างมากมีหลายคนเอาไปทำเป็น Server ส่งข้อมูลระหว่าง IOT บางคนก็เอาไปทำเป็น Application Server ที่มีหน้าที่ประมวลผลเลยก็มี

Start Node-RED ด้วย Docker

เนื่องจากเข้าใจว่าคนที่มาอ่านบทความนี้คงจะเป็น Dev QA หรือผู้ที่น่าจะเคยใช้งาน Docker มาแล้วดังนั้นจึงขอใช้ Node-RED ในรูปแบบของ Docker เพราะมันสะดวกไม่ต้อง config อะไรให้ยุ่งยาก

1
2
3
4
5
6
7
8
9
10

# ตัวอย่างการเรียกใช้งาน
# path/to/persistent/data ให้เปลี่ยนเป็น path ที่คุณอยากจะ mount data กับ Node-RED
# โดยถ้าไม่ทำการ map ไว้อะไรที่เคยทำไว้จะหายไปทั้งหมด

# กรณีเป็น Linux ให้ run
sudo chown -R 1000:1000 path/to/persistent/data


docker run -d -p 1880:1880 -v path/to/persistent/data:/data --name mock-server nodered/node-red:latest

โดยเมื่อ Run command ด้านบนเสร็จให้ลองเปิด Browser แล้วใส่ url

1
2
3
4
5
http://[ip ของเครื่องที่ Run docker]:8080

# ตัวอย่างคือ เครื่องที่ Run docker มี IP : 192.168.56.101 url ที่ได้จะเป็น

http://192.168.56.101:1880/

ซึ่งเมื่อเปิดแล้วจะได้ภาพแบบด้านล่าง ถ้าทำไม่ผิด

Mock Server

หากทาง Spec ที่ตกลงกันนั้นมี Request กับ Response ดังต่อไปนี้

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

ENDPOINT : /api/data
HTTP METHOD : POST

# HTTP REQUEST
{
"ref" : "string"
}

# HTTP RESPONSE

{
"transactionId" : "string", // unique string
"ref" : "string" // ref from request
}

โดยเรายิง request ที่มี ref ไปทาง server จะ return response กลับไปให้เป็น transactionId ที่สร้างขึ้นมาโดยต้อง unique และต้องเอา ref ส่งคืนกลับไปให้ใน response ด้วย

ด้วยความต้องการด้านบนเราสามารถใช้ Node-red ทำการ Mock server ได้โดยทำตามขั้นตอนดังต่อไปนี้

สร้างขารับ Http request ด้วย http in

  1. เลือก Component ชื่อ http in แล้วลากลงไปใน Flow
  2. ทำการกำหนด Method เป็น POST
  3. ทำการใส่ค่า URL เป็น /api/data
  4. กดปุ่ม Done

สร้างขาตอบกลับ Http response ด้วย

  1. เลือก Component ชื่อ http_response แล้วลากลงไปใน Flow
  2. ทำการลากเส้นจาก http in ไปหา http_response
  3. กด Deploy ด้านขวาบน

ลองทดสอบ Mock Server

  1. ทำการเปิด PostMan จากนั้นตั้งค่า Method เป็น POST

  2. ทำการใส่ url เป็น http://[ip เครื่องที่ run docker]:1880/api/data (ของผมเป็น VM เครื่อง 192.168.56.101)

  3. จากนั้นเลือก Body เลือกชนิดเป็น raw และเปลี่ยน type ของ raw เป็น Json จากนั้นกำหนด body เป็น

    1
    2
    3
    {
    "ref" : "TX1803"
    }

    จากนั้นกด Send

  4. ดู Response ที่กลับมา

    จาก Response จะเห็นว่า response นั้นเหมือนกับ request เลย เพื่อพิสูจน์ว่าเป็นจริงไหมให้ลองแก้ request เป็นข้อมูลแบบอื่นดู เช่น

    1
    2
    3
    4
    {
    "ref" : "TX1803",
    "testInput" : "TEST NEW INPUT"
    }

    จากนั้นยิงใหม่จะเห็นว่าข้อมูล Response ก็เปลี่ยนไปตาม Request

ทำการแก้ไข Response ที่จะตอบกลับ

  1. ทำลาก component : function ลงไปใน flow

  2. ทำการเพิ่ม

    1
    msg.payload.transactionId = "1234567890123";
  3. กด Done

  4. จากนั้นลากเส้นเชื่อมระหว่าง http in <–> function <–> http response

  1. กด Deploy

  2. จากนั้นเปิด Postman และยิง Request เหมือนในข้อก่อนหน้านี้และดูผลลัพธ์ที่ได้

ซึ่งจะเห็นว่ามีฟิลล์ชื่อ transactionId กลับมาใน response ด้วยซึ่งเป็นค่าเดียวกันกับที่เรา ตั้งค่าไปในขั้นตอนที่ 2 ซึ่งจะเห็นว่าเราสามารถตั้งค่าให้ Response ที่จะตอบกลับไปเป็นอะไรก็ได้ผ่านการ set ค่าที่ field msg.payload โดยถ้าเราเปลี่ยนข้อมูลตรง function เป็น

1
2
3
4
msg.payload = {
"field1" : "12345689",
"name" : "nico"
};

จากนั้น Deploy และใช้ Postman ยิงไปใหม่จะได้ข้อมูลดังภาพ

จะเห็นว่า Response ที่ตอบกลับมานั้นจะมีค่าเหมือนกับที่ set ค่าให้กับ msg.payload

  1. ทำการตั้งค่า function เป็นอย่างด้านล่างและกด Deploy

    1
    2
    3
    // ส่วนนี้จะทำการเอาค่า unix timestamp มาเป็น transactionId ซึ่งถ้าไม่ยิงมาพร้อมกันจริงๆเลขจะไม่ซ้ำกัน
    var transactionId = String(Date.now());
    msg.payload.transactionId = transactionId;

  2. ลองยิงด้วย Postman จะเห็นว่าได้ข้อมูลตาม spec api ที่ต้องการ

Export Flow และ Import Flow

Export Flow

เราสามารถ Export flow ที่เราพึ่งเขียนไปออกมาเก็บไว้ที่เครื่องตัวเองหรือจะส่งต่อให้ Dev คนอื่นๆที่ทำงานร่วมกับเราก็ได้โดยทำตามภาพ โดยไฟล์ที่ได้จะเป็นไฟล์ .json

Import Flow

เราสามารถ Import flow ได้โดยกดเลือก Import ตามภาพ

สรุป

ในตอนนี้เราสามารถทำการ Mock Http Response ให้สามารถตอบกลับตาม spec ที่เราต้องการได้แล้ว ในส่วนของ Component http in , http response ต่างๆนั้นสามารถทำอะไรได้อีกหลายๆอย่าง โดยสามารถไปอ่านเพิ่มได้ที่ https://cookbook.nodered.org/http/#http-endpoints

Protagoras - โปรตากอรัส

Protagoras - โปรตากอรัส

ความคิดเห็นส่วนตัว : ถ้าท่านเป็นผู้ชอบตั้งคำถาม ชอบการต่อสู้กันด้วยคำพูด แนะนำให้อ่านเป็นอย่างยิ่ง

Protagoras - โปรตากอรัส

หลังจากได้อ่านงานของเพลโตที่ชื่อ Republic แล้วรู้สึกชอบแนวคิดกับวิธีการสนทนาของโสคราตีส ซึ่งเพลโตเป็นลูกศิษย์ของโสคราตีส ผลงานที่เขาเขียนนั้นจะเอาอาจารย์ของเขาเป็นตัวดำเนินเรื่องโดยไปทำการสนทนากับผู้รู้ต่างๆและพยายามตามหาความจริงเกี่ยวกับเรื่องที่สนทนา หลังจากไปลองหางานของเพลโตดูก็พบว่ามีอกหลายเล่มที่มีลักษณะแบบนี้ ซึ่งเล่มที่พอจะยืมมาอ่านได้เลยก็คือ Protagoras - โปรตากอรัส เล่มนี้

หนังสือเล่มนี้เป็น “นิยาย” ย้ำนะครับว่า “นิยาย” เป็นเรื่องที่แต่งขึ้นโดยเฟลโต ซึ่งมีจุดประสงค์ใช้มันในการเผยแพร่แนวคิดของตนกับอาจารย์ และสั่งสอนชาวกรีกในยุคนั้นให้เป็นคนที่มีคุณธรรมแบบที่ถูกต้องตามแนวคิดของตน อีกทั้งยังทิ้งคำถามต่างๆที่ยังแก้ไม่ได้ให้คนที่ได้อ่านนำไปขบคิดกัน ซึ่งก็เหมือนจะได้ผลเพราะทุกวันนี้คำถามที่อยู่ในหนังสือเล่มนี้ก็ยังถูกนำมาขบคิดกันอยู่ว่ามันใช่หรือไม่ใช่ เราควรแบ่งสิ่งนั้นแบบไหนและอย่างไร โดยเรื่องนี้จะแต่งให้โสคราตีสมาสนทนาและพยายามหาความจริงกับ โปรตากอรัส ซึ่งได้รับขนานนามว่าเป็นนักปราชญ์ชื่อดังแห่งยุค และเป็นนักปราชญ์ที่ริเริ่มเก็บเงินจากคนที่มาขอเรียน (ติวเตอร์ยุคแรกเลยนะเนี่ย)

คุณธรรมของชาวกรีก

คุณธรรมของแต่ละที่บนโลกนั้นแตกต่างกัน คุณธรรมของชาวพุทธอาจจะเป็นแบบหนึ่ง คุณธรรมของชาวคริสต์ก็จะเป็นอีกแบบหนึ่ง ดังนั้นก็แน่นอนว่าคุณธรรมของชาวกรีกก็จะมีลักษณะเฉพาะตัวไม่เหมือนที่อื่นโดยคุณธรรมของชาวกรีกจะประกอบไปด้วย

  • ปัญญา (Wisdom) : คือความรู้ในเรื่องศาสตร์ต่างๆรวมถึงความรู้ในการใช้ชีวิตให้มีความสุข

  • ความชอบธรรม (Justice) : คือความถูกต้อง เป็นธรรม ซึ่งจะความหมายแบบเดียวกันกับยุคเราเลย

  • ความกล้าหาญ (Courage) : คือความกล้าหาญที่จะไปสู้รบทำสงคราม ในข้อนี้อาจจะแปลกๆในยุคนี้แต่ในยุคกรีกนั้นมีสงครามเกิดขึ้นอยู่ตลอด ถ้าคนไม่มีความกล้าหาญออกไปสู้สงคราม บ้านเมืองก็จะล่มสลายเพราะถูกศัตรูเข้ามาโจมตีและยึดเมืองและสุดท้ายก็สูญสิ้นอิสรภาพ

  • ความเคารพกฎของเทพ (Piety) : คือการทำกฎของเทพหรือจะมองง่ายๆก็คือการทำตามหลักของศาสนา

  • ความรู้จักพอดี (Temperance) : คือรู้ว่าเท่าใดที่เหมาะไม่มากหรือไม่น้อยจนเกินไป เช่น กล้าหาญมากจนเกินไปก็จะทำให้ไปตายเปล่า ประหยัดมากเกินไปจนกลายเป็นตระหนี่ก็ทำให้ใช้ชีวิตลำบาก ว่าง่ายๆก็คือทางสายกลางของพุทธศาสนานั่นแหละครับ

ในเรื่องนั้นโสคราตีสอยากจะให้โปรตากอรัสอธิบายว่าและพิสูจน์ว่าคุณธรรมนั้นสามารถสั่งสอนกันได้หรือไม่ เพราะโสคราตีสนั้นไม่คิดว่าเป็นอย่างนั้นเลยอยากจะขอร้องให้ผู้ที่มีความรู้แห่งยุคช่วยอธิบายและพิสูจน์

คุณธรรมทั้ง 5 อย่างนั้นเป็นสิ่งเดียวกัน หรือ ทั้ง 5 อย่างแยกเป็นส่วนๆแล้วมารวมกันเป็นคุณธรรม

อีกคำถามหนึ่งซึ่งโสคราตีสถามโปรตากอรัสก็คือ คุณธรรมทั้ง 5 เป็นสิ่งเดียวกัน หรือ ทั้ง 5 อย่างเป็นคนละอย่างกันแต่รวมกันแล้วจะกลายเป็นคุณธรรม คำถามนี้อาจจะดูไร้สาระในมุมมองของเรา แต่ผู้แปลได้ให้คำอธิบายถึงความสำคัญของคำถามนี้ ซึ่งก็คือหากคุณธรรมเป็นสิ่งเดียวกันหมด คนเราจะมีแค่ มีคุณธรรมกับไม่มีคุณธรรมเพียงเท่านั้น ขาดอย่างใดอย่างหนึ่งย่อมเป็นผู้ไม่มีคุณธรรม เช่น เป็นคนมีความกล้าหาญแต่ขาดความรู้ย่อมไม่ใช่ผู้มีคุณธรรม เขาจะเป็นแค่คนบ้าบิ่นที่พร้อมจะทำอะไรก็ได้โดยไม่คิด หรือ หากเป็นคนมีความรู้แต่ไม่มีความกล้าหาญก็ไม่ใช่ผู้มีคุณธรรมแถมเขาก็ไม่ใช่ผู้ที่มีความรู้ด้วย เพราะอย่าลืมว่าทั้ง 5 อย่างคือสิ่งเดียวกันถ้าไม่มีสิ่งใดก็เแปลว่าไม่มีอีก 4 อย่างด้วยไปโดยปริยาย ดังนั้นคนที่บอกว่ามีความรู้แต่ไม่มีความกล้าหาญก็แปลว่าไม่มีความรู้จริง เพราะคนรู้จริงย่อมจะรู้ว่าเวลาไหนควรมีความกล้าหาญที่จะเข้าไปต่อสู้ ซึ่งแตกต่างจากถ้าคุณธรรมเกิดจาก 5 สิ่งรวมกันเราสามารถบอกได้ว่าเขาเป็นผู้มีคุณธรรม 3 ส่วน 4 ส่วน 1 ส่วน

การวัดระดับคุณธรรม

การวัดว่าคนคนหนึ่งมีคุณธรรมหรือไม่นั้นอาจจะวัดจากการที่เขาประพฤติและการกระทำของเขาตอนที่เราเห็น โดยการที่เขาตามคุณธรรมนั้นเขาอาจจะทำเพราะกลัวความผิดที่จะได้รับไม่ว่าจะจากกฎหมายหรือสังคม ซึ่งทางโปรตากอรัสก็มองว่าเพียงพอแล้วเพราะคนอยู่ในกฏหมายและไม่ทำให้คนอื่นเดือดร้อนแล้ว (สมัยนี้เราก็ยึดหลักนั้น) แต่ในมุมมองของโสคราตีสนั้นมองว่าคนคนนั้นไม่ได้เป็นผู้มีคุณธรรม คนผู้ที่มีคุณธรรมจริงๆนั้นจะยึดมั่นในคุณธรรมทุกชั่วขณะ ไม่ว่าจะมีคนเห็นหรือคนไม่เห็น หรือแม้แต่กฏเกณฑ์กติกาจะแปรเปลี่ยแบบสุดขั้ว ลองนึกถึงตัวอย่างว่ามีคนชั่วมาปกครองแผ่นดินแล้วออกกฎหมายว่าการขโมยนั้นไม่ผิดตราบเท่าที่แบ่งส่วนที่ปล้นได้ให้รัฐด้วย ถ้าคุณมีคุณธรรมแบบแรก คุณสามารถเปลี่ยนไปปล้นฆ่าคนได้เพราะมันไม่ผิดกฎหมายแล้วและสังคมมองว่ามันถูกต้อง แต่คนในแบบที่สองจะไม่ทำเพราะเขาเข้าใจว่าสิ่งที่ทำนั้นไม่ถูกต้อง ไม่มีคุณธรรม ซึ่งถ้ามองดูแล้วก็จะคล้ายๆกับหลักการของศาสนาพุทธที่มักสอนเราอยู่เสมอว่า ทำชั่ว ทำดี เรารู้อยู่แก่ใจ ต่อให้ขโมยโดยไม่มีใครเห็นตัวเราก็รู้อยู่ดีว่าเราขโมย ซึ่งจะเห็นว่าหลักการพวกนี้มีอยู่ทั่วโลกไม่ได้มีแค่ในศาสนาพุทธ (จริงๆตั้งแต่เรื่องความพอดีละ)

เฉือดเฉือนกันด้วยเหตุผล

ในเรื่องนี่จะมีการต่อสู้กันด้วยวาทศิลป์ซึ่งเป็นอะไรที่สนุกมาก มันเหมือนคุณไปดูผู้สมัครเลือกตั้งมาโต้เถียงกันในหัวข้อต่างๆ โดยในเรื่องคุณจะได้เห็นคน 2 คนพยายามเอาชนะกัน คนนึงเป็นสาย พรรณาให้เห็นภาพใช้วาทศิลป์ทำให้คนคล้อยตาม (ซึ่งคนในปัจจุบันเราจะเจอคนเหล่านี้เยอะมาก) กับอีกคนนึงที่จะใช้เหตุผลในการพิสูจน์ทฤษฎีของอีกฝั่ง และใช้มันเพื่อพิสูจน์ทฤษฎีของตน (คนแบบนี้หายากในยุคปัจจุบัน) เราจะได้เห็นการแก้เกมส์ของทั้งสองคนเพื่อพิสูจน์คำพูดของตนเองและทำให้คนอื่นเชื่อด้วย (อย่าลืมว่าคำพูดของคุณแม้จะจริง แต่ถ้าคนอื่นไม่เชื่อก็ไม่มีประโยชน์) ซึ่งผมขอบอกเลยว่ามันสนุกจริงๆ

อ่านแล้วได้อะไร

สำหรับการได้อ่านหนังสือเล่มนี้นั้นทำให้ผมได้คำถามมากมายที่น่าสนใจ ไม่ว่าเรื่องคุณธรรมนั้นสามารถสั่งสอนกันได้หรือไม่ คุณธรรมเป็นสิ่งเดียวกันหรือไม่ แล้วเราใช้อะไรเป็นตัวบอกว่าคนคนนั้นมีคุณธรรม ต้องพิสูจน์ระดับไหน ซึ่งจริงๆผมก็ค่อนข้างเห็นด้วยกับโปรตากอรัสที่เราตัดสินมนุษย์ว่ามีคุณธรรมผ่านการกระทำก็น่าจะเพียงพอ ซึ่งถ้าคุณธรรมอยู่ในระดับนี้เราก็สามารถสั่งสอนให้คนมีคุณธรรมได้โดยการสอนให้รู้ว่าการไม่มีคุณธรรมแล้วจะเจอกับอะไร แต่นั่นมันใช่คุณธรรมควรที่จะเป็นหรือเปล่า เพราะคุณทำไม่ดีไม่มีคุณธรรมแต่ไม่มีคนเห็นคุณก็ยังเป็นผู้มีคุณธรรมอยู่

แล้วถ้าคุณธรรมนั้นอยู่ในระดับที่สูงกว่าคือไม่ว่าจะเจอสถานการณ์ใดผู้มีคุณธรรมต้องยึดมั่นที่จะรักษาคุณธรรม ถ้าเป็นคุณธรรมคือสิ่งนี้มันเป็นไปได้ไหมที่จะสั่งสอนได้ หรือมันเป็นเรื่องของแต่ละบุคคล แล้วถ้ามันเป็นเรื่องของแต่ละบุคคลอะไรที่ทำให้เขามีคุณธรรมล่ะ

อีกอย่างหนึ่งที่ผมชอบเกี่ยวกับเรื่องนี้คือ ตอนจบนั้นเราจะไม่เห็นผู้ที่ชนะเบ็ดเสร็จเด็ดขาด แต่เราจะเห็นว่าพอมาถึงข้อสรุปเราจะพบว่าข้อสรุปนั้นมันขัดแย้งในตัวเองกันทั้ง 2 ฝั่ง (ซึ่งความขัดแย้งนั้นคืออะไรไปลองอ่านดู มันเป็นอะไรที่น่าตกใจ) ซึ่งนั่นทำให้เกิดความสงสัยว่า ข้อสรุปที่พิสูจน์กันได้นั้นมันผิด หรือสิ่งที่ตนเองนั้นเชื่อนั้นผิด ซึ่งนั่นเปิดโอกาสให้เราได้ใช้ความคิดของเราซึ่งเป็นคนยุคใหม่ที่เรามักพูดเสมอเจริญกว่า เก่งกว่า ไปทำการพิสูจน์ต่อว่าตกลงแล้ว คุณธรรมสามารถสั่งสอนกันได้หรือไม่ และ คุณธรรมทั้งหมดเป็นสิ่งเดียวกัน หรือ คุณธรรมแยกเป็นส่วนๆแล้วมาร่วมกันกลายเป็นคุณธรรม

LUNA - The Immersive Musical Experience

LUNA - The Immersive Musical Experience

ความคิดเห็นส่วนตัว : เป็นละครเวทีที่สนุกถ้าคุณชอบความสมจริงในการรับรู้เนื้อเรื่อง

LUNA - The Immersive Musical Experience

ผมรู้จักละครเวทีเรื่อง LUNA จากการที่น้องที่รู้จักได้ไปแสดงในละครเวทีเรื่องนี้ พอไปดูรายละเอียดเกี่ยวกับละครเวทีเรื่องนี้ก็เจอจุดน่าสนใจคือ เขาบอกว่ามันเป็นละครเวทีที่คุณต้องเดินไปกับตัวละคร แถมคุณสามารถเลือกได้ว่าคุณจะตามตัวละครตัวไหนก็ได้ แถมคุณยังสามารถคุยโต้ตอบกับตัวละครในเรื่องได้ด้วย ซึ่งจะต่างจากละครเวทีที่ผมเคยดูมาทั้งหมดที่เราเป็นเพียงผู้นั่งชมดูความเป็นไปของตัวละคร อย่างมากสุดตัวละครก็หันมาคุยกับเราแบบ Breaking the Fourth Wall (เหมือนที่ Dead pool หันมาคุยกับคุณเนี่ยแหละ) ดังนั้นผมจึงตัดสินใจซื้อบัตรไปดูละครเรื่องนี้

เริ่มเดินทาง

บัตรเข้าขม

ถ้าเป็นละครเวทีแบบที่ผมเคยดูเขาจะให้เราเข้าประตูแล้วไปจับจองที่นั่ง แต่ LUNA ไม่ใช่ครับ หลังจากคุณได้บัตรคุณจะต้องเลือกฝั่งที่จะเข้า คุณอ่านไม่ผิดครับคุณจะได้เลือกฝั่งที่เข้าโดยมี 2 ฝั่งให้คุณเลือกคือ ฝั่งเมือง กับ ฝั่งป่า และพิเศษกว่านั้นคุณสามารถได้บัตรพิเศษเพื่อใช้ในการดำเนินเรื่องที่เฉพาะคนที่มีบัตรพิเศษด้วย โดยเงื่อนไขในการได้บัตรพิเศษมาคือร่วมสมทบทุนบริจาคเข้ามูลนิธิชัยพฤกษ์ แต่ต่อไม่ให้มีบัตรพิเศษคุณก็ดูละครเวทีได้ตามปกติ จากนั้นเมื่อเลือกฝั่งเสร็จแล้ว ทีมงานจะให้เราเข้าไปในโรงละครซึ่งจะถูกจัดเป็นธีมต่างเนื้อเรื่อง

ดำเนินเรื่อง

พอคนเข้าไปในโรงละครครบเขาก็จะเริ่มแสดงคือต้องอธิบายก่อนว่าละครเวทีเรื่องนี้เขาแสดงพร้อมกันทั้ง 2 ฝั่ง ถ้ามองง่ายๆคือมันเหมือนชีวิตจริงเลย คือระหว่างที่ผมดูละครเวที เพื่อนผมก็อาจจะกำลังเตะบอลอยู่ ดังนั้นระหว่างที่ฝั่งป่าดำเนินเรื่อง ฝั่งเมืองก็ดำเนินเรื่องอยู่เช่นกัน ดังนั้นมันจึงเหมือนจริงมาก คราวนี้พอดำเนินเรื่องไปถึงจุดหนึ่งแล้วตัวละครจะเริ่มแยกไปตามเส้นทางของแต่ละตัวละคร พอถึงตรงนี้คุณจะต้องเลือกครับว่าคุณจะต้องเลือกว่าจะไปกับตัวละครไหน และแน่นอนว่าทุกตัวละครก็ดำเนินเรื่องพร้อมกัน นั่นแปลว่าถ้าคุณไปกับตัวละคร A คุณจะเห็นการดำเนินเรื่องผ่านตัวละคร A คุณจะไม่รู้เลยว่าตัวละคร B นั้นเจออะไร ซึ่งก็เหมือนกับชีวิตจริงเลยแหละครับ

คราวนี้เมื่อดำเนินไปเรื่อยๆมันจะมีจุดที่ตัวละครของทั้ง 2 ฝั่งมาเจอกันคือฝั่งป่ากับฝั่งเมือง ตรงจุดนี้เราจะเห็นความขัดแย้ง ความเกี่ยวข้องกับทั้ง 2 ฝั่ง และที่สนุกกว่านั้นคือละครเวทีเรื่องนี้อนุญาตให้เราเปลี่ยนไปตามละครที่คุณเจอระหว่างทางตรงนั้นได้เลย ประมาณว่าผมเริ่มที่ฝั่งป่า คราวนี้ผมไปเจอตัวละครฝั่งเมือง ผมสามารถเปลี่ยนไปตามตัวละครฝั่งเมืองที่ผมสนใจได้เลย

ซึ่งพออ่านมาถึงตรงนี้คุณอาจจะสงสัยว่าเฮ้ยแล้วมันจะรู้เรื่อง ผมก็อยากบอกว่ามันเหมือนชีวิตจริงนั่นแหละครับ คุณไปอยู่ในเหตุการณ์ใหญ่เหตุการณ์หนึ่ง คุณเห็นเฉพาะในมุมมองของคุณ แต่สุดท้ายคุณก็สามารถเข้าใจภาพรวมได้ LUNA ก็เช่นกันครับ พอจึงจุดสรุปของเรื่องคุณจะเข้าใจภาพรวมทุกอย่างของเรื่อง เหตุผลของตัวละครหลัก ปมปัญหาทั้งหมด คุณจะเข้าใจภาพรวมตรงนี้ แต่ถ้าเป็นส่วนรายละเอียดเชิงลึกของตัวละครที่คุณไม่ได้ไปด้วยคุณจะไม่รู้

ในส่วนของการมีปฏิสัมพันธ์กับตัวละครนั้นจะเปิดโอกาสเป็นช่วงๆให้เราได้คุยได้ถามตัวละคร ในกรณีของผมได้เดินไปกับตัวละครยายแซน เขาเปิดโอกาสให้เราได้ถามเรื่องต่างๆ ไม่ว่าจะเป็นอดีตของแก ทำไมแกถึงแก่ลงเร็วมากๆ ทำไมต้องปกปิดความลับบางอย่างกับ LUNA ซึ่งตัวละครก็จะตอบเราภายใต้สิ่งที่ตัวละครตัวนั้นรู้ หรือว่าง่ายๆก็เหมือนเราคุยกับคนปกตินั่นแหละครับ ถามอะไรก็ตอบเท่าที่เขารู้นั่นแหละ แต่มันก็เปิดเป็นช่วงๆนะครับแล้วมันก็มีขอบเขตคือเป็นแค่ถามตอบเท่านั้น คุณไม่สามารถถามเขาตอนที่เขากำลังดำเนินเนื้อเรื่องหลักได้ หรือคุณไม่สามารถไปขวางการต่อสู้ระหว่างคนสองคนได้

ความคิดเห็นส่วนตัว

ของที่ระลึก

ส่วนตัวผมประทับใจกับละครเวทีเรื่องนี้ที่เขาเปลี่ยนวิธีนำเสนอแบบที่ให้เรานั่งดูอย่างเดียวมาเป็นการให้เราเดินทางไปกับตัวละคร และเปิดโอกาสให้เราเลือกว่าเราจะเลือกไปกับตัวละครไหนตามแต่ที่ใจเราต้องการเลย ในส่วนของเนื้อเรื่องนั้นเขาก็ทำออกมาได้ดีคือเขากระจายบทและเนื้อเรื่องไปให้กับทุกตัวละครได้อย่างเพียงพอที่จะทำให้คนดูอย่างเราสามารถปะติดปะต่อเนื้อเรื่องและภาพรวมของเรื่องทั้งหมดได้ระหว่างที่เรื่องกำลังดำเนินไปได้ ในส่วนของเพลงที่ใช้ร้องก็ถือว่าทำมาได้ดีมากๆ คือเขาตั้งใจแต่งให้มันลงทำนองจังหวะเสียงสูงต่ำแถมคำก็สละสลวยด้วย ไม่ใช่แปลๆแล้วเอามาใส่ทำนอง ซึ่งบางเพลงนี่ผมอยากให้เขาอัดทำเป็น OST ขายจริงๆ ในส่วนของนักแสดงนั้นเล่นได้ดีมากๆแสดงความรู้สึกต่างๆออกมาให้เรารู้สึกเศร้า ดีใจ สงสัย โกรธ ไปกับตัวละคร

ทั้งหมดเป็นข้อดีที่ผมได้จากการไปดูละครเรื่องนี้ คราวนี้มาพูดถึงข้อเสียของเรื่องนี้บ้าง ข้อเสียอย่างแรกเลยคือถ้าคุณเป็นคนชอบดูละครหรือละครแบบเก็บรายละเอียด อยากรู้รายละเอียดทั้งหมดของทุกตัวละครเพื่อเข้าใจมุมมองต่างๆของทุกตัวละคร คุณอาจจะไม่ถูกใจละครเวทีเรื่องนี้เพราะอย่างที่ผมอธิบายไปที่ทุกตัวละครดำเนินเนื้อเรื่องไปพร้อมกัน ถ้าคุณไปกับตัวละคร A คุณจะไม่ได้ไปกับตัวละคร B และคุณจะไม่รู้รายละเอียดต่างๆของตัวละคร B เลย ซึ่งผมเป็นพวกชอบเก็บรายละเอียดอยากรู้เกี่ยวกับทุกตัวละคร ดังนั้นผมเลยรู้สึกเหมือนขาดอะไรไปตอนดูจบ ข้อเสียอีกเรื่องนึงคือตัวละครฝั่งป่านั้นน้อยเกินไป คือตัวละครฝั่งป่าเนี่ยที่พูดคุยกับเราได้จริงๆเนี่ยมีประมาณ 4 คน ส่วนอีก 4 คนที่เหลือเป็นภูติซึ่งคุณคุยกับภูติได้แต่ภูติจะตอบกลับคุณเป็นภาษาภูติซึ่งคุณฟังไม่รู้เรื่อง ซึ่งมันกลายเป็นว่าคุณคุยได้แค่ 4 ตัวละคร แตกต่างจากฝั่งเมืองที่ตัวละครเยอะมาก แถมเป็นตัวละครคนที่คุณอาจจะคุยด้วยได้ (ส่วนนี้ผมไม่รู้เพราะเลือกเริ่มฝั่งป่าและไม่ได้ย้ายไปฝั่งเมือง) ผมก็เลยรู้สึกว่าทางฝั่งป่านั้นดูจะมีอะไรน้อยกว่าฝั่งเมือง

โดยรวมแล้วสำหรับผม LUNA เป็นละครเวทีที่ผมแนะนำให้ลองไปดูครับ เพราะมันทำให้คุณได้รับประสบการณ์ใหม่ๆเกี่ยวกับการดูละครเวที เพลงในเรื่องก็เพราะ นักแสดงก็แสดงได้ดี ดังนั้นถ้าใครสนใจหรือลังเลอยู่ผมก็แนะนำให้ไปดูกันครับ

Link ซื้อบัตร : https://ticketmelon.com/castscape/lunathemusical

ข้อแนะนำสำหรับคนอยากไปดู

อันนี้เป็นส่วนเสริมไม่อ่านก็ได้ครับแต่เป็นสิ่งที่ผมคิดว่าถ้าผมมีโอกาสได้ไปดูอีกรอบผมจะทำอะไรบ้าง

  • ถ้าคุณชอบการได้เจอตัวละครเยอะๆ หรืออยากคุยกับตัวละคร ผมแนะนำฝั่งเมืองมากกว่าฝั่งป่า
  • ถ้าตามตัวละครไหนแล้วควรตามให้สุด อย่าสลับไปสลับมา คือตอนผมไปดูเนี่ยเนื่องจากติดนิสัยอยากรู้เกี่ยวกับทุกตัวละครพอเจอตัวไหนที่สนใจเปลี่ยนไปตามคนนั้นเลย ซึ่งพอหลุดจากตัวละครที่เราตามไปแล้วยากมากที่จะกลับไปหาตัวละครนั้นอีก หรือไม่ได้เห็นจุดสำคัญของตัวละครนั้น ซึ่งผมโดนมากับตัวคือผมตามตัวละครคุณยาย แต่เกิดเปลี่ยนใจไปตามตัวละครฝั่งเมือง พอกลับมาอีกทีคุณยายก็ผ่านเหตุการณ์สำคัญมาแล้วซึ่งเหตุการณ์นั้นคืออะไรผมก็ยังไม่รู้เลย ดังนั้นผมแนะนำว่าตามตัวใดตัวหนึ่งไปเลยดีกว่าครับ

ปล. ผมไม่มีส่วนได้ส่วนเสียแม้แต่บาทเดียวกับละครเรื่องนี้ดังนั้นที่ผม Review นี่คือพูดตามเนื้อผ้าล้วนๆ จริงๆดูได้จากข้อเสียที่ผมเขียนก็ได้นะ ถ้ารับจ้างมาอวยคงไม่เขียนข้อเสีย แถมข้อเสียเป็นจุดตายด้วย