ติดตั้ง SQL Server Express และตั้งสำรองข้อมูลอัตโนมัติ
คำตอบสั้น ๆ: ติดตั้ง SQL Server Express ที่ใช้งานได้ฟรี เปิดการเชื่อมต่อจากเครือข่าย และตั้งสำรองข้อมูลอัตโนมัติซึ่งรุ่นฟรีไม่มีตัวจัดการงานให้
คู่มือนี้อธิบาย SQL Server Express ทีละขั้นตอน พร้อมคำสั่งที่ใช้ได้จริงและปัญหาที่พบบ่อย
SQL Server Express เป็นรุ่นที่ใช้งานได้ฟรีโดยไม่มีค่าลิขสิทธิ์ เหมาะกับระบบงานขนาดเล็กถึงกลาง โดยมีข้อจำกัดที่ต้องรู้ก่อนวางแผน ฐานข้อมูลละไม่เกิน 10 GB ใช้หน่วยความจำได้ 1410 MB และใช้ CPU ได้ไม่เกิน 4 คอร์หรือ 1 ซ็อกเก็ต
ข้อจำกัดที่กระทบงานดูแลระบบมากที่สุดคือไม่มี SQL Server Agent จึงตั้งงานสำรองข้อมูลตามเวลาจากในตัวโปรแกรมไม่ได้ คู่มือนี้แก้ด้วยการใช้สคริปต์ร่วมกับ Task Scheduler ซึ่งใช้งานได้ดีไม่แพ้กัน
สิ่งที่ต้องเตรียม (SQL Server Express)
Windows Server 2019 ขึ้นไป
หน่วยความจำอย่างน้อย 4 GB และพื้นที่ดิสก์ 10 GB
สิทธิ์ Administrator
ขั้นตอนที่ 1: ติดตั้ง (SQL Server Express)
ดาวน์โหลดตัวติดตั้งจากเว็บไซต์ของ Microsoft แล้วติดตั้งแบบไม่ต้องโต้ตอบ
.\SQLEXPR_x64_ENU.exe /qs /ACTION=Install /FEATURES=SQLEngine `
/INSTANCENAME=SQLEXPRESS `
/SQLSVCACCOUNT="NT AUTHORITY\NETWORK SERVICE" `
/SQLSYSADMINACCOUNTS="BUILTIN\Administrators" `
/TCPENABLED=1 `
/SECURITYMODE=SQL /SAPWD="รหัสผ่านที่แข็งแรง" `
/IACCEPTSQLSERVERLICENSETERMS
ตรวจว่าติดตั้งสำเร็จ
Get-Service | Where-Object Name -like "MSSQL*"
sqlcmd -S .\SQLEXPRESS -Q "SELECT @@VERSION;"
ติดตั้งเครื่องมือบรรทัดคำสั่งเพิ่มหากยังไม่มี
sqlcmd -?
ขั้นตอนที่ 2: เปิดการเชื่อมต่อจากเครือข่าย (SQL Server Express)
SQL Server Express ปิดการเชื่อมต่อผ่าน TCP/IP ไว้ตามค่าเริ่มต้น ต้องเปิดเองผ่าน SQL Server Configuration Manager หรือด้วยคำสั่ง
$wmi = New-Object 'Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer'
$tcp = $wmi.GetSmoObject("ManagedComputer[@Name='$env:COMPUTERNAME']/ServerInstance[@Name='SQLEXPRESS']/ServerProtocol[@Name='Tcp']")
$tcp.IsEnabled = $true
$tcp.Alter()
# ตั้งพอร์ตคงที่แทนพอร์ตแบบสุ่ม
$tcp.IPAddresses | Where-Object Name -eq 'IPAll' | ForEach-Object {
$_.IPAddressProperties['TcpDynamicPorts'].Value = ''
$_.IPAddressProperties['TcpPort'].Value = '1433'
}
$tcp.Alter()
Restart-Service 'MSSQL$SQLEXPRESS' -Force
เปิด Firewall
New-NetFirewallRule -DisplayName "SQL Server Express" `
-Direction Inbound -Protocol TCP -LocalPort 1433 -Action Allow `
-RemoteAddress 10.0.0.0/24
ทดสอบจากเครื่องอื่น
Test-NetConnection 10.0.0.61 -Port 1433
ขั้นตอนที่ 3: สร้างฐานข้อมูลและผู้ใช้
sqlcmd -S .\SQLEXPRESS -Q "CREATE DATABASE myapp;"
sqlcmd -S .\SQLEXPRESS -Q "
CREATE LOGIN myapp_user WITH PASSWORD = 'รหัสผ่านที่แข็งแรง';
USE myapp;
CREATE USER myapp_user FOR LOGIN myapp_user;
ALTER ROLE db_datareader ADD MEMBER myapp_user;
ALTER ROLE db_datawriter ADD MEMBER myapp_user;
"
อย่าให้แอปใช้บัญชี sa ให้สิทธิ์เท่าที่จำเป็นเสมอ และปิดบัญชี sa หากไม่ได้ใช้
sqlcmd -S .\SQLEXPRESS -Q "ALTER LOGIN sa DISABLE;"
ขั้นตอนที่ 4: ตั้งโหมดการกู้คืนให้เหมาะสม
sqlcmd -S .\SQLEXPRESS -Q "
SELECT name, recovery_model_desc, state_desc FROM sys.databases;
"
โหมด SIMPLE ไม่เก็บ Transaction Log ไว้ จึงกู้ย้อนเวลาไม่ได้แต่ Log ไม่โต ส่วนโหมด FULL กู้ย้อนเวลาได้แต่ต้องสำรอง Log เป็นระยะ ไม่เช่นนั้นไฟล์ Log จะโตจนดิสก์เต็ม
-- สำหรับระบบที่ยอมให้ข้อมูลหายได้ถึงรอบสำรองล่าสุด
ALTER DATABASE myapp SET RECOVERY SIMPLE;
-- สำหรับระบบที่ต้องกู้ย้อนเวลาได้
ALTER DATABASE myapp SET RECOVERY FULL;
ขั้นตอนที่ 5: เขียนสคริปต์สำรองข้อมูล
notepad C:\Scripts\sql-backup.ps1
$ErrorActionPreference = 'Stop'
$server = '.\SQLEXPRESS'
$dest = 'D:\Backups\SQL'
$stamp = Get-Date -Format 'yyyyMMdd-HHmm'
$keep = 14
New-Item -ItemType Directory -Path $dest -Force | Out-Null
$dbs = Invoke-Sqlcmd -ServerInstance $server -Query "
SELECT name FROM sys.databases
WHERE database_id > 4 AND state = 0;"
foreach ($db in $dbs) {
$n = $db.name
$file = Join-Path $dest "$n-$stamp.bak"
Invoke-Sqlcmd -ServerInstance $server -QueryTimeout 0 -Query "
BACKUP DATABASE [$n] TO DISK = N'$file'
WITH COMPRESSION, CHECKSUM, INIT, STATS = 10;"
Write-Output "สำรอง $n แล้ว: $file"
}
# ตรวจความถูกต้องของไฟล์ที่เพิ่งสร้าง
Get-ChildItem $dest -Filter "*-$stamp.bak" | ForEach-Object {
Invoke-Sqlcmd -ServerInstance $server -Query "RESTORE VERIFYONLY FROM DISK = N'$($_.FullName)';"
Write-Output "ตรวจสอบผ่าน: $($_.Name)"
}
# ลบไฟล์เก่า
Get-ChildItem $dest -Filter '*.bak' |
Where-Object LastWriteTime -lt (Get-Date).AddDays(-$keep) |
Remove-Item -Force
ติดตั้งโมดูลที่ต้องใช้
Install-Module -Name SqlServer -Scope AllUsers -Force -AllowClobber
สังเกตคำสั่ง RESTORE VERIFYONLY ซึ่งตรวจว่าไฟล์สำรองอ่านได้จริง ควรมีเสมอเพราะไฟล์สำรองที่เสียหายจะรู้ตัวก็ต่อเมื่อต้องกู้จริง
ขั้นตอนที่ 6: ตั้งเวลาด้วย Task Scheduler
$action = New-ScheduledTaskAction -Execute 'powershell.exe' `
-Argument '-NoProfile -ExecutionPolicy Bypass -File C:\Scripts\sql-backup.ps1'
$trigger = New-ScheduledTaskTrigger -Daily -At 1:30am
Register-ScheduledTask -TaskName "SQL Express Backup" `
-Action $action -Trigger $trigger `
-User "SYSTEM" -RunLevel Highest -Force
Start-ScheduledTask -TaskName "SQL Express Backup"
Get-ScheduledTaskInfo -TaskName "SQL Express Backup"
สำหรับฐานข้อมูลที่ใช้โหมด FULL ให้เพิ่มงานสำรอง Transaction Log ทุกชั่วโมงด้วย
BACKUP LOG [myapp] TO DISK = N'D:\Backups\SQL\myapp-log.trn' WITH COMPRESSION, INIT;
ขั้นตอนที่ 7: กู้คืน
-- ดูเนื้อหาของไฟล์สำรอง
RESTORE FILELISTONLY FROM DISK = N'D:\Backups\SQL\myapp-20260925-0130.bak';
-- กู้ไปยังชื่อใหม่เพื่อตรวจสอบก่อน
RESTORE DATABASE myapp_test
FROM DISK = N'D:\Backups\SQL\myapp-20260925-0130.bak'
WITH MOVE 'myapp' TO 'D:\Data\myapp_test.mdf',
MOVE 'myapp_log' TO 'D:\Data\myapp_test_log.ldf',
REPLACE, RECOVERY;
ขั้นตอนที่ 8: เฝ้าดูขีดจำกัดของรุ่นฟรี
SELECT DB_NAME(database_id) AS db,
CAST(SUM(size) * 8.0 / 1024 AS DECIMAL(10,1)) AS size_mb
FROM sys.master_files
WHERE type = 0
GROUP BY database_id
ORDER BY size_mb DESC;
เมื่อฐานข้อมูลใกล้ 10 GB ต้องวางแผนล่วงหน้า ทางเลือกคือย้ายข้อมูลเก่าออกไปฐานข้อมูลอื่น แยกตารางใหญ่ไปคนละฐานข้อมูล หรืออัปเกรดเป็นรุ่นที่มีลิขสิทธิ์
ปัญหาที่พบบ่อยเกี่ยวกับ SQL Server Express
เชื่อมต่อจากเครื่องอื่นไม่ได้
ตรวจสี่ข้อ TCP/IP เปิดแล้ว พอร์ตตั้งเป็น 1433 คงที่ Firewall เปิดแล้ว และบริการ SQL Server Browser ทำงานหากเชื่อมต่อด้วยชื่ออินสแตนซ์
Set-Service SQLBrowser -StartupType Automatic
Start-Service SQLBrowser
ไฟล์ Log โตจนดิสก์เต็ม
ฐานข้อมูลอยู่ในโหมด FULL แต่ไม่ได้สำรอง Transaction Log เลย แก้โดยเปลี่ยนเป็น SIMPLE หากไม่ต้องกู้ย้อนเวลา หรือเพิ่มงานสำรอง Log ตามขั้นตอนที่ 6
ฐานข้อมูลถึงขีดจำกัด 10 GB
จะได้ข้อผิดพลาดเมื่อพยายามเขียนเพิ่ม ตรวจขนาดตามขั้นตอนที่ 8 และย้ายข้อมูลเก่าออกก่อนจะถึงจุดนั้น
Task Scheduler รันแล้วไม่สำเร็จ
ตรวจว่าบัญชี SYSTEM มีสิทธิ์ทั้งบน SQL Server และโฟลเดอร์ปลายทาง และใส่ -NoProfile ในพารามิเตอร์เสมอ ดูผลลัพธ์ได้จาก Task Scheduler ในแท็บ History
ต้องการวางระบบฐานข้อมูลบน Windows พร้อมการสำรองข้อมูลที่ตรวจสอบได้ ติดต่อ THAI DATA CLOUD ได้ที่ https://thaidata.cloud/contact/
อ่านเพิ่มเติมเกี่ยวกับ SQL Server Express