Kotchasan Framework Documentation
PostgreSQLDriver Class
PostgreSQLDriver Class
ภาพรวม
คลาส Kotchasan\Connection\PostgreSQLDriver เป็นไดรเวอร์เฉพาะสำหรับฐานข้อมูล PostgreSQL รองรับฟีเจอร์ขั้นสูงของ PostgreSQL เช่น schemas, SSL connections, และ SQL functions ที่เฉพาะเจาะจง
การติดตั้งและความต้องการ
ความต้องการ
- PHP 7.4 หรือสูงกว่า
- PDO PostgreSQL extension (
pdo_pgsql) - PostgreSQL 10.0+
การตรวจสอบ Extension
if (!extension_loaded('pdo_pgsql')) {
throw new \Exception('PDO PostgreSQL extension ไม่ได้ติดตั้ง');
}การตั้งค่าการเชื่อมต่อ
การตั้งค่าพื้นฐาน
use Kotchasan\Connection\PostgreSQLDriver;
$config = [
'host' => 'localhost',
'port' => 5432,
'database' => 'myapp',
'username' => 'postgres',
'password' => 'password',
'schema' => 'public'
];
$driver = new PostgreSQLDriver();
$connected = $driver->connect($config);การตั้งค่า SSL
$config = [
'host' => 'postgres.example.com',
'port' => 5432,
'database' => 'secure_db',
'username' => 'app_user',
'password' => 'secure_pass',
'schema' => 'app_schema',
'sslmode' => 'require',
'sslcert' => '/path/to/client.crt',
'sslkey' => '/path/to/client.key',
'sslrootcert' => '/path/to/ca.crt',
'application_name' => 'MyKotchasanApp'
];ฟีเจอร์เฉพาะ PostgreSQL
การจัดการ Schema
// การเชื่อมต่อกับ schema เฉพาะ
$config['schema'] = 'analytics';
$driver->connect($config);การเพิ่มประสิทธิภาพตาราง
// PostgreSQL ใช้ VACUUM แทน OPTIMIZE
$success = $driver->optimizeTable('users');
// ทำงานเป็น: VACUUM FULL "users";การล้างข้อมูลตาราง
// TRUNCATE พร้อม options เฉพาะ PostgreSQL
$success = $driver->emptyTable('temp_data', [
'use_truncate' => true,
'restart_identity' => true, // รีเซ็ต sequence
'cascade' => false // ไม่ลบตารางที่เกี่ยวข้อง
]);SQL Functions สำหรับ PostgreSQL
ฟังก์ชันวันที่และเวลา
// ดึงปี (ใช้ EXTRACT)
$yearFunc = $driver->formatSqlFunction('YEAR', ['column' => 'created_at'], 'year_created');
// ผลลัพธ์: EXTRACT(YEAR FROM "created_at") AS "year_created"
// แปลงเป็นวันที่
$dateFunc = $driver->formatSqlFunction('DATE', ['column' => 'timestamp_col'], 'date_only');
// ผลลัพธ์: "timestamp_col"::DATE AS "date_only"
// จัดรูปแบบวันที่
$formatFunc = $driver->formatSqlFunction('DATE_FORMAT', [
'column' => 'created_at',
'format' => 'YYYY-MM-DD'
], 'formatted_date');
// ผลลัพธ์: TO_CHAR("created_at", 'YYYY-MM-DD') AS "formatted_date"ฟังก์ชันข้อความ
// รวมข้อความแบบกลุ่ม (ใช้ STRING_AGG)
$groupConcatFunc = $driver->formatSqlFunction('GROUP_CONCAT', [
'column' => 'tag_name',
'separator' => ', ',
'order' => ['tag_name']
], 'tags');
// ผลลัพธ์: STRING_AGG("tag_name", ', ' ORDER BY "tag_name") AS "tags"
// จัดการค่า NULL (ใช้ COALESCE)
$ifnullFunc = $driver->formatSqlFunction('IFNULL', [
'column1' => 'nickname',
'column2' => 'first_name'
], 'display_name');
// ผลลัพธ์: COALESCE("nickname", "first_name") AS "display_name"ฟังก์ชันอื่นๆ
// สุ่ม (ใช้ RANDOM)
$randFunc = $driver->formatSqlFunction('RAND', [], 'random_value');
// ผลลัพธ์: RANDOM() AS "random_value"
// ความแตกต่างของวันที่
$datediffFunc = $driver->formatSqlFunction('DATEDIFF', [
'column1' => 'end_date',
'column2' => 'start_date'
], 'duration');
// ผลลัพธ์: ("end_date" - "start_date") AS "duration"ตัวอย่างการใช้งาน
การทำงานกับ Sequences
// ดึง ID ล่าสุดจาก sequence
$lastId = $driver->lastInsertId('users_id_seq');
// ใช้ในการ INSERT
$stmt = $driver->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->execute(['John Doe', 'john@example.com']);
$newId = $driver->lastInsertId('users_id_seq');การจัดการ Transaction ขั้นสูง
try {
$driver->beginTransaction();
// ตั้งค่า isolation level
$driver->prepare("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE")->execute();
// ทำงานต่างๆ
$stmt1 = $driver->prepare("INSERT INTO orders (user_id, total) VALUES (?, ?)");
$stmt1->execute([1, 100.00]);
$stmt2 = $driver->prepare("UPDATE inventory SET quantity = quantity - ? WHERE product_id = ?");
$stmt2->execute([1, 123]);
$driver->commit();
} catch (\Exception $e) {
$driver->rollback();
throw $e;
}การใช้งาน JSON (PostgreSQL 9.2+)
// คิวรี JSON data
$sql = "SELECT data->>'name' as name, data->>'email' as email FROM user_profiles WHERE data ? 'active'";
$stmt = $driver->prepare($sql);
$result = $stmt->execute();การจัดการข้อผิดพลาด
ข้อผิดพลาดที่พบบ่อย
try {
$driver->connect($config);
} catch (\PDOException $e) {
$errorCode = $e->getCode();
$message = $e->getMessage();
if (strpos($message, 'authentication failed') !== false) {
echo "การยืนยันตัวตนล้มเหลว";
} elseif (strpos($message, 'database') !== false && strpos($message, 'does not exist') !== false) {
echo "ไม่พบฐานข้อมูลที่ระบุ";
} elseif (strpos($message, 'Connection refused') !== false) {
echo "ไม่สามารถเชื่อมต่อเซิร์ฟเวอร์ PostgreSQL";
} else {
echo "ข้อผิดพลาด PostgreSQL: " . $message;
}
}การปรับแต่งประสิทธิภาพ
การตั้งค่า PostgreSQL ที่แนะนำ
-- postgresql.conf
shared_buffers = 256MB
effective_cache_size = 1GB
work_mem = 4MB
maintenance_work_mem = 64MB
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100การใช้ EXPLAIN ANALYZE
// วิเคราะห์ประสิทธิภาพคิวรี
$sql = "EXPLAIN ANALYZE SELECT * FROM users WHERE email = ?";
$stmt = $driver->prepare($sql);
$result = $stmt->execute(['user@example.com']);คำแนะนำและข้อควรระวัง
แนวทางปฏิบัติที่ดี
- ใช้ Schemas: จัดระเบียบตารางด้วย schemas
- ตั้งค่า SSL: ใช้ SSL สำหรับการเชื่อมต่อที่ปลอดภัย
- ใช้ VACUUM: ทำ VACUUM เป็นประจำ
- จัดการ Sequences: ระบุ sequence name เมื่อใช้ lastInsertId()
ข้อควรระวัง
- Case Sensitivity: PostgreSQL แยกตัวพิมพ์ใหญ่-เล็ก
- Identifier Quoting: ใช้ double quotes สำหรับ identifiers
- Data Types: ระวังความแตกต่างของ data types
ปัญหาที่พบบ่อย
- Schema Path: ตั้งค่า search_path ให้ถูกต้อง
- Encoding: ใช้ UTF-8 encoding
- Connection Pooling: ใช้ connection pooling สำหรับแอปพลิเคชันขนาดใหญ่
คลาสที่เกี่ยวข้อง
- Connection - คลาสการเชื่อมต่อพื้นฐาน
- ConnectionManager - ตัวจัดการการเชื่อมต่อ
- DriverInterface - อินเทอร์เฟซไดรเวอร์
- MySQLDriver - ไดรเวอร์ MySQL