Linux Komut Satırından MySQL Sorguları Nasıl Çalıştırılır


Bir veritabanı sunucusunu yönetmekle sorumluysanız, zaman zaman bir sorgu çalıştırmanız ve dikkatlice incelemeniz gerekebilir. Bunu MySQL/MariaDB kabuğundan yapabileceğiniz gibi, bu ipucu size MySQL/MariaDB sorgularını doğrudan Linux komut satırını kullanarak çalıştırma ve çıktıyı daha sonra incelemek üzere bir dosyaya kaydetme imkânı sağlayacaktır (bu, sorgu çok sayıda kayıt döndürüyorsa özellikle faydalıdır).

Daha ileri bir sorguya geçmeden önce, komut satırından doğrudan MYSQL sorguları çalıştırmanın bazı basit örneklerine bakalım.

Örnek Veritabanlarını Kurma

Komutlara geçmeden önce, bu kılavuz boyunca çalışacağımız örnek veritabanlarını kuralım, böylece siz de kendi sisteminizde bu teknikleri takip edebilir ve uygulayabilirsiniz.

Tecmintdb Veritabanını Oluşturma

Öncelikle, tecmintdb veritabanını ve tutorials tablosunu oluşturalım:

mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS tecmintdb;"

Sonraki adımda, tecmintdb veritabanında tutorials adlı bir veritabanı tablosu oluşturmak için aşağıdaki komutu çalıştırın:

sudo mysql -u root -p tecmintdb << 'EOF'
CREATE TABLE IF NOT EXISTS tutorials (
    tut_id INT NOT NULL AUTO_INCREMENT,
    tut_title VARCHAR(100) NOT NULL,
    tut_author VARCHAR(40) NOT NULL,
    submission_date DATE,
    PRIMARY KEY (tut_id)
);

INSERT INTO tutorials (tut_title, tut_author, submission_date) VALUES
('Getting Started with Linux', 'John Smith', '2024-01-15'),
('Advanced Bash Scripting', 'Sarah Johnson', '2024-02-20'),
('MySQL Database Administration', 'Mike Williams', '2024-03-10'),
('Apache Web Server Configuration', 'Emily Brown', '2024-04-05'),
('Python for System Administrators', 'David Lee', '2024-05-12'),
('Docker Container Basics', 'Lisa Anderson', '2024-06-18'),
('Kubernetes Orchestration', 'Robert Taylor', '2024-07-22'),
('Linux Security Hardening', 'Jennifer Martinez', '2024-08-30');
EOF

Verilerin eklendiğini doğrulayın:

sudo mysql -u root -p -e "USE tecmintdb; SELECT * FROM tutorials;"

MySQL Veritabanı Tablo Verilerini Doğrula

Çalışanlar Veritabanını Oluşturma

Şimdi, daha karmaşık bir employees veritabanı oluşturalım; birden fazla ilişkili tabloya sahip bu veritabanını daha ileri düzey sorgu örneklerinde kullanacağız:

sudo mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS employees;"

employees tablosunu oluşturun:

sudo mysql -u root -p employees << 'EOF'
CREATE TABLE IF NOT EXISTS employees (
    emp_no INT NOT NULL AUTO_INCREMENT,
    birth_date DATE NOT NULL,
    first_name VARCHAR(14) NOT NULL,
    last_name VARCHAR(16) NOT NULL,
    gender ENUM('M','F') NOT NULL,
    hire_date DATE NOT NULL,
    PRIMARY KEY (emp_no)
);

INSERT INTO employees (emp_no, birth_date, first_name, last_name, gender, hire_date) VALUES
(10001, '1953-09-02', 'Georgi', 'Facello', 'M', '1984-06-02'),
(10002, '1964-06-02', 'Bezalel', 'Simmel', 'F', '1984-11-21'),
(10003, '1959-12-03', 'Parto', 'Bamford', 'M', '1984-08-28'),
(10004, '1954-05-01', 'Chirstian', 'Koblick', 'M', '1984-12-01'),
(10005, '1955-01-21', 'Kyoichi', 'Maliniak', 'M', '1984-09-15'),
(10006, '1953-04-20', 'Anneke', 'Preusig', 'F', '1985-02-18'),
(10007, '1957-05-23', 'Tzvetan', 'Zielinski', 'F', '1985-03-20'),
(10008, '1958-02-19', 'Saniya', 'Kalloufi', 'M', '1984-07-11'),
(10009, '1952-04-19', 'Sumant', 'Peac', 'F', '1985-02-18'),
(10010, '1963-06-01', 'Duangkaew', 'Piveteau', 'F', '1984-08-24');
EOF

salaries tablosunu oluştur:

sudo mysql -u root -p employees << 'EOF'
CREATE TABLE IF NOT EXISTS salaries (
    emp_no INT NOT NULL,
    salary INT NOT NULL,
    from_date DATE NOT NULL,
    to_date DATE NOT NULL,
    PRIMARY KEY (emp_no, from_date),
    FOREIGN KEY (emp_no) REFERENCES employees(emp_no) ON DELETE CASCADE
);

INSERT INTO salaries (emp_no, salary, from_date, to_date) VALUES
(10001, 60117, '1984-06-02', '1985-06-02'),
(10001, 62102, '1985-06-02', '1986-06-02'),
(10001, 66074, '1986-06-02', '9999-01-01'),
(10002, 65828, '1984-11-21', '1985-11-21'),
(10002, 65909, '1985-11-21', '9999-01-01'),
(10003, 40006, '1984-08-28', '1985-08-28'),
(10003, 43616, '1985-08-28', '9999-01-01'),
(10004, 40054, '1984-12-01', '1985-12-01'),
(10004, 42283, '1985-12-01', '9999-01-01'),
(10005, 78228, '1984-09-15', '1985-09-15'),
(10005, 82507, '1985-09-15', '9999-01-01'),
(10006, 40000, '1985-02-18', '1986-02-18'),
(10006, 43548, '1986-02-18', '9999-01-01'),
(10007, 56724, '1985-03-20', '1986-03-20'),
(10007, 60605, '1986-03-20', '9999-01-01'),
(10008, 46671, '1984-07-11', '1985-07-11'),
(10008, 48584, '1985-07-11', '9999-01-01'),
(10009, 60929, '1985-02-18', '1986-02-18'),
(10009, 64604, '1986-02-18', '9999-01-01'),
(10010, 72488, '1984-08-24', '1985-08-24'),
(10010, 74057, '1985-08-24', '9999-01-01');
EOF

Daha karmaşık birleştirmeler için departments tablosunu oluşturun:

sudo mysql -u root -p employees << 'EOF'
CREATE TABLE IF NOT EXISTS departments (
    dept_no CHAR(4) NOT NULL,
    dept_name VARCHAR(40) NOT NULL,
    PRIMARY KEY (dept_no),
    UNIQUE KEY (dept_name)
);

INSERT INTO departments (dept_no, dept_name) VALUES
('d001', 'Marketing'),
('d002', 'Finance'),
('d003', 'Human Resources'),
('d004', 'Production'),
('d005', 'Development'),
('d006', 'Quality Management');
EOF

employees tablosunu departments tablosuna bağlamak için dept_emp tablosunu oluşturun:

sudo mysql -u root -p employees << 'EOF'
CREATE TABLE IF NOT EXISTS dept_emp (
    emp_no INT NOT NULL,
    dept_no CHAR(4) NOT NULL,
    from_date DATE NOT NULL,
    to_date DATE NOT NULL,
    PRIMARY KEY (emp_no, dept_no),
    FOREIGN KEY (emp_no) REFERENCES employees(emp_no) ON DELETE CASCADE,
    FOREIGN KEY (dept_no) REFERENCES departments(dept_no) ON DELETE CASCADE
);

INSERT INTO dept_emp (emp_no, dept_no, from_date, to_date) VALUES
(10001, 'd005', '1984-06-02', '9999-01-01'),
(10002, 'd005', '1984-11-21', '9999-01-01'),
(10003, 'd004', '1984-08-28', '9999-01-01'),
(10004, 'd004', '1984-12-01', '9999-01-01'),
(10005, 'd003', '1984-09-15', '9999-01-01'),
(10006, 'd005', '1985-02-18', '9999-01-01'),
(10007, 'd004', '1985-03-20', '9999-01-01'),
(10008, 'd005', '1984-07-11', '9999-01-01'),
(10009, 'd006', '1985-02-18', '9999-01-01'),
(10010, 'd006', '1984-08-24', '9999-01-01');
EOF

Her şeyin doğru şekilde ayarlandığını doğrulayın:

sudo mysql -u root -p -e "USE employees; SHOW TABLES;"

MySQL Veritabanı Kurulumumuzu Doğrulayın

Artık her iki veritabanını örnek verilerle kurdunuz ve bu kılavuzdaki tüm örnekleri takip edebilirsiniz. tecmintdb veritabanı basit sorgular için mükemmeldir, employees veritabanı ise join ve toplama gibi daha karmaşık işlemleri uygulamanıza olanak tanır.

Temel Sorgu Yürütme

Sunucunuzdaki tüm veritabanlarını görüntülemek için aşağıdaki komutu çalıştırabilirsiniz:

sudo mysql -u root -p -e "show databases;"

Sonraki adım olarak, tecmintdb veritabanında tutorials adlı bir veritabanı tablosu oluşturmak için aşağıdaki komutu çalıştırın:

sudo mysql -u root -p -e "USE tecmintdb; CREATE TABLE tutorials(tut_id INT NOT NULL AUTO_INCREMENT, tut_title VARCHAR(100) NOT NULL, tut_author VARCHAR(40) NOT NULL, submissoin_date DATE, PRIMARY KEY (tut_id));"

MySQL Sorgu Sonuçlarını Bir Dosyaya Kaydetmek

Aşağıdaki komutu kullanacağız ve çıktıyı, çıktıyı saklamak istediğimiz dosyanın adından sonra gelen tee komutuna yönlendireceğiz.

Örnek olarak, employees adlı bir veritabanı ve employees ile salaries tabloları arasında basit bir join kullanacağız. Kendi durumunuzda ise, sadece tırnak işaretleri arasına SQL sorgusunu yazın ve Enter tuşuna basın.

Veritabanı kullanıcısı için şifreyi girmeniz isteneceğini unutmayın:

sudo mysql -u root -p -e "USE employees; SELECT DISTINCT A.first_name, A.last_name FROM employees A JOIN salaries B ON A.emp_no = B.emp_no WHERE hire_date < '1985-01-31';" | tee queryresults.txt

Sorgu sonuçlarını cat komutunun yardımıyla görüntüleyin.

cat queryresults.txt

MySQL/MariaDB Sorgularını Komut Satırından Çalıştır

Sorgu sonuçlarını düz metin dosyalarında elde ederek, kayıtları diğer komut satırı araçlarını kullanarak daha kolay işleyebilirsiniz. Temelleri gördüğünüze göre, komut satırı veritabanı çalışmalarınızı daha verimli hale getirecek bazı daha gelişmiş teknikleri keşfedelim.

Daha İyi Okunabilirlik İçin Çıktıyı Biçimlendirme

Varsayılan tablo formatı terminalde görüntülemek için harikadır, ancak bazen farklı formatlara ihtiyacınız olur. Sonuçları dikey formatta da görüntüleyebilirsiniz, bu özellikle çok sütunlu tablolarla uğraşırken kullanışlıdır:

sudo mysql -u root -p -e "USE employees; SELECT * FROM employees LIMIT 1\G"

Sondaki \G, her satırı tablo yerine dikey olarak gösterir, böylece sıkışık bir yatay tablo görmek yerine şu şekilde bir şey elde edersiniz:

*************************** 1. row ***************************
    emp_no: 10001
birth_date: 1953-09-02
first_name: Georgi
 last_name: Facello
    gender: M
 hire_date: 1984-06-02

CSV Formatına Aktarma

Sorgu sonuçlarını elektronik tablo uygulamalarına veya diğer araçlara aktarmanız gerektiğinde, en iyi seçenek CSV formatıdır:

sudo mysql -u root -p -e "USE employees; SELECT first_name, last_name, hire_date FROM employees WHERE hire_date < '1985-01-31';" | sed 's/\t/,/g' > employees.csv

Bu, çıktıyı sed aracılığıyla borular, sekmeleri virgüllerle değiştirir ve Excel, LibreOffice Calc veya diğer herhangi bir elektronik tablo yazılımında sorunsuz açılan uygun bir CSV dosyası oluşturur.

Şifre Sormadan Sorgu Çalıştırma

Eğer veritabanı görevlerini cron işleri veya scriptlerle otomatikleştiriyorsanız, her seferinde şifreleri manuel olarak girmek istemezsiniz; işte burada MySQL yapılandırma dosyaları devreye girer.

Kimlik bilgilerinizle ~/.my.cnf dosyasını oluşturun:

[client]
user=root
password=your_password_here

Sonra yalnızca sizin okuyabileceğiniz şekilde güvence altına alın:

chmod 600 ~/.my.cnf

Artık -p bayrağı olmadan ve herhangi bir uyarı almadan sorguları çalıştırabilirsiniz:

mysql -e "SHOW DATABASES;"

Unutmayın, parolaları düz metin dosyalarında saklamanın güvenlik riskleri vardır, bu nedenle bu yaklaşımı yalnızca erişimi kontrol ettiğiniz sunucularda kullanın ve üretim ortamları için MySQL’in daha güvenli kimlik doğrulama yöntemlerini kullanmayı düşünün.

Karmaşık Çok Satırlı Sorguları Çalıştırma

Bazen sorgularınız tek bir komut satırında yazamayacak kadar karmaşıktır, özellikle birden fazla join, alt sorgu veya karmaşık koşullarla uğraşıyorsanız.

SQL'inizi bir dosyaya koyabilir ve çalıştırabilirsiniz:

cat > complex_query.sql << 'EOF'
USE employees;
SELECT 
    e.first_name,
    e.last_name,
    d.dept_name,
    s.salary
FROM employees e
INNER JOIN dept_emp de ON e.emp_no = de.emp_no
INNER JOIN departments d ON de.dept_no = d.dept_no
INNER JOIN salaries s ON e.emp_no = s.emp_no
WHERE e.hire_date BETWEEN '1985-01-01' AND '1985-12-31'
    AND s.from_date = (
        SELECT MAX(from_date) 
        FROM salaries 
        WHERE emp_no = e.emp_no
    )
ORDER BY s.salary DESC
LIMIT 10;
EOF

Şimdi uygula.

sudo mysql -u root -p < complex_query.sql > top_earners_1985.txt

Bu yaklaşım, sorgularınızı düzenli ve yeniden kullanılabilir tutar ve onları diğer herhangi bir kod gibi git ile sürüm kontrolüne alabilirsiniz.

Birden Çok Sorgunun Toplu İşlenmesi

Birden fazla ilgili sorguyu çalıştırmanız ve her sonucu ayrı ayrı kaydetmeniz gerekiyorsa, bunu script ile yapabilirsiniz:

#!/bin/bash

QUERIES=(
    "SELECT COUNT(*) as total_employees FROM employees"
    "SELECT dept_name, COUNT(*) as employee_count FROM dept_emp de JOIN departments d ON de.dept_no = d.dept_no GROUP BY dept_name"
    "SELECT YEAR(hire_date) as year, COUNT(*) as hires FROM employees GROUP BY YEAR(hire_date) ORDER BY year"
)

FILENAMES=(
    "total_count.txt"
    "dept_distribution.txt"
    "yearly_hires.txt"
)

for i in "${!QUERIES[@]}"; do
    echo "Running query $((i+1))..."
    mysql -u root -p -e "USE employees; ${QUERIES[$i]}" > "${FILENAMES[$i]}"
    echo "Results saved to ${FILENAMES[$i]}"
done

Bunu bir betik olarak kaydedin, chmod +x ile çalıştırılabilir hale getirin ve tekrar kullanılabilir bir toplu sorgulama aracınız olsun.

Uzun Süreli Sorguları İzleme

Bir süre alabilecek sorgular çalıştırıyorsanız, ilerlemeyi görmek veya en azından hâlâ çalıştıklarını bilmek istersiniz.

Sorgunuzu durum çıktısıyla birleştirin:

(sudo mysql -u root -p -e "USE employees; SELECT COUNT(*) FROM large_table WHERE complex_condition;" && echo "Query completed at $(date)") | tee query_log.txt

Daha uzun sorgular için, bunları arka planda çalıştırın ve MySQL işlem listesini izleyin:

sudo mysql -u root -p -e "USE employees; SELECT * FROM massive_table;" > output.txt &
sudo watch -n 5 'mysql -u root -p -e "SHOW PROCESSLIST\G" | grep -A 5 "SELECT"'

Bu, sorgunuzu arka planda çalıştırırken her 5 saniyede bir işlem listesini gösterir, böylece sorgunun hala çalıştığını ve ne kadar ilerleme kaydettiğini görebilirsiniz.

Sonuçları Filtreleme ve İşleme

Sorgu sonuçlarını bir metin dosyasında aldıktan sonra, onları daha fazla işlemek için standart Linux araçlarını kullanabilirsiniz. İşte bazı faydalı örüntüler:

Sonuç satırlarının sayısını sayın (başlık hariç):

tail -n +2 queryresults.txt | wc -l

Awk kullanarak belirli sütunları çıkarın:

awk '{print $1, $3}' queryresults.txt

Sonuçlarda belirli desenleri ara:

grep -i "engineering" dept_distribution.txt

Sonuçları sayısal bir sütuna göre sırala:

tail -n +2 queryresults.txt | sort -k3 -n

Özel Karakterler ve Büyük Veri Setlerinin İşlenmesi

Verileriniz özel karakterler, tab boşlukları veya yeni satırlar içeriyorsa, varsayılan çıktı karışık olabilir, bu yüzden daha temiz bir çıktı için --batch ve --raw seçeneklerini kullanın:

sudo mysql -u root -p --batch --raw -e "SELECT description FROM products WHERE category='electronics';" > products.txt

Milyonlarca satır döndüren sorgular için, her şeyi belleğe yüklemek yerine, sonuçları akış halinde işleyerek bellek sorunlarıyla karşılaşabilirsiniz:

sudo mysql -u root -p --quick -e "SELECT * FROM huge_table;" | gzip > huge_results.txt.gz

--quick seçeneği, MySQL’in tüm sonuç kümesini belleğe almadan satırları tek tek getirmesini sağlar ve gzip üzerinden yönlendirme yapmak, çıktıyı anında sıkıştırarak disk alanından tasarruf sağlar.

Hızlı Veritabanı Yedekleri Oluşturma

Bu teknik olarak sorgu çalıştırmak olmasa da, mysqldump komutunu kullanarak hızlı veritabanı dökümleri oluşturmak için benzer komut satırı tekniklerini kullanabilirsiniz.

sudo mysqldump -u root -p employees | gzip > employees_backup_$(date +%Y%m%d).sql.gz

Ya da sadece belirli tabloları yedekleyin:

sudo mysqldump -u root -p employees employees salaries | gzip > critical_tables_$(date +%Y%m%d).sql.gz

Otomatik Raporları Zamanlamak

Ele aldığımız her şeyi birleştirerek aşağıdaki bash betiğinin yardımıyla cron kullanarak otomatik günlük raporlar oluşturun.

#!/bin/bash
REPORT_DATE=$(date +%Y-%m-%d)
REPORT_FILE="/var/reports/daily_stats_${REPORT_DATE}.txt"

{
    echo "Database Statistics Report - ${REPORT_DATE}"
    echo "=========================================="
    echo
    
    echo "Total Employees:"
    mysql -e "USE employees; SELECT COUNT(*) FROM employees;"
    echo
    
    echo "New Hires This Month:"
    mysql -e "USE employees; SELECT COUNT(*) FROM employees WHERE MONTH(hire_date) = MONTH(CURRENT_DATE()) AND YEAR(hire_date) = YEAR(CURRENT_DATE());"
    echo
    
    echo "Department Distribution:"
    mysql -e "USE employees; SELECT d.dept_name, COUNT(*) as count FROM dept_emp de JOIN departments d ON de.dept_no = d.dept_no WHERE de.to_date = '9999-01-01' GROUP BY d.dept_name ORDER BY count DESC;"
    
} > "$REPORT_FILE"

echo "Report generated: $REPORT_FILE"

Bunu cron'a ekleyin ve her gün sabah 6'da çalıştırın:

0 6 * * * /usr/local/bin/generate_db_report.sh
Özet

Günlük Linux görevlerinizi otomatikleştirme veya bunları daha kolay gerçekleştirme konusunda faydalı bulabileceğiniz birkaç Linux ipucunu paylaştık.

Buradan çıkarılacak en önemli nokta, veritabanlarınızla çalışmak için her zaman MySQL kabuğunu açmanız veya ağır GUI araçları kullanmanız gerekmediğidir; komut satırı size hız, otomasyon yetenekleri ve veritabanı işlemlerini mevcut kabuk betikleriniz ve iş akışlarınıza entegre etme imkanı sağlar.

Toplulukla paylaşmak istediğiniz başka ipuçlarınız var mı? Eğer varsa, lütfen aşağıdaki yorum formunu kullanarak paylaşın. :