สอบถามการ Query sqlsrv โดยให้เรียงรายการและแยกข้อมูลตามรายการนั้นๆ
ถึงจะไม่เข้าใจว่าทำแบบนั้นทำไม และทำไมไม่ออกแบบฐานข้อมูลตามหลัก RDBMS
แต่วิธีง่านสุด คือ แยก select แล้วนำมา union ก็ได้แล้ว
Date :
2023-02-16 10:53:28
By :
009
Quote: หลักการออกแบบฐานข้อมูลตาม RDBMS พอสังเขป
1.ปรับข้อมูลให้เป็นมาตรฐาน: เพื่อลดความซ้ำซ้อนและขจัดความไม่สอดคล้องกันของข้อมูล ควรแบ่งตารางขนาดใหญ่ออกเป็นตารางที่เล็กลงและจัดระเบียบข้อมูลเพื่อช่วยหลีกเลี่ยงความผิดพลาดในการอัปเดต ซึ่งการเปลี่ยนแปลงส่วนหนึ่งส่วนใดของฐานข้อมูลจะส่งผลกระทบต่อส่วนอื่นๆ ของแอปโดยตรง
2. ใช้ Data Type ที่เหมาะสมในแต่ละคอลัมน์: เพื่อให้ข้อมูลมีความสมบูรณ์และการจัดเก็บที่มีประสิทธิภาพ ตัวอย่างเช่น numeric, int, float สำหรับตัวเลข datetime, timestamp สำหรับวันที่และเวลา และ (n)varchar, text สำหรับข้อความ
3. สร้างคีย์หลัก(pk) และคีย์รอง(fk): เพื่อบังคับใช้ข้อมูลและอำนวยความสะดวกในการค้นหาที่มีประสิทธิภาพ คีย์หลักจะกำหนดแต่ละแถวในตารางโดยไม่ซ้ำกัน ในขณะที่คีย์รองจะสร้างความสัมพันธ์ระหว่างตาราง
4.จัดทำ column index สำหรับ query ที่ใช้บ่อย: เพื่อเพิ่มประสิทธิภาพการสืบค้น การทำ index ช่วยให้ฐานข้อมูลสามารถค้นหาแถวที่ตรงกับข้อมูลที่ query ได้อย่างรวดเร็ว แทนที่จะสแกนทั้งตาราง
5.ใช้หลักการตั้งชื่อที่เหมาะสม (Name convention): ใช้หลักการตั้งชื่อที่เหมาะสมสำหรับตาราง คอลัมน์ และความสัมพันธ์เพื่อทำให้ฐานข้อมูลง่ายต่อการเข้าใจและดูแลรักษา
...
ตัวอย่าง
แบบเดิม (ตารางเดียว):
bill1, bill2, bill3, box1, box2, box3, weight1, weight2, weight3
ออกแบบใหม่ (4 tables) ด้วยความสัมพันธ์แบบ M:N
Table: bill
- bill_id pk)
- bill_number
Table: box
- box_id (pk)
- box_number
Table: weight
- weight_id (pk)
- weight_number
Table: bill_box_weight
- bill_id (fk to bill)
- box_id (fk to box)
- weight_id (fk to weight)
ตัวอย่าง query จาก DB ที่ออกแบบใหม่
SELECT
b.bill_number,
bo.box_number,
w.weight_number
FROM
bill_box_weight bbw
INNER JOIN bill b ON bbw.bill_id = b.bill_id
INNER JOIN box bo ON bbw.box_id = bo.box_id
INNER JOIN weight w ON bbw.weight_id = w.weight_id
ORDER BY
b.bill_number ASC;
Date :
2023-02-16 22:06:48
By :
009
(ถ้าตกลงกับหัวหน้าได้ ...อ้างอิงตัวอย่างนี้แล้วประยุกต์ให้เข้ากับข้อมูลของตัวเอง)
ขั้นตอนย้ายข้อมูลตามตัวอย่าง
1. สร้าง table ใหม่
Code (SQL)
CREATE TABLE bill (
bill_id INT IDENTITY(1,1) PRIMARY KEY,
bill_number VARCHAR(255) NOT NULL
);
CREATE TABLE box (
box_id INT IDENTITY(1,1) PRIMARY KEY,
box_number VARCHAR(255) NOT NULL
);
CREATE TABLE weight (
weight_id INT IDENTITY(1,1) PRIMARY KEY,
weight_number VARCHAR(255) NOT NULL
);
CREATE TABLE bill_box_weight (
bill_id INT NOT NULL,
box_id INT NOT NULL,
weight_id INT NOT NULL,
FOREIGN KEY (bill_id) REFERENCES bill (bill_id),
FOREIGN KEY (box_id) REFERENCES box (box_id),
FOREIGN KEY (weight_id) REFERENCES weight (weight_id),
PRIMARY KEY (bill_id, box_id, weight_id)
);
2. โค้ด migration แบบเดิม ไปแบบใหม่
Code (PHP)
// Connect to the database
$serverName = "serverName\sqlexpress";
$connectionOptions = array(
"Database" => "old_database",
"UID" => "username",
"PWD" => "password"
);
$conn = sqlsrv_connect($serverName, $connectionOptions);
// Query ข้อมูลจากตารางเดิม
$oldData = array();
$query = "SELECT bill1, box1, weight1 FROM old_table";
$stmt = sqlsrv_query($conn, $query);
if ($stmt === false) {
die(print_r(sqlsrv_errors(), true));
}
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$oldData[] = $row;
}
// Insert ข้อมูลไปยังตารางใหม่
// Loop แต่ละแถวจากข้อมูลเก่า (อาร์เรย์ $oldData)
foreach ($oldData as $row) {
// Insert ตาราง 'bill'
$billQuery = "INSERT INTO bill (bill_number) VALUES (?)";
$billParams = array($row['bill1']);
$billStmt = sqlsrv_prepare($conn, $billQuery, $billParams);
sqlsrv_execute($billStmt);
// Insert ตาราง 'box'
$boxQuery = "INSERT INTO box (box_number) VALUES (?)";
$boxParams = array($row['box1']);
$boxStmt = sqlsrv_prepare($conn, $boxQuery, $boxParams);
sqlsrv_execute($boxStmt);
// Insert ตาราง 'weight'
$weightQuery = "INSERT INTO weight (weight_number) VALUES (?)";
$weightParams = array($row['weight1']);
$weightStmt = sqlsrv_prepare($conn, $weightQuery, $weightParams);
sqlsrv_execute($weightStmt);
// เก็บค่า ID จากแถวที่ insert
$bill_id = sqlsrv_query($conn, "SELECT SCOPE_IDENTITY()")->fetch()[0];
$box_id = sqlsrv_query($conn, "SELECT SCOPE_IDENTITY()")->fetch()[0];
$weight_id = sqlsrv_query($conn, "SELECT SCOPE_IDENTITY()")->fetch()[0];
// Insert ความสัมพันธ์ของข้อมูลในตาราง 'bill_box_weight'
$bbwQuery = "INSERT INTO bill_box_weight (bill_id, box_id, weight_id) VALUES (?, ?, ?)";
$bbwParams = array($bill_id, $box_id, $weight_id);
$bbwStmt = sqlsrv_prepare($conn, $bbwQuery, $bbwParams);
sqlsrv_execute($bbwStmt);
}
3. ตรวจสอบข้อมูลในตารางใหม่ว่าถูกต้องหรือไม่ แล้วลบตารางเดิม
Quote: คำเตือน:
ก่อนนำไปใช้ ให้ฝึกกำลังภายในให้ช่ำชอง
ด้วยการทดลองเปลี่ยนค่าต่างๆ และทดสอบ
จาก DB ขนา่ดเล็ก จนเข้าใจก่อน
ไม่งั้น อาจน้ำตาตกใน
Date :
2023-02-16 22:30:39
By :
009
ขอบคุณทุกคำแนะนำมากๆครับ ผมจะลองทำตามดูครับ
Date :
2023-02-17 15:13:46
By :
kko
Load balance : Server 05