88624065 ฐานข้อมูลเชิงสัมพันธ์ · ดร.ชัยศิริ สนิทพลกลาง · ม.บูรพา

สรุป Database บทที่ 1–6 + Lab

สรุปจากสไลด์ใน Classroom ทั้ง 12 ไฟล์ เรียงตามเส้นทางการออกแบบจริง เริ่มจากอ่าน TOR ไปจนถึงเขียน SQL ไอคอน จุดสอบ คือเรื่องที่สไลด์เน้นหรือมีแบบฝึก ขีดเส้นใต้สีทอง คือ Primary Key ส่วน ตัวเอียงสีเขียว คือ Foreign Key

TOR + Lab
อ่านความต้องการStakeholder, กริยา = Process, นาม = Entity, Business rule
บทที่ 2–3
ER DiagramEntity, Attribute, Relationship, Cardinality
บทที่ 4
ER → ตารางMapping 7 ขั้น, PK/FK
บทที่ 5
NormalizeFD, 1NF→BCNF, Lossless join
บทที่ 6
Relational Algebraσ π ⋈ ρ ∪ − γ
Lab 11–12
SQL จริงphpMyAdmin, DDL, INSERT/SELECT/UPDATE/DELETE

กดกล่องด้านบน หรือเลือกบทจากแถบเมนู เพื่อเปิดอ่านทีละบท

Requirements
Conceptual design
Logical design
Logical design
Query theory
Physical / ใช้งาน
สีหัวข้อ:นิยาม/แนวคิดDBMSประโยชน์overhead/ข้อเสียคน/ผู้ใช้โครงสร้างภาษา/คำสั่งขั้นตอน/วิธีทำตัวอย่าง
1
Introduction to Database

ฐานข้อมูลคืออะไร ทำไมต้องใช้ DBMS

01 ch01 · 42 หน้า
Database

ชุดข้อมูลที่เกี่ยวข้องกัน

Data

ข้อเท็จจริงที่บันทึกได้และมีความหมายโดยนัย

Mini-world

ส่วนของโลกจริงที่เราเก็บลงฐานข้อมูล เช่น เกรดและ transcript ของนักศึกษา

DBMS

ซอฟต์แวร์ที่ช่วย สร้าง และ บำรุงรักษา ฐานข้อมูล

Database System

DBMS + Database (+ Applications)

Database System Environment

Users / Programmers
↓
Application Programs / Queries
↓
DBMS Software
Software to Process Queries/Programs
↓
Software to Access Stored Data
↙ ↘
Stored DB Definition
(Meta-Data / catalog)
Stored Database
(ข้อมูลจริง)

ผู้ใช้ไม่แตะข้อมูลตรง ๆ ทุกอย่างวิ่งผ่าน DBMS

4 ลักษณะเด่นของ Database Technology จุดสอบ

  1. Self-describing catalog เก็บ meta-data (คำอธิบายฐานข้อมูล) ทำให้ DBMS ใช้กับหลายฐานข้อมูลได้
  2. Program-data independence แก้โครงสร้างการเก็บได้โดยไม่ต้องแก้โปรแกรม
  3. Data abstraction ใช้ data model ซ่อนรายละเอียดการเก็บ ให้ผู้ใช้เห็นภาพเชิงแนวคิด
  4. Multiple views ผู้ใช้แต่ละกลุ่มเห็นมุมมองต่างกัน เช่น Transcript view กับ Prerequisite view ที่ได้จากตารางชุดเดียวกัน

ประโยชน์เพิ่มเติม 12 ข้อ

ควบคุมความซ้ำซ้อนแชร์ข้อมูลหลายผู้ใช้กันการเข้าถึงโดยไม่ได้รับอนุญาตหลาย interfaceแสดงความสัมพันธ์ซับซ้อนบังคับ integrity constraintsbackup / recoveryบังคับมาตรฐานยืดหยุ่นต่อการเปลี่ยนโครงสร้างลดเวลาพัฒนา appข้อมูลเป็นปัจจุบันประหยัดเมื่อขยายขนาด

Redundancy แบบควบคุม vs ไม่ควบคุม

GRADE_REPORT ที่ใส่ StudentName ซ้ำไว้ (ข้อมูลจริง: เลข 17 = Smith)

(a) Controlled

NoNameSec
17Smith112
8Brown85
ซ้ำโดยตั้งใจ แต่ค่าตรงกับ STUDENT

(b) Uncontrolled

NoNameSec
17Brown112
8Brown85
ขัดแย้งกับ STUDENT เกิด inconsistency

Actors on the scene

  • DBA ดูแลระบบ ติดตั้ง ปรับแต่งประสิทธิภาพ backup ความปลอดภัย
  • Database designer วิเคราะห์ความต้องการข้อมูล ออกแบบตาราง ความสัมพันธ์ และกฎ
  • End users แบ่งเป็น Casual, Naïve/parametric และ Sophisticated
  • System analysts & application programmers

เมื่อไหร่ ไม่ ควรใช้ DBMS

  • ต้นทุนเริ่มต้นสูง และมี overhead จาก security, concurrency, recovery, integrity
  • ระบบเรียบง่าย นิยามชัด และไม่น่าจะเปลี่ยน
  • มีข้อกำหนด real-time เข้มงวดจน overhead ของ DBMS รับไม่ได้
  • ไม่มีผู้ใช้หลายคนเข้าถึงพร้อมกัน
  • DBMS ไม่พอ เมื่อข้อมูลซับซ้อนเกินกว่าที่ model รองรับ หรือต้องการ operation พิเศษ

Data Models

Data model คือชุดแนวคิดที่ใช้อธิบาย โครงสร้าง และ constraints ของฐานข้อมูล ส่วน operations คือการ retrieve และ update

ประเภทระดับความหมาย
Conceptualสูง (semantic)ใกล้กับที่ผู้ใช้มองเห็น เรียกอีกชื่อว่า entity-based หรือ object-based
Practical (Implementation)กลางแบบ record-oriented อยู่ระหว่างสองระดับ
Physicalต่ำ (internal)อธิบายวิธีเก็บในคอมพิวเตอร์
196019701980199020002010 Hierarchical Network Relational Object-Oriented Object-Relational Semi-Structured XML Codd 1970
Modelจุดจำ
RelationalE.F. Codd 1970, ขายเชิงพาณิชย์ครั้งแรก 1981–82 (Oracle, Sybase, Informix, Ingres)
Networkimplement เป็นตัวแรก โดย Honeywell IDS ปี 1964–65 ได้รับการผลักดันจาก CODASYL (IDMS, IMAGE)
HierarchicalIBM + North American Rockwell ราวปี 1965 กลายเป็นตระกูล IMS
Object-Orientedมี class, method และ IS_A (inheritance) เช่น GEMSTONE, O2, ORION
Object-Relationalตารางเก็บ object ได้ เช่น ILLUSTRA
Semi-structuredentity กลุ่มเดียวกันอาจมี attribute ไม่เท่ากัน ไม่ต้องมีครบ และ type ต่างกันได้ เช่น XML

Hierarchical = ต้นไม้

Pavement Improvement
├ Reconstruction
├ Maintenance
│  ├ Routine
│  ├ Corrective
│  └ Preventive
└ Rehabilitation
ลูกแต่ละตัวมี parent ได้ ตัวเดียว

Network = กราฟ

Joint Seal ─┐
            ├→ Asphalt
Patching ───┘   Sealant
node มี parent ได้ หลายตัว จึงทำ M:N ได้
✓ ประโยชน์ของ DBMS
ข้อสอบ "ข้อใดเป็นประโยชน์"
ควบคุมความซ้ำซ้อน · แชร์ข้อมูล · กันสิทธิ์ · หลาย interface · ความสัมพันธ์ซับซ้อน · integrity · backup/recovery · มาตรฐาน · ยืดหยุ่น · พัฒนาเร็ว · ข้อมูลปัจจุบัน · ประหยัดเมื่อใหญ่
✗ Overhead / ข้อเสียของ DBMS
มักเป็นตัวลวงในข้อ "ข้อใดไม่ใช่ประโยชน์"
ลงทุนเริ่มต้นสูง · อาจต้องซื้อฮาร์ดแวร์เพิ่ม · overhead จาก security, concurrency control, recovery, integrity · ช้าเกินไปสำหรับ real-time เข้มงวด
แบบฝึกท้ายบท: (1) Database ต่างจาก DBMS อย่างไร (2) ระบุ mini-world ของโรงพยาบาล ร้านอาหาร และ Delivery (ในสไลด์มีโจทย์ สาขา CS, ร้านกาแฟ และโรงภาพยนตร์ด้วย)
2
Database Schemas and Model

Schema, 3 ระดับ, ภาษา และขั้นการออกแบบ

04 ch02 · 61 หน้า

Schema vs Instance จุดสอบ

SchemaInstance (State)
คือโครงสร้างเชิงตรรกะ + constraintsข้อมูลจริง ณ เวลาหนึ่ง
เปรียบ"ชนิดของตัวแปร""ค่าของตัวแปร"
เปลี่ยนไม่บ่อยบ่อย

Schema diagram แสดงแค่ชื่อตารางกับชื่อคอลัมน์ ในตารางจริง ชื่อตาราง = Entity, หัวคอลัมน์ = Attribute, แถว = Tuple (instance)

Three-Schema Architecture จุดสอบ

End users
↕
External level
External views หลายมุมมอง
↕ external / conceptual mapping
Conceptual level
โครงสร้าง + constraints ทั้งหมด
↕ conceptual / internal mapping
Internal level
physical storage, access paths
↕
Stored database

มีขึ้นเพื่อรองรับ program-data independence และ multiple views

โปรแกรมอ้างถึง External schema แล้ว DBMS map ลงไปถึง Internal เพื่อ execute

Data Independence

Logical เปลี่ยน Conceptual schema (เพิ่ม/ลบตาราง คอลัมน์ ความสัมพันธ์) โดยที่ External view และโปรแกรมไม่ต้องแก้

Physical เปลี่ยน Internal schema หรือฮาร์ดแวร์ โดยที่ Conceptual และ External ไม่กระทบ

เปลี่ยนแค่ mapping ระหว่างชั้น ส่วนชั้นบนไม่ต้องแก้

DBMS Languages

ภาษาใช้ทำอะไร
DDLDBA และ designer ใช้นิยาม conceptual schema ผ่าน DDL compiler แล้วผลไปเก็บใน Data Dictionary
SDLStorage Definition กำหนด internal schema
VDLView Definition กำหนด external schema
DMLretrieve และ update แบ่งเป็น Procedural (บอกว่าเอาอะไรและได้มาอย่างไร) กับ Declarative (บอกแค่ว่าเอาอะไร) ฝังใน host language อย่าง C หรือ COBOL ได้ หรือใช้เดี่ยวเป็น query language

Data Dictionary เก็บ metadata ได้แก่ schema, storage definition, integrity constraints (domain, referential integrity, assertions) และ authorization

ตัวอย่าง Data Dictionary

Data ItemTypeFormatBytesExample
Customer IDStringXNNNNNN7M123456
First NameString–25สมชาย
Date of BirthDateDD/MM/YYYY824/05/1998
Platinum MemberBooleanX11
SpendingFloating$XX.XX4145,000

Utilities และการจำแนก DBMS

Utilities ได้แก่ loading, backup, reorganize, report generation, performance monitoring, sorting และ compression
การจำแนก DBMS: ตาม model (Traditional = Relational/Network/Hierarchical, Emerging = OO/OR), single-user หรือ multi-user, centralized หรือ distributed

Main Phases of Database Design จุดสอบ

Mini-world→Requirements collection & analysis→ 1 Conceptual design
ER Diagram
→ 2 Logical design
แปลง ER เป็นตาราง
→ 3 Physical design
การเก็บระดับฮาร์ดแวร์

ขาข้างหนึ่งทำ Functional requirements ไปเป็น Transaction spec แล้วต่อเป็น Application program design ขั้น Conceptual ยัง DBMS-independent ส่วนตั้งแต่ Logical ลงไปเป็น DBMS-specific

3
ER Model (บทที่ 2 ส่วนหลัง + บทที่ 3)

เขียน ER Diagram ให้ถูกสัญลักษณ์

04 ch02 p.24–60 · 05 ch03 · 47 หน้า

สัญลักษณ์ ER (Chen notation) จุดสอบ

EEntity (strong)
Weak entity
Relationship
Identifying rel. (ของ weak)
idKey attribute (ขีดเส้นใต้)
attrSimple attribute
Multivalued {phone}
ageDerived
Total participation
Partial participation
namePartial key (ของ weak)
Composite = วงรีแตกกิ่งต่อ

ประเภท Attribute

ประเภทความหมายตัวอย่าง
Keyค่าไม่ซ้ำในแต่ละ entitySSN, Roll_No
Simpleค่าเดียวแบบ atomicSex
Compositeแตกย่อยได้ และซ้อนเป็นลำดับชั้นได้Address → Street, City, State, Zip
Multivaluedมีได้หลายค่า เขียนเป็น { }{Color}, {Phone}
Derivedคำนวณได้จาก attribute อื่นAge จาก BirthDate

Key อาจเป็น composite เช่น VehicleTag = (Number, State) และ entity หนึ่งมีได้หลาย key เช่น CAR มีทั้ง VIN และ VehicleTag ส่วน {PreviousDegrees(College, Year, Degree)} คือ composite ที่เป็น multivalued ด้วย
Entity type = กลุ่ม entity ที่มี attribute ชุดเดียวกัน ส่วน Entity set = entity ทั้งหมดที่มีอยู่จริง ณ ตอนนั้น

Degree ของ Relationship

Degreeจำนวน entityตัวอย่าง
Unary / Recursive1Person — Married to, EMPLOYEE — Supervision
Binary2Student — Enrolled in — Course
Ternary3STUDENT, COURSE, INSTRUCTOR
N-arynDOCTOR, PATIENT, PRESCRIPTION, HOSPITAL

Roles คือป้ายบนเส้นที่บอกบทบาท เช่น supervisor/supervisee หรือ manager/worker จะใส่หรือไม่ใส่ก็ได้ แต่จำเป็นมากใน recursive
Relationship มี attribute ได้ เช่น depositor(access_date), Works_on(Hours), ร้านค้า–ใช้–บัตรเครดิต(จำนวนเงิน, วันที่)

Cardinality ratio ดูจาก mapping จริง จุดสอบ

Cardinality = จำนวน สูงสุด ที่ entity หนึ่งเข้าร่วม relationship ได้ ส่วน Participation = จำนวน ต่ำสุด ถ้า "ทุกตัวต้องมี" เป็น total (เส้นคู่ หรือเรียกว่า existence dependency) ถ้า "บางตัว" เป็น partial

Notation อื่นอ่านว่า
ลูกศร → ชี้ไปฝั่ง "one"customer ← borrower — loan หมายถึงลูกค้า 1 คนมีหลาย loan
min..max บนเส้นcustomer 0..* borrower 1..1 loan หมายถึงลูกค้ากู้ได้ 0 ถึงหลาย loan และ loan แต่ละอันมีลูกค้า 1 คนพอดี (loan เป็น total)

Weak Entity

  • ไม่มี key เป็นของตัวเอง
  • ระบุตัวตนด้วย partial key + PK ของ owner
  • เชื่อมกับ owner ผ่าน identifying relationship (double diamond) แบบ 1:N และฝั่ง weak เป็น total
  • เช่น DEPENDENT ของ EMPLOYEE, BANK-BRANCH ของ BANK
  • ใน ER จะไม่เขียน PK ของ owner ลงใน weak entity เพราะมันอยู่ใน relationship อยู่แล้ว

วาด ER 6 ขั้น จุดสอบ

Identify Entities หาคำนามหลัก วาดเป็นสี่เหลี่ยม
Identify Relationships วาดเป็นข้าวหลามตัด ห้ามเชื่อม relationship เข้าหากันตรง ๆ ระบุ cardinality (อ่านแบบ "มากสุด") และ participation (อ่านแบบ "อย่างน้อยทุก/บาง")
Add Attributes วาดเป็นวงรี เชื่อมกับ entity
Define Primary Keys ขีดเส้นใต้
Remove Redundancies ตัดของที่ซ้ำหรือไม่จำเป็น
Review for Clarity ทบทวนว่าแผนภาพอ่านแล้วชัดเจน

ตัวอย่างการอ่านจากสไลด์: "อย่างน้อย ทุก Project ต้องถูกควบคุมได้ มากสุดเพียง 1 Department" ได้ PROJECT เป็น total และ cardinality N:1

COMPANY ER Diagram (ตัวอย่างหลักที่ใช้ทั้งบท 3 และบท 4)

Requirement: แผนกมีผู้จัดการ 1 คน (เก็บ start date) และมีได้หลาย location แผนกควบคุมหลายโปรเจกต์ พนักงานสังกัด 1 แผนกแต่ทำได้หลายโปรเจกต์ (เก็บชั่วโมง) มี supervisor และอาจมี dependents หลายคน

EMPLOYEE DEPARTMENT PROJECT DEPENDENT WORKS_FOR MANAGES WORKS_ON CONTROLS SUPERVISION DEPENDENTS_OF Ssn Bdate Address Salary Sex Name Fname Minit Lname Name Number Locations Number_of_employees Name Number Location Start_date Hours Name Sex Birth_date Relationship N1 11 MN 1N 1N 1N supervisorsupervisee
RelationshipCardinalityParticipationAttribute
WORKS_FOREMPLOYEE N : 1 DEPARTMENTtotal ทั้งสองฝั่ง–
MANAGES1 : 1EMPLOYEE partial, DEPARTMENT totalStart_date
CONTROLSDEPARTMENT 1 : N PROJECTDEPT partial, PROJECT total–
WORKS_ONEMPLOYEE M : N PROJECTtotal ทั้งสองฝั่งHours
SUPERVISIONrecursive 1 : Npartial–
DEPENDENTS_OFidentifying 1 : NDEPENDENT total–
ER อื่น ๆ ในสไลด์: BANK, customer, ตัวอย่างภาษาไทย
BANK database
BRANCHES (identifying)BANK 1 : N BANK-BRANCH (weak, partial key BranchNo)total
ACCTS / LOANSBANK-BRANCH 1 : N ACCOUNT / LOANACCOUNT, LOAN total
A-C / L-CACCOUNT, LOAN M : N CUSTOMERACCOUNT, LOAN total
ตัวอย่างไทย (มหาวิทยาลัย)
ทำงานพนักงาน N : 1 คณะพนักงาน total
เป็นคณบดีพนักงาน 1 : 1 คณะคณะ total
เป็นนักศึกษาคณะ 1 : N นักศึกษานักศึกษา total
customer: customer_id, name (first, middle_initial, last), address (street (number, name, apt), city, state, zip), {phone_number}, date_of_birth, age (derived)
แบบฝึกเขียน ER: ระบบจองห้องประชุม และแพลตฟอร์มดูแลผู้สูงอายุ

จองห้องประชุมออนไลน์

  • ผู้ใช้ (รหัส, ชื่อ, อีเมล, โทร, ตำแหน่ง) ผู้ใช้ N : 1 หน่วยงาน
  • ห้องประชุม (รหัส, ชื่อ, อาคาร, ชั้น, ความจุ, อุปกรณ์, สถานะ)
  • การจอง (วันที่, เริ่ม, สิ้นสุด, หัวข้อ, จำนวนคน, สถานะ) การจอง N : 1 ห้อง และต้องบันทึกผู้จอง
  • ผู้ดูแลระบบ อนุมัติหรือปฏิเสธการจอง

ดูแลผู้สูงอายุอัจฉริยะ

  • ผู้สูงอายุ M : N ผู้ดูแล (มี attribute ความสัมพันธ์ เช่น บุตร หลาน)
  • การตรวจสุขภาพ บันทึกโดยเจ้าหน้าที่หรืออาสาสมัคร
  • ผู้สูงอายุ M : N กิจกรรม (มีสถานะการเข้าร่วม)
  • การนัดหมาย กับบุคลากรการแพทย์
  • ผู้สูงอายุ 1 : N อุปกรณ์ IoT, อุปกรณ์ 1 : N ข้อมูลที่วัดได้, ข้อมูลผิดปกติทำให้เกิดการแจ้งเตือน
4
ER-to-Relational Mapping

แปลง ER เป็นตาราง 7 ขั้น

06 ch04 · 24 หน้า
สไลด์ใช้ลำดับขั้นสองแบบ หน้าสรุปให้ 3 = 1:N และ 5 = 1:1 แต่หน้ารายละเอียดให้ 3 = 1:1, 4 = 1:N, 5 = M:N ด้านล่างใช้แบบหน้ารายละเอียด ถ้าข้อสอบถามเลขขั้นให้ดูตามที่อาจารย์ใช้
1

Strong entity

สร้างตารางที่มี simple attribute ทั้งหมด ถ้าเป็น composite ให้เก็บเฉพาะส่วนย่อย ไม่เอา multivalued และ derived

EMPLOYEE(Ssn, Fname, Minit, Lname, Address, Bdate, Salary, Sex)
PROJECT(PName, PNumber, PLocation)
2

Weak entity

PK = PK ของ owner + partial key และ PK ของ owner เป็น FK ไปด้วย

DEPENDENT(Ssn, Dep_Name, Dep_sex, Birth_date, Relationship)
3

Binary 1:1

เลือกตาราง S (ควรเป็นฝั่งที่ total) แล้วใส่ PK ของอีกฝั่งเป็น FK ใน S ย้าย attribute ของ relationship มาด้วย ถ้า total ทั้งคู่จะรวมเป็นตารางเดียวก็ได้

DEPARTMENT(DName, DNumber, Mssn, Start_Date)
4

Binary 1:N

เอา PK ฝั่ง "1" ไปใส่ในตารางฝั่ง "N" เป็น FK ใช้กับ recursive ได้ด้วย

EMPLOYEE(…, Dno, superSsn)
PROJECT(…, Dno)
5

Binary M:N

สร้าง ตารางใหม่ โดย PK = PK ของทั้งสองฝั่งรวมกัน (และแต่ละตัวเป็น FK) แล้วเก็บ attribute ของ relationship ที่นี่

WORKS_ON(Ssn, Pno, Hours)
6

Multivalued attribute

สร้างตารางใหม่เก็บค่านั้นกับ PK ของเจ้าของ ให้ PK = ทั้งสองคอลัมน์

DEPT_LOCATION(DNumber, DLocation)
7

N-ary (n > 2)

สร้างตารางใหม่ใส่ PK ของทุก entity ที่เข้าร่วมเป็น FK ตัวอย่างในสไลด์คือ Managed ที่เชื่อม Store, Inventory, Market, Sales

Manages(OrderID, ProductID, StoreName)

ผลลัพธ์สุดท้ายของ COMPANY จุดสอบ

RelationAttributesFK อ้างถึงมาจากขั้น
EMPLOYEESsn, Fname, Minit, Lname, Address, Bdate, Salary, Sex, Dno, superSsnDno→DEPARTMENT, superSsn→EMPLOYEE1, 4
DEPARTMENTDName, DNumber, Mssn, Start_DateMssn→EMPLOYEE1, 3
DEPT_LOCATIONDNumber, DLocationDNumber→DEPARTMENT6
PROJECTPName, PNumber, Plocation, DnoDno→DEPARTMENT1, 4
WORKS_ONSsn, Pno, HoursSsn→EMPLOYEE, Pno→PROJECT5
DEPENDENTSsn, Dep_Name, Dep_sex, Birth_date, RelationshipSsn→EMPLOYEE2

Number_of_employees เป็น derived จึงไม่มีในตารางใดเลย เพราะคำนวณด้วย COUNT ได้

แบบฝึกท้ายบท: ร้านค้าออนไลน์ (CustomerInfo / OrderCartInfo / InventoryItem / ItemType / Category) พร้อมแนวคำตอบ

ER: CustomerInfo 1:N OrderCartInfo (has), OrderCartInfo M:N InventoryItem (lineItems: orderPrice, qtyOrdered), ItemType 1:N InventoryItem (hasInStock, identifying และ InventoryItem เป็น weak), Category 1:N ItemType (belongsTo) ส่วน totalPrice เป็น derived และ date เป็น composite (oYear, oMonth, oDay)

CustomerInfo(loginName, password, firstName, lastName, cStreet, cCity, cState, cZip, phone, email)
Category(categoryId, description)
ItemType(itemNum, name, picture, price, categoryId)
OrderCartInfo(orderCartId, type, oYear, oMonth, oDay, loginName)
InventoryItem(itemNum, code, qtyInStock, itemColor, itemSize)
LineItems(orderCartId, itemNum, code, orderPrice, qtyOrdered)

แนวคำตอบนี้คิดเพิ่มเอง ไม่ได้มาจากสไลด์ และในรูปไม่ชัดว่า loginName เป็น key จริงหรือไม่

5
Relational Database Design

FD, Normalization และ Lossless Join

07 บทที่ 5 · 68 หน้า

Guidelines 4 ข้อของตารางที่ดี

  1. ความหมายชัด หนึ่งแถวแทน 1 entity หรือ 1 เหตุการณ์ ไม่เอาหลาย entity มาปนในตารางเดียว และอ้างถึงกันด้วย FK เท่านั้น
  2. ไม่มี anomaly ทั้ง insert, delete และ update
  3. NULL น้อยที่สุด NULL เกิดได้ 3 แบบคือ not applicable, unknown และ unavailable ถ้าคอลัมน์ไหน NULL เยอะให้แยกออกเป็นตารางใหม่
  4. ไม่มี spurious tuples แยกตารางแล้วต้อง join กลับได้ข้อมูลเดิม (lossless) ห้ามเสียคุณสมบัตินี้ ส่วน dependency preservation ยอมเสียได้บางกรณี

ตัวอย่างตารางที่ไม่ดี: ใส่ Phone No หลายเบอร์ในช่องเดียว และเอาชื่อแผนกมาปนกับข้อมูลพนักงาน

Anomalies จุดสอบ

EMP_PROJ(Ssn, Pnumber, Hours, Ename, Pname, Plocation)

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

Anomaly ไม่ได้เกิดจาก SQL แต่เกิดจากการออกแบบตาราง

SsnPnoEnamePnamePloc
1234567891SmithProductXBellaire
1234567892SmithProductYSugarland
4534534531EnglishProductXBellaire
ช่องที่ไฮไลต์คือข้อมูลที่ซ้ำ

Functional Dependency

X → Y อ่านว่า "X กำหนด Y" ถ้า t1[X] = t2[X] แล้วต้องได้ t1[Y] = t2[Y] เสมอ FD มาจาก business rule ของโลกจริง ไม่ใช่ดูจากข้อมูลไม่กี่แถว และถ้า K เป็น key แล้ว K → ทุก attribute

Armstrong's Axioms

ReflexivityY ⊆ X ⇒ X→Y
AugmentationX→Y ⇒ XZ→YZ
TransitivityX→Y, Y→Z ⇒ X→Z

กฎเสริม

DecompositionX→YZ ⇒ X→Y, X→Z
UnionX→Y, X→Z ⇒ X→YZ
PseudotransitivityX→Y, WY→Z ⇒ WX→Z

F⁺ = FD ทุกตัวที่อนุมานได้จาก F ส่วน X⁺ = attribute ทุกตัวที่ X กำหนดได้ ถ้า X⁺ ครอบคลุมทุกคอลัมน์ X เป็น superkey ถ้าตัดอะไรออกไม่ได้อีกแล้ว X คือ candidate key
Minimal cover: RHS มีตัวเดียว, ไม่มี FD ซ้ำซ้อน, LHS ไม่มีตัวเกิน

ลองหา Closure แบบฝึก 2

R(A,B,C,D,E), F = {A→B, B→C, AC→D, D→E}

เริ่มที่ A⁺ = {A}
A→B ได้ {A,B}
B→C ได้ {A,B,C}
มี A และ C แล้ว AC→D ได้ {A,B,C,D}
D→E ได้ {A,B,C,D,E} ครบทุกตัว

A เป็น superkey และเป็น candidate key ส่วน AC ก็เป็น superkey แต่ไม่ใช่ candidate key เพราะ C เกินมา

Keys และ Prime attribute

Superkey

ชุดที่มี candidate key อยู่ข้างใน อาจมีตัวเกิน

Candidate key

ชุด เล็กที่สุด ที่ระบุแถวได้ไม่ซ้ำ

Primary key

candidate key ที่เลือกมาเป็นหลัก

Alternate key

candidate key ตัวอื่นที่ไม่ได้ถูกเลือก

Prime attribute

attribute ที่อยู่ใน candidate key ใดก็ได้

Non-prime

attribute ที่ไม่อยู่ใน candidate key ใดเลย

บันได Normal Form จุดสอบ

1NF

ทุกช่องเป็นค่า atomic ไม่มี multivalued, composite หรือ nested

มีหลายค่าในช่องเดียวไหม?
2NF

1NF + ไม่มี partial dependency คือ non-prime ต้องขึ้นกับ key ทั้งชุด

PK เป็น composite ไหม แล้วมีคอลัมน์ที่ขึ้นกับแค่บางส่วนของ PK ไหม?
3NF

2NF + ไม่มี transitive dependency คือ non-prime ห้ามกำหนด non-prime

ทุก X→A มี X เป็น superkey หรือ A เป็น prime
BCNF

ทุก determinant ต้องเป็น superkey (เข้มกว่า 3NF)

LHS ของทุก FD เป็น superkey ไหม?
4NF

ไม่มี MVD (X →→ Y) ที่ X ไม่ใช่ superkey

มีข้อมูลหลายชุดที่อิสระกันแต่เก็บรวมกันไหม?
5NF

Join dependency หรือ PJNF แยกเป็นตั้งแต่ 3 ตารางแล้ว join กลับได้ถูก

เช่น Supplier–Part–Project

งานจริงทำถึง 3NF หรือ BCNF ก็พอ ส่วน Denormalization คือการรวมตารางกลับเพื่อประสิทธิภาพ แลกกับการยอมคุมความซ้ำซ้อนเอง

→ 2NF

EMP_PROJ(SSN, PNumber, EName, Hours, PName, PLocation)

  • SSN → EName (partial)
  • PNumber → PName, PLocation (partial)
  • {SSN, PNumber} → Hours (full)

แยกเป็น

EP1(SSN, EName)
EP2(PNumber, PName, PLocation)
EP3(SSN, PNumber, Hours)

→ 3NF

EMP_DEPT(SSN, EName, BDate, Address, DNumber, DName, Dmgr_ssn)

  • SSN → …, DNumber
  • DNumber → DName, Dmgr_ssn ทำให้เกิด transitive

แยกเป็น

ED1(SSN, EName, BDate, Address, DNumber)
ED2(DNumber, DName, Dmgr_ssn)

→ BCNF

ลงทะเบียน(StudentID, CourseID, Advisor)

  • {StudentID, CourseID} → Advisor
  • Advisor → CourseID แต่ Advisor ไม่ใช่ superkey

แยกเป็น

(Advisor, CourseID)
(StudentID, Advisor)

TEACH(Student, Course, Instructor) ก็เป็นแบบเดียวกัน คือผ่าน 3NF แต่ไม่ผ่าน BCNF

สไลด์ p.42 บอกว่า (ItemID, Zipcode, City) ที่มี Zipcode → City "ผ่าน 3NF แต่ไม่เป็น BCNF" แต่ถ้าดูตามนิยามในสไลด์เอง Zipcode → City เป็น partial dependency ซึ่งไม่ผ่านตั้งแต่ 2NF แล้ว ถ้าข้อนี้ออกสอบควรถามอาจารย์ให้ชัด

ทดสอบ Lossless Join ด้วย Matrix (Chase)

แถว = ตารางย่อย, คอลัมน์ = attribute ถ้าตารางย่อยมี attribute นั้นใส่ a ถ้าไม่มีใส่ b แล้วไล่ใช้ FD ทีละตัว แถวไหนที่ LHS เท่ากันให้ทำ RHS ให้เท่ากัน ถ้าสุดท้ายมีแถวที่เป็น a ครบทุกช่อง แปลว่า Lossless

R1 = EMP(SSN, ENAME), R2 = PROJECT(PNUMBER, PNAME, PLOCATION), R3 = WORKS_ON(SSN, PNUMBER, HOURS)

SSNENAMEPNUMPNAMEPLOCHOURS
R1a1a2b13b14b15b16
R2b21b22a3a4a5b26
R3a1b32→a2a3b34→a4b35→a5a6

SSN→ENAME (R1 กับ R3 มี SSN เท่ากัน) ทำให้ R3.ENAME เป็น a2 ส่วน PNUMBER→PNAME, PLOC (R2 กับ R3) ทำให้ R3 ได้ a4 และ a5 ผลคือ R3 เป็น a ครบทุกช่อง จึง Lossless
ถ้าแยกเป็น EMP_LOCS(ENAME, PLOCATION) กับ EMP_PROJ1(…) matrix จะไม่เปลี่ยนเลย จึงเป็น Lossy และเกิด spurious tuples

ทางลัด: แยกเป็น 2 ตาราง

{R1, R2} เป็น lossless เมื่อ

(R1 ∩ R2) → (R1 − R2)
หรือ
(R1 ∩ R2) → (R2 − R1)

หมายถึงคอลัมน์ที่ใช้ร่วมกันต้องเป็น key ของตารางใดตารางหนึ่ง
แบบฝึก 4: R(A,B,C), F={A→B} แยกเป็น R1(A,B), R2(A,C) จะได้ R1∩R2 = A และ A→B = R1−R2 จึงเป็น Lossless

คุณสมบัติที่ต้องเช็กหลังแยกตาราง

Attribute preservation, Dependency preservation และ Lossless join

Dangling tuple

แถวที่หาคู่ไม่เจอจะหายไปจาก INNER/NATURAL JOIN ถ้าอยากเก็บไว้ต้องใช้ OUTER JOIN (LEFT/RIGHT/FULL) ซึ่งช่องที่ไม่มีคู่จะเป็น NULL

4NF: Multivalued Dependency

ENamePNameDName
SmithXAnna
SmithXJohn
SmithYAnna
SmithYJohn

โปรเจกต์กับผู้ติดตามไม่เกี่ยวกัน แต่ต้องเก็บทุกคู่ผสม EName →→ PName และ EName →→ DName

แก้โดยแยกเป็น EMP_PROJECTS(EName, PName) และ EMP_DEPENDENTS(EName, DName)

MVD จะเป็น trivial เมื่อ Y ⊆ X หรือ X ∪ Y = R และ FD ถือเป็นกรณีพิเศษของ MVD

แบบฝึกในชั้น 1 และ 3 พร้อมแนวคำตอบ

แบบฝึก 1: ORDER_ALL(OrderID, OrderDate, CustomerID, CustomerName, ProductID, ProductName, Qty, UnitPrice) ให้หาข้อมูลที่ซ้ำและยกตัวอย่าง anomaly ทั้ง 3 แบบ

แบบฝึก 3: SALES(OrderID, OrderDate, CustomerID, CustomerName, ProductID, ProductName, UnitPrice, Qty) มี Key = {OrderID, ProductID}

FD: OrderID → OrderDate, CustomerID · CustomerID → CustomerName · ProductID → ProductName, UnitPrice · {OrderID, ProductID} → Qty
2NF: ORDER(OrderID, OrderDate, CustomerID, CustomerName) · PRODUCT(ProductID, ProductName, UnitPrice) · ORDER_LINE(OrderID, ProductID, Qty)
3NF: ORDER(OrderID, OrderDate, CustomerID) + CUSTOMER(CustomerID, CustomerName)

แนวคำตอบนี้คิดเพิ่มเอง ไม่ได้มาจากสไลด์

6
Relational Algebra

Relation เข้า → ตัวดำเนินการ → Relation ออก

08 บทที่ 6 · 51 หน้า

พื้นฐาน

  • Closure property ผลลัพธ์ของทุก operator ยังเป็น relation จึงซ้อนกันได้
  • Degree = จำนวน attribute, Cardinality = จำนวน tuple
  • Relation ไม่มีลำดับแถว ไม่มีลำดับคอลัมน์ และไม่มี tuple ซ้ำ
  • แต่ละ tuple คือประโยคที่เป็นจริงของ predicate (Intension = รูปแบบของประโยค, Extension = ชุดประโยคที่จริง ณ ตอนนั้น)
  • Closed World Assumption ถ้า tuple ไม่อยู่ในตาราง แปลว่าฐานข้อมูลไม่รับรองว่าจริง

ข้อมูลตัวอย่างที่ใช้ทั้งบท

IS_CALLED
S1Anne
S2Boris
S3Cindy
S4Devinder
S5Boris
IS_ENROLLED_ON
S1C1
S1C2
S2C1
S3C3
S4C1
EXAM_MARK
S1C185
S1C249
S2C149
S3C366
S4C193

COURSE มี C1 Database, C2 HCI, C3 Op Systems และ C4 Programming

σ

Selection

เลือก แถว ตามเงื่อนไข (WHERE)

σ Name='Boris' (IS_CALLED)
S2Boris
S5Boris
π

Projection

เลือก คอลัมน์ และตัดแถวที่ซ้ำ (SELECT DISTINCT)

π StudentId (IS_ENROLLED_ON)

ได้ S1, S2, S3, S4 คือ 4 แถวจากเดิม 5 เพราะ S1 ที่ซ้ำเหลือตัวเดียว

⋈

Natural JOIN

จับคู่แถวด้วย attribute ที่ชื่อเหมือนกัน

IS_CALLED ⋈ IS_ENROLLED_ON
S1AnneC1
S1AnneC2
S2BorisC1
S3CindyC3
S4DevinderC1

S5 หายไปเพราะไม่มีคู่ (dangling) ถ้าชื่อคอลัมน์ไม่ตรงกันใช้ Theta join ⋈cond

ρ

RENAME

เปลี่ยนชื่อ attribute ซึ่งเปลี่ยนแค่ heading ค่าในตารางเหมือนเดิม (SQL ใช้ AS)

ρ Sid←StudentId (IS_CALLED)

ใช้ทำ Self join เช่นหาคนที่ชื่อเหมือนกัน (S2 กับ S5 ชื่อ Boris) โดยใส่ WHERE Sid1 < Sid2 กันการจับคู่กับตัวเอง

+

EXTEND

เพิ่มคอลัมน์ที่คำนวณได้ จำนวนแถวเท่าเดิม

EXTEND IS_CALLED : {Initial := SUBSTRING(Name,0,1)}

ได้ S1 Anne A, S2 Boris B, …

∪

UNION

รวมแถวในแนวตั้งและตัดตัวซ้ำ โดยต้อง union-compatible คือจำนวน attribute เท่ากัน ชื่อตรงกัน และ domain ตรงกัน

{S1,S2,S4} ∪ {S1,S3,S4} = {S1,S2,S3,S4}

มีคุณสมบัติ commutative, associative และ idempotent (R ∪ R = R) ใน SQL ถ้าใช้ UNION ALL จะเก็บแถวซ้ำไว้

−

Difference / NOT MATCHING

หาแถวที่ไม่มีคู่ ตรงกับ SQL NOT EXISTS หรือ EXCEPT

IS_CALLED NOT MATCHING IS_ENROLLED_ON

ได้ (S5, Boris) คือคนที่ไม่ได้ลงทะเบียน

γ

SUMMARIZE / Aggregate

COUNT=5, SUM=342, AVG=68.4, MAX=93, MIN=49 ส่วน aggregate คืนค่าเดียว ไม่ได้คืน relation

SUMMARIZE EXAM_MARK BY {CourseId} : {TopScore := MAX(Mark)}
C193
C249
C366

SUMMARIZE BY vs PER จุดสอบ

BY

แสดงเฉพาะกลุ่มที่มีอยู่ในข้อมูล

PER COURSE{CourseId}

ใช้ relation อื่นเป็นตัวกำหนดกลุ่ม จึงแสดงกลุ่มที่ว่างด้วย

C13
C21
C31
C40

คุณสมบัติของ JOIN

r ⋈ r = r ถ้า attribute เหมือนกันทั้งหมด JOIN จะกลายเป็น ∩ ถ้าไม่มี attribute ร่วมเลยจะกลายเป็น × (TIMES) และ JOIN เป็น commutative กับ associative ทำให้ DBMS สลับลำดับเพื่อ optimize ได้

RA ↔ Tutorial D ↔ SQL

ทำอะไรRATutorial DSQL
เลือกแถวσWHEREWHERE
เลือกคอลัมน์π{A, B}SELECT DISTINCT
เชื่อม⋈JOINJOIN
เปลี่ยนชื่อρRENAMEAS
รวม∪UNIONUNION
ผลต่าง−NOT MATCHING / MINUSNOT EXISTS / EXCEPT
จัดกลุ่มγSUMMARIZEGROUP BY

SQL ยอมให้มีแถวซ้ำได้ แต่ relation ในทางทฤษฎีเป็นเซต จึงไม่มีแถวซ้ำ

สูตรแก้โจทย์ RA: เลือกแถว → เชื่อม → คำนวณ → เลือกคอลัมน์

โจทย์: หารหัส ชื่อ และคะแนนของคนที่สอบ C1 ได้ตั้งแต่ 50 ขึ้นไป

π StudentId, Name, Mark ( IS_CALLED ⋈ σ CourseId='C1' ∧ Mark≥50 (EXAM_MARK) )
σ ได้ (S1,C1,85), (S4,C1,93)→⋈ IS_CALLED ได้ชื่อ Anne, Devinder→π ได้ S1 Anne 85 · S4 Devinder 93

ขั้นตอนตามสไลด์: (1) หาตารางที่มีคอลัมน์ที่ต้องใช้ (2) σ (3) ⋈ (4) EXTEND หรือ aggregate (5) π (6) ตรวจ heading ก่อนทำ ∪ หรือ − แล้วเขียนจากวงเล็บในสุดออกมา

Constraint เขียนแบบ RA ได้ เช่น IS_EMPTY(EXAM_MARK WHERE Mark < 0 OR Mark > 100) ส่วน KEY ใช้กันค่าซ้ำ และ FOREIGN KEY ใช้รักษาการอ้างอิงให้ถูกต้อง

แบบฝึก UNION และโจทย์ท้ายบท
  1. {S1,S2,S4} ∪ {S2,S3,S4} ได้ {S1,S2,S3,S4} cardinality = 4
  2. R(StudentId) กับ S(Sid) ยัง UNION ไม่ได้ ต้องใช้ ρ StudentId←Sid ก่อน ถ้าจำนวนคอลัมน์ไม่เท่ากันให้ π ฝั่งที่เกินออก
  3. "ชื่อ Boris หรือ ลง C1": π StudentId(σ Name='Boris'(IS_CALLED)) ∪ π StudentId(σ CourseId='C1'(IS_ENROLLED_ON)) ได้ {S1,S2,S4,S5}
  4. π StudentId(IS_CALLED) ∪ π CourseId(IS_ENROLLED_ON) ผิด เพราะความหมายของคอลัมน์ต่างกัน ห้าม RENAME CourseId เป็น StudentId
  5. โจทย์ท้ายบท: คนที่ลง C1 แต่ไม่ได้สอบ C1 (ใช้ −), ชื่อคนที่ได้คะแนนสูงสุดของแต่ละวิชา, วิชาที่ไม่มีคนสอบ (ใช้ SUMMARIZE PER), ทำไม π ทำให้ cardinality ลดลง (เพราะตัดแถวซ้ำ) และแปลง RA เป็น SQL
Lab
phpMyAdmin + SQL เบื้องต้น

ลงมือสร้างและจัดการข้อมูล

11 Lab phpMyAdmin · 12 Lab SQL

เปิด phpMyAdmin ผ่าน XAMPP (macOS)

เปิด manager-osx→แท็บ Manage Servers→Start All แล้วรอไฟเขียว (Running)→Welcome → Go to Application→เมนู phpMyAdmin→New → ตั้งชื่อ DB + Collation utf8mb4_general_ci → Create→ตั้งชื่อตาราง + จำนวนคอลัมน์ → Create→กรอกฟอร์ม → Preview SQL → Save

phpMyAdmin เป็นแค่ หน้าจอ (interface) สำหรับ MySQL/MariaDB ไม่ใช่ตัวฐานข้อมูล เข้าได้ที่ http://localhost/phpmyadmin

ช่องในฟอร์มสร้างคอลัมน์

ช่องหมายถึง
Type / LengthINT, VARCHAR(100), DATE, DECIMAL(10,2) (รวม 10 หลัก ทศนิยม 2)
DefaultNone, As defined, NULL, CURRENT_TIMESTAMP
Collationกติกาเทียบและเรียงข้อความ ใช้กับ VARCHAR/TEXT เท่านั้น ไม่มีผลกับ INT
AttributesUNSIGNED = ห้ามค่าติดลบ
Nullติ๊ก = ยอมให้ว่างได้ ไม่ติ๊ก = NOT NULL (NULL ≠ 0 ≠ '')
IndexPRIMARY, UNIQUE, INDEX, FULLTEXT
A_IAuto Increment รันเลขให้เอง เหมาะกับ PK
Storage EngineInnoDB ต้องใช้ตัวนี้ถึงจะทำ Foreign Key ได้

หน้า Structure ใช้ Change แก้คอลัมน์, Drop ลบ และ Add column after … เพิ่มคอลัมน์ต่อท้ายคอลัมน์ที่เลือก

DDL ที่ใช้ในแท็บ SQL

CREATE DATABASE IF NOT EXISTS BonusSuki
  CHARACTER SET utf8mb4
  COLLATE utf8mb4_general_ci;

CREATE TABLE Member_test(
  member_id INT NOT NULL AUTO_INCREMENT,
  full_name VARCHAR(100) NOT NULL,
  phone VARCHAR(20) NOT NULL,
  joined_at DATE NOT NULL,
  PRIMARY KEY (member_id)
) ENGINE=InnoDB;

ALTER TABLE member_test ADD COLUMN email VARCHAR(150) NULL;
ALTER TABLE member_test MODIFY COLUMN phone VARCHAR(25) NOT NULL;
ALTER TABLE member_test RENAME COLUMN full_name TO member_name;
ALTER TABLE member_test DROP COLUMN email;
DROP DATABASE IF EXISTS BonusSuki;

ลำดับ clause ของ SELECT จุดสอบ

SELECT คอลัมน์→FROM ตาราง→JOIN … ON→WHERE กรองแถว→GROUP BY→HAVING กรองกลุ่ม→ORDER BY ASC/DESC→LIMIT

ตาราง Products (ใช้ทุกตัวอย่าง)

IDNamePriceStockCategory
1ปากกา15.00100เครื่องเขียน
2ดินสอ10.0080เครื่องเขียน
3ยางลบ8.0050เครื่องเขียน
4สมุด35.0040เครื่องเขียน
5สินค้าใหม่99.005NULL

PriceUpdates: (1, 19.00), (4, 39.00)

SELECT 12 แบบ เลือกดูทีละแบบได้


          

INSERT 7 แบบ

INSERT INTO Products (ProductName, Price, Stock, Category)
VALUES (N'ปากกา', 15.00, 100, N'เครื่องเขียน');      -- 1 แถว
VALUES (…), (…), (…);                                   -- หลายแถว
(ProductName, Price) VALUES (N'แฟ้ม', 25.00);           -- บางคอลัมน์
VALUES (N'ไม้บรรทัด', 12.00, DEFAULT);                  -- ใช้ค่า default
VALUES (N'สินค้าใหม่', 99.00, 5, NULL);                 -- NULL ไม่ใส่ ''
VALUES (N'ชุดปากกา', 15.00 * 3, 20);                    -- คำนวณ → 45.00
INSERT INTO BudgetProducts (ProductName, Price)
SELECT ProductName, Price FROM Products WHERE Price < 20;

เช็ก 4 ข้อ: (1) ลำดับและจำนวนค่าต้องตรงกับคอลัมน์ (2) type, NOT NULL และ UNIQUE (3) รันซ้ำจะได้แถวซ้ำ (4) SELECT ตรวจหลังเพิ่ม
ถ้าไม่ระบุ Stock จะได้ 0, Category ได้ NULL, CreatedAt ได้เวลาปัจจุบัน และ ID รันเลขเอง

UPDATE / DELETE ⚠

ถ้าลืม WHERE จะโดนทุกแถว ให้ทำตามลำดับนี้เสมอ: SELECT … WHERE x → UPDATE/DELETE … WHERE x → SELECT … WHERE x โดยใช้ WHERE เดียวกันทั้งสามคำสั่ง
UPDATE Products SET Price = 18.00 WHERE ProductID = 1;
SET Stock = Stock - 3 WHERE ProductID = 1 AND Stock >= 3;
SET Price = ROUND(Price * 0.90, 2) WHERE Category='เครื่องเขียน' AND Price >= 10;
SET Price = CASE ProductID WHEN 1 THEN 18 WHEN 2 THEN 12 ELSE Price END
UPDATE Products p JOIN PriceUpdates u ON p.ProductID=u.ProductID
  SET p.Price = u.NewPrice;

DELETE FROM Products WHERE ProductID IN (2, 3);
WHERE Price BETWEEN 8 AND 10;           -- รวมค่าขอบ
WHERE Price <= 15 ORDER BY ProductID LIMIT 1;
DELETE u FROM PriceUpdates u JOIN Products p … WHERE p.Stock <= 40;
DELETE FROM PriceUpdates WHERE NOT EXISTS
  (SELECT 1 FROM Products WHERE Products.ProductID = PriceUpdates.ProductID);

DELETE ลบทั้งแถวแต่ตารางยังอยู่ ส่วน DELETE u ลบเฉพาะตาราง u ถ้าค่าใหม่เท่ากับค่าเดิม จำนวนแถวที่เปลี่ยนจะเป็น 0

แบบฝึก Lab 11 (coffee_shop_lab) และ Lab 12

Lab 11

สร้าง DB coffee_shop_lab ใช้ collation utf8mb4_unicode_ci

  • categories(category_id PK AI, category_name UNIQUE)
  • products(product_id PK, product_name, price ≥ 0, category_id FK, is_available)
  • members(member_id PK, first_name, last_name, phone UNIQUE, registered_at)
  • sales(sale_id PK, member_id FK ที่เป็น NULL ได้, sale_datetime, total_amount)
  • เพิ่ม description แบบ NULL ได้, เปลี่ยนชื่อ phone เป็น phone_number และลบ 1 คอลัมน์ที่ไม่ใช่ PK

Lab 12

  • เพิ่ม กาว 18.00/25 และเพิ่ม กรรไกร 45 กับ เทปใส 20 ในคำสั่งเดียว (Stock ใช้ default)
  • สมุดรหัส 4 เปลี่ยนชื่อเป็น "สมุดเส้นบรรทัด" ราคา 40, ดินสอเพิ่มสต็อก 20 และแก้หมวดที่เป็น NULL เป็น "อื่น ๆ"
  • ราคา ≤ 15 เรียงน้อยไปมาก, นับสินค้าที่สต็อก ≥ 50 และใช้ LEFT JOIN หาสินค้าที่ไม่มีราคาใหม่
  • ลบราคา > 30, ลบรหัส 1 กับ 3 และลบสินค้าสต็อก ≥ 50 แค่ 1 แถวโดยเลือกรหัสมากสุดก่อน
TOR
กรณีศึกษา + ขั้นตอนวิเคราะห์ระบบ

ร้านโบนัสสุกี้: จาก TOR สู่ ER

02/09 TOR · 03 วิเคราะห์ระบบ · 10 ER drawio

คิดแบบ System Analyst

อ่าน TOR→เข้าใจธุรกิจ→เข้าใจคน→เข้าใจกระบวนการ→เข้าใจข้อมูล→ค่อยออกแบบระบบ
Overview ระบบทำเพื่ออะไร ใครเป็นเจ้าของ แก้ปัญหาอะไร และมีเป้าหมายอะไร
Stakeholders ใครใช้ระบบบ้าง
Role แต่ละคนทำอะไร
Process ขีดเส้นใต้ คำกริยา เช่น สมัคร ยืม ชำระเงิน
Data (Entity) ขีดเส้นใต้ คำนาม เช่น สมาชิก สินค้า ใบสั่งซื้อ
Attribute entity นี้ต้องเก็บอะไรบ้าง
Relationship เช่น นักศึกษาลงทะเบียนวิชา เป็น M:N
Business rules เช่น ยืมได้ไม่เกิน 5 เล่ม หรือของหมดห้ามขาย ซึ่งมักถูกมองข้าม
จัดหมวด แยกเป็น คน / งาน / ข้อมูล / กฎ
ค่อยวาด Diagram

ปัญหา 3 ข้อในหน้าร้าน

  1. ทอนเงินผิด ยอด 317.79 รับเงิน 500 ระบบทอน 182.25 ทั้งที่ต้องเป็น 182.21 จึงต้องใช้ Decimal ทศนิยม 2 ตำแหน่ง
  2. ใช้โปรผิดเงื่อนไข ลูกค้ามา 2 คนแต่กดโปร "มา 4 จ่าย 3" ได้ จึงต้องบังคับใส่ headcount แล้ว block โปรที่ไม่เข้าเงื่อนไข
  3. เปิดโต๊ะซ้อน โต๊ะที่กำลังใช้อยู่ต้องถูก hard lock สถานะมี 3 สี: เขียว = ว่าง, แดง = กำลังทาน, เหลือง = รอเช็คบิล

โมดูลใน TOR

โต๊ะ · Billing (ซุปพิเศษ +49/หม้อ, เงินสด และ Dynamic QR มาตรฐาน EMVCo) · Promotion engine (กฎ stacking) · CRM (บังคับแค่ชื่อกับเบอร์ 10 หลักที่ห้ามซ้ำ แต้มคิดหลังหักส่วนลดเมื่อปิดบิล) · Inventory (BOM ตัดสต็อกตามสูตร, COGS แบบ FIFO หรือ Moving Average, ของเสีย, re-order point) · HR/Payroll (Full-time หรือ Part-time, OT 1.5 เท่า และ 2 เท่าในวันหยุด, ต้อง approve ก่อนจ่าย) · Expense · P&L

Revenue − COGS = Gross Profit
Gross Profit − OPEX = Net Profit

NFR: ACID, audit log (void bill, เปิดลิ้นชักโดยไม่มีการขาย), offline + sync, RBAC 3 ระดับ (ผู้จัดการ ห้ามเห็นเงินเดือน คนอื่น), PDPA และ password hashing

ER สุกี้โบนัส (Lab drawio)

EntityAttributes
MemberMember_ID, Name, PhoneNo, Address
BillOrder_ID, Payment amount
ProductTable_ID* , Name, amount, {Product_type}
Dining_TableTable_ID, TableName, Zone, Size
EmployeeEmp_ID, Name, Address, PhoneNo, EmpType
vendorVendor_ID, Name, Address, phoneNo
PromotionPromotionID, Pro_Name, Detail, start, End
Work_Time (weak)Date, Entry_time, End_time, hours (derived)
RelationshipCard.Attribute
Member payment Bill1 : MDate
Member use Dining_TableM : MDataTime, {status_table}
Dining_Table of Bill1 : Mamount_member (headcount), {soup_type}, {package}, Start/End
Bill use ProductM : 1DateTime, unit
Bill use PromotionM : MDateTime
Import (ternary)Employee 1, Product M, vendor Mnumber, DateTime
Employee in Work_Time1 : M (identifying)–

* ในรูปขีดเส้นใต้ PK ของ Product เป็น Table_ID ซึ่งน่าจะตั้งชื่อผิด และควรเป็น Product_ID

✓
ทบทวนก่อนเข้าห้องสอบ

แฟลชการ์ด: แตะเพื่อดูคำตอบ