Kotchasan Framework Documentation
MySQLDriver Class
MySQLDriver Class
ภาพรวม
คลาส Kotchasan\Connection\MySQLDriver เป็นไดรเวอร์เฉพาะสำหรับฐานข้อมูล MySQL และ MariaDB รองรับฟีเจอร์ทั้งหมดของ MySQL รวมถึง SQL functions, การเพิ่มประสิทธิภาพตาราง และการจัดการ charset
การติดตั้งและความต้องการ
ความต้องการ
- PHP 7.4 หรือสูงกว่า
- PDO MySQL extension (
pdo_mysql) - MySQL 5.7+ หรือ MariaDB 10.2+
การตรวจสอบ Extension
if (!extension_loaded('pdo_mysql')) {
throw new \Exception('PDO MySQL extension ไม่ได้ติดตั้ง');
}การตั้งค่าการเชื่อมต่อ
การตั้งค่าพื้นฐาน
use Kotchasan\Connection\MySQLDriver;
$config = [
'host' => 'localhost',
'port' => 3306,
'database' => 'myapp',
'username' => 'dbuser',
'password' => 'dbpass',
'charset' => 'utf8mb4'
];
$driver = new MySQLDriver();
$connected = $driver->connect($config);การตั้งค่าขั้นสูง
$config = [
'host' => 'mysql.example.com',
'port' => 3306,
'database' => 'production_db',
'username' => 'app_user',
'password' => 'secure_password',
'charset' => 'utf8mb4',
'unix_socket' => '/var/run/mysqld/mysqld.sock', // สำหรับ Unix socket
];การตั้งค่า SSL
$config = [
'host' => 'secure-mysql.example.com',
'port' => 3306,
'database' => 'secure_db',
'username' => 'ssl_user',
'password' => 'ssl_password',
'charset' => 'utf8mb4',
// PDO options สำหรับ SSL จะถูกจัดการโดยไดรเวอร์
];การใช้งานพื้นฐาน
การเชื่อมต่อและตรวจสอบสถานะ
$driver = new MySQLDriver();
if ($driver->connect($config)) {
echo "เชื่อมต่อ MySQL สำเร็จ";
if ($driver->isConnected()) {
echo "สถานะ: เชื่อมต่ออยู่";
}
} else {
echo "เชื่อมต่อไม่สำเร็จ: " . $driver->getLastError();
}การเตรียม Statement
$sql = "SELECT * FROM users WHERE status = ? AND created_at > ?";
$statement = $driver->prepare($sql);
// ใช้งาน statement
$result = $statement->execute(['active', '2024-01-01']);การจัดการ Transaction
try {
$driver->beginTransaction();
// ทำงานหลายๆ คำสั่ง
$stmt1 = $driver->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt1->execute(['John Doe', 'john@example.com']);
$stmt2 = $driver->prepare("UPDATE profiles SET user_id = ? WHERE id = ?");
$stmt2->execute([$driver->lastInsertId(), 1]);
$driver->commit();
echo "Transaction สำเร็จ";
} catch (\Exception $e) {
$driver->rollback();
echo "Transaction ล้มเหลว: " . $e->getMessage();
}ฟีเจอร์เฉพาะ MySQL
การเพิ่มประสิทธิภาพตาราง
// เพิ่มประสิทธิภาพตารางเดียว
$success = $driver->optimizeTable('users');
if ($success) {
echo "เพิ่มประสิทธิภาพตาราง users สำเร็จ";
}
// เพิ่มประสิทธิภาพหลายตาราง
$tables = ['users', 'posts', 'comments'];
foreach ($tables as $table) {
$driver->optimizeTable($table);
}การล้างข้อมูลตาราง
// ใช้ TRUNCATE (เร็วกว่า)
$success = $driver->emptyTable('temp_data', ['use_truncate' => true]);
// ใช้ DELETE (ปลอดภัยกว่า)
$success = $driver->emptyTable('logs', ['use_truncate' => false]);การป้องกัน SQL Injection
$userInput = "'; DROP TABLE users; --";
$escaped = $driver->escape($userInput);
// ใช้ในคิวรี (แต่แนะนำให้ใช้ prepared statements)
$sql = "SELECT * FROM users WHERE name = {$escaped}";SQL Functions
ฟังก์ชันวันที่และเวลา
// ดึงปี
$yearFunc = $driver->formatSqlFunction('YEAR', ['column' => 'created_at'], 'year_created');
// ผลลัพธ์: YEAR(`created_at`) AS `year_created`
// ดึงเดือน
$monthFunc = $driver->formatSqlFunction('MONTH', ['column' => 'created_at'], 'month_created');
// ผลลัพธ์: MONTH(`created_at`) AS `month_created`
// วันที่ปัจจุบัน
$nowFunc = $driver->formatSqlFunction('NOW', [], 'current_time');
// ผลลัพธ์: NOW() AS `current_time`
// จัดรูปแบบวันที่
$dateFormatFunc = $driver->formatSqlFunction('DATE_FORMAT', [
'column' => 'created_at',
'format' => '%Y-%m-%d'
], 'formatted_date');
// ผลลัพธ์: DATE_FORMAT(`created_at`, '%Y-%m-%d') AS `formatted_date`ฟังก์ชันข้อความ
// รวมข้อความ
$concatFunc = $driver->formatSqlFunction('CONCAT', [
'fields' => ['first_name', 'last_name'],
'separator' => ' '
], 'full_name');
// ผลลัพธ์: CONCAT_WS(' ', `first_name`, `last_name`) AS `full_name`
// รวมข้อความแบบกลุ่ม
$groupConcatFunc = $driver->formatSqlFunction('GROUP_CONCAT', [
'column' => 'tag_name',
'separator' => ', ',
'distinct' => true,
'order' => ['tag_name']
], 'tags');
// ผลลัพธ์: GROUP_CONCAT(DISTINCT `tag_name` ORDER BY `tag_name` SEPARATOR ', ') AS `tags`ฟังก์ชันคำนวณ
// นับจำนวน
$countFunc = $driver->formatSqlFunction('COUNT', [
'column' => 'id',
'distinct' => true
], 'total_users');
// ผลลัพธ์: COUNT(DISTINCT `id`) AS `total_users`
// รวม
$sumFunc = $driver->formatSqlFunction('SUM', ['column' => 'amount'], 'total_amount');
// ผลลัพธ์: SUM(`amount`) AS `total_amount`
// ค่าเฉลี่ย
$avgFunc = $driver->formatSqlFunction('AVG', ['column' => 'score'], 'average_score');
// ผลลัพธ์: AVG(`score`) AS `average_score`ฟังก์ชันอื่นๆ
// สุ่ม
$randFunc = $driver->formatSqlFunction('RAND', [], null);
// ผลลัพธ์: RAND()
// จัดการค่า NULL
$ifnullFunc = $driver->formatSqlFunction('IFNULL', [
'column1' => 'nickname',
'column2' => 'first_name'
], 'display_name');
// ผลลัพธ์: IFNULL(`nickname`, `first_name`) AS `display_name`
// ความแตกต่างของวันที่
$datediffFunc = $driver->formatSqlFunction('DATEDIFF', [
'column1' => 'end_date',
'column2' => 'start_date'
], 'duration_days');
// ผลลัพธ์: DATEDIFF(`end_date`, `start_date`) AS `duration_days`ตัวอย่างการใช้งานขั้นสูง
การสร้างคิวรีที่ซับซ้อน
$driver = new MySQLDriver();
$driver->connect($config);
// สร้างคิวรีรายงานยอดขาย
$sql = "
SELECT
" . $driver->formatSqlFunction('YEAR', ['column' => 'order_date'], 'year') . ",
" . $driver->formatSqlFunction('MONTH', ['column' => 'order_date'], 'month') . ",
" . $driver->formatSqlFunction('COUNT', ['column' => 'id'], 'total_orders') . ",
" . $driver->formatSqlFunction('SUM', ['column' => 'total_amount'], 'total_sales') . ",
" . $driver->formatSqlFunction('AVG', ['column' => 'total_amount'], 'average_order') . "
FROM orders
WHERE status = 'completed'
GROUP BY
" . $driver->formatSqlFunction('YEAR', ['column' => 'order_date'], null) . ",
" . $driver->formatSqlFunction('MONTH', ['column' => 'order_date'], null) . "
ORDER BY year DESC, month DESC
";
$statement = $driver->prepare($sql);
$result = $statement->execute();การจัดการข้อมูลขนาดใหญ่
// การล้างข้อมูลเก่า
$driver->beginTransaction();
try {
// ลบข้อมูลเก่า
$stmt = $driver->prepare("DELETE FROM logs WHERE created_at < DATE_SUB(NOW(), INTERVAL 30 DAY)");
$stmt->execute();
// เพิ่มประสิทธิภาพตาราง
$driver->optimizeTable('logs');
$driver->commit();
echo "ทำความสะอาดข้อมูลสำเร็จ";
} catch (\Exception $e) {
$driver->rollback();
echo "เกิดข้อผิดพลาด: " . $e->getMessage();
}การสำรองและกู้คืนข้อมูล
// สำรองตาราง
function backupTable($driver, $tableName) {
$backupTable = $tableName . '_backup_' . date('Ymd_His');
$sql = "CREATE TABLE `{$backupTable}` AS SELECT * FROM `{$tableName}`";
$statement = $driver->prepare($sql);
return $statement->execute();
}
// ใช้งาน
if (backupTable($driver, 'users')) {
echo "สำรองข้อมูลตาราง users สำเร็จ";
}การจัดการข้อผิดพลาด
ข้อผิดพลาดที่พบบ่อย
try {
$driver->connect($config);
} catch (\PDOException $e) {
switch ($e->getCode()) {
case 1045: // Access denied
echo "ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง";
break;
case 1049: // Unknown database
echo "ไม่พบฐานข้อมูลที่ระบุ";
break;
case 2002: // Connection refused
echo "ไม่สามารถเชื่อมต่อเซิร์ฟเวอร์ MySQL";
break;
default:
echo "ข้อผิดพลาด MySQL: " . $e->getMessage();
}
}การตรวจสอบสถานะการเชื่อมต่อ
function checkConnection($driver) {
if (!$driver->isConnected()) {
throw new \Exception("ไม่ได้เชื่อมต่อกับฐานข้อมูล");
}
// ทดสอบการเชื่อมต่อ
try {
$stmt = $driver->prepare("SELECT 1");
$stmt->execute();
return true;
} catch (\Exception $e) {
return false;
}
}การปรับแต่งประสิทธิภาพ
การตั้งค่า MySQL สำหรับ Kotchasan
-- การตั้งค่าที่แนะนำใน my.cnf
[mysqld]
innodb_buffer_pool_size = 1G
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 2
query_cache_size = 128M
query_cache_type = 1
max_connections = 200การใช้ Index อย่างมีประสิทธิภาพ
// ตรวจสอบ Index
$sql = "SHOW INDEX FROM users";
$statement = $driver->prepare($sql);
$result = $statement->execute();
// สร้าง Index
$sql = "CREATE INDEX idx_user_email ON users (email)";
$statement = $driver->prepare($sql);
$statement->execute();คำแนะนำและข้อควรระวัง
แนวทางปฏิบัติที่ดี
- ใช้ utf8mb4: รองรับ emoji และอักขระพิเศษ
- ใช้ Prepared Statements: ป้องกัน SQL injection
- จัดการ Transaction: ใช้ transaction สำหรับการทำงานหลายขั้นตอน
- เพิ่มประสิทธิภาพตาราง: ใช้ OPTIMIZE TABLE เป็นประจำ
ข้อควรระวัง
- Charset: ตั้งค่า charset ให้ถูกต้อง
- Connection Timeout: ตั้งค่า timeout ให้เหมาะสม
- Memory Usage: ระวังการใช้หน่วยความจำกับข้อมูลขนาดใหญ่
ปัญหาที่พบบ่อย
- Charset Issues: ใช้ utf8mb4 แทน utf8
- Connection Lost: ตรวจสอบการเชื่อมต่อก่อนใช้งาน
- Lock Timeout: ใช้ transaction ให้สั้น���ี่สุด
คลาสที่เกี่ยวข้อง
- Connection - คลาสการเชื่อมต่อพื้นฐาน
- ConnectionManager - ตัวจัดการการเชื่อมต่อ
- DriverInterface - อินเทอร์เฟซไดรเวอร์
- PostgreSQLDriver - ไดรเวอร์ PostgreSQL
- Database - Database operations