نصب و پیکربندی حرفهای MySQL
چون ابزار اصلی شما XAMPP است (که شامل MariaDB میشود) با همان شروع میکنیم، اما تنظیمات Production لینوکسی را هم پوشش میدهیم چون در نهایت باید پروژههایتان روی سرور واقعی…
۲.۱ نصب MySQL/MariaDB در محیطهای مختلف
چون ابزار اصلی شما XAMPP است (که شامل MariaDB میشود) با همان شروع میکنیم، اما تنظیمات Production لینوکسی را هم پوشش میدهیم چون در نهایت باید پروژههایتان روی سرور واقعی deploy شوند.
۲.۱.۱ XAMPP روی Windows (محیط شما)
XAMPP پیشفرض روی C:xampp نصب میشود و MariaDB در C:xamppmysql قرار دارد. فایل پیکربندی اصلی در این مسیر است:
PathC:xamppmysqlbinmy.ini
۲.۱.۲ نصب MySQL 8.0 روی Ubuntu/Debian (سرور Production)
Bash# Ubuntu 22.04+ sudo apt update sudo apt install mysql-server -y # تنظیمات امنیتی اولیه sudo mysql_secure_installation # بررسی وضعیت sudo systemctl status mysql # فایل تنظیمات sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
۲.۱.۳ نصب MariaDB روی CentOS/RHEL
Bashsudo dnf install mariadb-server -y sudo systemctl enable --now mariadb sudo mariadb-secure-installation
۲.۲ ساختار my.cnf – فایل پیکربندی اصلی
my.cnf (یا my.ini در Windows) قلب تنظیمات است. ساختار آن به صورت بخشهایی است که با [نام بخش] از هم جدا میشوند:
my.cnf[client] # تنظیمات کلی برای همه ابزارهای کلاینت port = 3306 default-character-set = utf8mb4 [mysql] # فقط برای ابزار mysql CLI default-character-set = utf8mb4 prompt = "u@h [d]> " [mysqld] # مهمترین بخش - تنظیمات خود سرور port = 3306 bind-address = 127.0.0.1 character-set-server = utf8mb4 collation-server = utf8mb4_persian_ci default-storage-engine = InnoDB sql_mode = STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION [mysqldump] quick quote-names default-character-set = utf8mb4
[mysqld] فقط با restart سرور اعمال میشوند. تنظیمات بخشهای دیگر برای ابزارهای کلاینت بعد از همان دستور بعدی فعال هستند.
۲.۳ تنظیمات حیاتی برای Performance
این تنظیمات را همیشه باید بررسی کنید:
my.cnf - Performance[mysqld] # === Buffer Pool (مهمترین تنظیم) === # روی سرور با 8GB RAM: 5G # روی XAMPP محلی: 256M یا 512M innodb_buffer_pool_size = 5G # تعداد instance های Buffer Pool # قانون: روی RAM > 1G، یک instance به ازای هر 1GB innodb_buffer_pool_instances = 5 # === Redo Log === # اندازه بزرگتر = نوشتن سریعتر اما recovery طولانیتر innodb_log_file_size = 512M innodb_log_buffer_size = 16M # === Flush Strategy === # 1 = ACID کامل (پیشفرض، امنترین) # 2 = یک بار در ثانیه (سریعتر، crash میتواند 1 ثانیه از دست بدهد) innodb_flush_log_at_trx_commit = 1 # === Connections === max_connections = 200 max_allowed_packet = 64M # === Tables Cache === table_open_cache = 4000 table_definition_cache = 2000 # === Temp Tables === tmp_table_size = 64M max_heap_table_size = 64M # === Slow Query Log (در فصل 5 میبینیم) === slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 1.0 log_queries_not_using_indexes = 0
- سرور Production با 16GB RAM و فقط MySQL:
10G - سرور با 16GB RAM که Apache/PHP هم دارد:
6G - VPS کوچک با 2GB RAM:
1G - XAMPP محلی برای توسعه:
256Mتا512M
۲.۴ مشکل بزرگ Encoding فارسی – utf8mb4
این یکی از پرتکرارترین مشکلاتی است که توسعهدهنده فارسیزبان با آن مواجه میشود. اگر تا حالا متن فارسی به ؟؟؟؟ یا اق تبدیل شده، با همین موضوع روبرو بودهاید.
چرا utf8 معمولی کافی نیست؟
عجیب اما واقعی: utf8 در MySQL فقط ۳ بایت در هر کاراکتر است و emoji و برخی کاراکترهای اوستایی/پهلوی را پشتیبانی نمیکند. utf8mb4 ۴ بایتی است و کامل است. همیشه از utf8mb4 استفاده کنید.
کدام Collation برای فارسی؟
| Collation | توصیف | توصیه |
|---|---|---|
utf8mb4_persian_ci |
مرتبسازی الفبای فارسی (آ، ب، پ، …) | ✅ برای فیلدهای فارسی |
utf8mb4_unicode_ci |
مرتبسازی Unicode عمومی | 👍 جایگزین قابلقبول |
utf8mb4_0900_ai_ci [MySQL 8] |
پیشفرض MySQL 8، Accent-Insensitive | 👌 مدرن، خوب |
utf8mb4_general_ci |
سریع اما نادرست در sort | ❌ توصیه نمیشود |
utf8mb4_bin |
byte-by-byte، case-sensitive | برای فیلدهای حساس به حروف بزرگ/کوچک |
تنظیم کامل برای فارسی
my.ini (XAMPP)[client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4 [mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_persian_ci init-connect = 'SET NAMES utf8mb4' skip-character-set-client-handshake
تبدیل دیتابیس موجود به utf8mb4
SQL-- 1. تغییر دیتابیس ALTER DATABASE my_database CHARACTER SET = utf8mb4 COLLATE = utf8mb4_persian_ci; -- 2. تغییر هر جدول ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_persian_ci; -- 3. تولید script برای همه جدولها SELECT CONCAT( 'ALTER TABLE `', table_name, '` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_persian_ci;' ) AS sql_command FROM information_schema.tables WHERE table_schema = 'my_database' AND table_type = 'BASE TABLE';
ALTER TABLE همه جدول را قفل میکند. در محیط Production از pt-online-schema-change از Percona Toolkit استفاده کنید (در فصل ۱۴ میبینیم).
۲.۵ sql_mode – حفاظت از دادههای نادرست
یکی از مهمترین تنظیماتی که اکثر توسعهدهندهها نادیده میگیرند. sql_mode تعیین میکند MySQL در برابر دادههای اشتباه چگونه واکنش نشان دهد.
SQL-- بررسی mode فعلی SELECT @@sql_mode; -- mode پیشنهادی برای پروژه جدید (Strict) SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO';
flagهای مهم:
- STRICT_TRANS_TABLES: اگر داده اشتباه insert شود (مثلاً string در ستون int)، خطا میدهد بهجای truncate کردن بیصدا
- NO_ZERO_DATE: اجازه نمیدهد
0000-00-00ذخیره شود - NO_ZERO_IN_DATE: اجازه نمیدهد
2024-00-15ذخیره شود - ERROR_FOR_DIVISION_BY_ZERO: تقسیم بر صفر را خطا میدهد، نه NULL
- ONLY_FULL_GROUP_BY: ستونهای GROUP BY باید کامل ذکر شوند (پیشفرض MySQL 8)
SET sql_mode = ''. اما این یک «بدهی فنی» است که باید برطرف شود.
۲.۶ راهاندازی اولیه و امنیت
بعد از نصب، این مراحل ضروری است:
SQL-- 1. حذف کاربران anonymous DELETE FROM mysql.user WHERE User=''; -- 2. حذف دیتابیس test DROP DATABASE IF EXISTS test; -- 3. اطمینان از root با password قوی ALTER USER 'root'@'localhost' IDENTIFIED BY 'StrongPasswordHere2026!'; -- 4. ساخت کاربر برای اپلیکیشن (هرگز از root استفاده نکنید!) CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'AppPassword2026!'; GRANT SELECT, INSERT, UPDATE, DELETE ON my_database.* TO 'app_user'@'localhost'; FLUSH PRIVILEGES; -- 5. بررسی کاربران SELECT User, Host, plugin FROM mysql.user;
۲.۷ بررسی تنظیمات فعلی – چکلیست عملی
بعد از تغییرات، با این queryها وضعیت را بررسی کنید:
SQL-- نسخه و engine پیشفرض SELECT VERSION(); SHOW VARIABLES LIKE 'default_storage_engine'; -- character set SHOW VARIABLES LIKE 'character_set%'; SHOW VARIABLES LIKE 'collation%'; -- buffer pool SHOW VARIABLES LIKE 'innodb_buffer_pool%'; -- connection info SHOW VARIABLES LIKE 'max_connections'; SHOW STATUS LIKE 'Threads_connected'; -- timezone (مهم برای ایران!) SHOW VARIABLES LIKE '%time_zone%'; -- باید روی +03:30 یا 'Asia/Tehran' باشد SET GLOBAL time_zone = '+03:30';
۲.۸ Timezone و تاریخ شمسی
چون اپلیکیشنهای فارسی معمولاً تقویم شمسی نمایش میدهند، مدیریت timezone حیاتی است:
SQL-- بهترین رویکرد: ذخیره همه چیز به UTC در DB، تبدیل در اپلیکیشن -- اما اگر میخواهید timezone سرور Tehran باشد: -- در my.cnf default-time-zone = '+03:30' -- یا runtime SET GLOBAL time_zone = '+03:30'; -- بارگذاری timezone tables (یک بار) mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql -- بعد میتوانید از نام منطقه استفاده کنید SET time_zone = 'Asia/Tehran';
TIMESTAMP که خودکار به UTC میرود)، و در اپلیکیشن (Django یا PHP) به Asia/Tehran تبدیل کنید و سپس به شمسی. این روش روی سرورهای جهانی هم بدون مشکل کار میکند.
۲.۹ خلاصه فصل
- my.cnf قلب تنظیمات است؛ با [mysqld] شروع کنید
- innodb_buffer_pool_size مهمترین تنظیم Performance است (۵۰-۷۵٪ RAM)
- برای فارسی همیشه
utf8mb4_persian_ciاستفاده کنید - sql_mode را Strict نگه دارید تا داده اشتباه ذخیره نشود
- هرگز از root برای اپلیکیشن استفاده نکنید؛ کاربر اختصاصی بسازید
- timezone را روی
+03:30یا UTC تنظیم کنید
در فصل بعد، انواع داده و طراحی Schema حرفهای را یاد میگیریم.