SQL(Structured Query Language)은 관계형 데이터베이스에서 데이터를 정의하고 조작하는 데 사용되는 표준 언어이다.
데이터베이스에서 데이터를 조회, 삽입, 업데이트 및 삭제하는 기능을 제공한다.
관계형 데이터베이스는 데이터를 테이블 형태로 저장한다.
각 테이블은 행과 열로 구성되며, 행은 레코드, 열은 속성을 나타냅니다. 테이블 간에는 관계가 설정될 수 있다.
테이블은 다음과 같은 구조를 가진다:
예를 들어, 직원 정보를 저장하는 employees
테이블은 다음과 같은 구조를 가질 수 있다:
employee_id | first_name | last_name | hire_date | |
---|---|---|---|---|
1 | John | Doe | john.doe@example.com | 2022-01-15 |
2 | Jane | Smith | jane.smith@example.com | 2023-05-22 |
SQL 데이터베이스는 데이터를 표 형식으로 저장하며, 각 표는 행과 열로 구성된다.
주요 SQL 데이터베이스 시스템으로는 MySQL, PostgreSQL, Oracle, Microsoft SQL Server 등이 있다.
SQL은 다양한 명령어를 제공하여 데이터베이스를 관리합니다. 주요 명령어는 다음과 같다:
테이블을 생성하려면 CREATE TABLE
명령어를 사용합니다. 예를 들어, employees
테이블을 생성하는 SQL 문은 다음과 같다:
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50),
email VARCHAR(100),
hire_date DATE
);
테이블 구조를 수정하려면 ALTER TABLE
명령어를 사용합니다. 예를 들어, employees
테이블에 phone_number
열을 추가하려면 다음과 같이 한다:
ALTER TABLE employees
ADD phone_number VARCHAR(15);
이렇게 할 수도 있다.
ALTER TABLE employees ADD COLUMN salary DECIMAL(10, 2);
테이블을 삭제하려면 DROP TABLE
명령어를 사용합니다. 다음 SQL 문은 employees
테이블을 삭제한다:
DROP TABLE employees;
데이터를 삽입하려면 INSERT INTO
명령어를 사용합니다. 예를 들어, employees
테이블에 새 직원을 추가하려면 다음과 같은 SQL 문을 사용한다:
INSERT INTO employees (employee_id, first_name, last_name, email, hire_date)
VALUES (1, 'John', 'Doe', 'john.doe@example.com', '2022-01-15');
새 데이터를 체이블에 추가한다면 이런 식이다.
INSERT INTO employees (id, name, age, department, salary)
VALUES (1, 'John Doe', 30, 'Engineering', 60000.00);
데이터를 조회하려면 SELECT
명령어를 사용합니다. 예를 들어, employees
테이블에서 모든 직원을 조회하려면 다음과 같은 SQL 문을 사용합니다:
SELECT * FROM employees;
특정 열만 조회하려면 다음과 같이 쿼리를 수정할 수 있습니다:
SELECT first_name, email FROM employees;
데이터를 업데이트하려면 UPDATE
명령어를 사용합니다. 예를 들어, employees
테이블에서 특정 직원의 이메일 주소를 업데이트하려면 다음과 같은 SQL 문을 사용합니다:
UPDATE employees
SET email = 'john.newemail@example.com'
WHERE employee_id = 1;
데이터를 삭제하려면 DELETE FROM
명령어를 사용합니다. 예를 들어, employees
테이블에서 특정 직원을 삭제하려면 다음과 같은 SQL 문을 사용합니다:
DELETE FROM employees
WHERE employee_id = 1;
위 내용을 간단 명료하게 정리하면, 다음과 같다.
INSERT INTO: 새로운 데이터를 테이블에 추가한다.
INSERT INTO employees (id, name, age, department, salary)
VALUES (1, 'John Doe', 30, 'Engineering', 60000.00);
UPDATE: 기존 데이터를 수정한다.
UPDATE employees
SET salary = 65000.00
WHERE id = 1;
DELETE: 데이터를 삭제한다.
DELETE FROM employees
WHERE id = 1;
SELECT: 데이터를 조회한다.
SELECT * FROM employees;
추가적인 내용을 더 보자면,
GRANT: 사용자에게 권한을 부여한다.
GRANT SELECT, INSERT ON employees TO user1;
REVOKE: 사용자 권한을 철회한다.
REVOKE INSERT ON employees FROM user1;
JOIN
명령어를 사용하여 여러 테이블의 데이터를 결합할 수 있다.
주요 JOIN
유형은 다음과 같다:
예시를 통해 보자면,
INNER JOIN: 두 테이블에서 일치하는 행만 조회한다.
SELECT employees.name, departments.department_name
FROM employees
INNER JOIN departments
ON employees.department = departments.department_id;
LEFT JOIN: 왼쪽 테이블의 모든 행과 오른쪽 테이블의 일치하는 행을 조회한다.
SELECT employees.name, departments.department_name
FROM employees
LEFT JOIN departments
ON employees.department = departments.department_id;
RIGHT JOIN: 오른쪽 테이블의 모든 행과 왼쪽 테이블의 일치하는 행을 조회한다.
SELECT employees.name, departments.department_name
FROM employees
RIGHT JOIN departments
ON employees.department = departments.department_id;
FULL OUTER JOIN: 두 테이블의 모든 행을 조회하며, 일치하지 않는 경우 NULL을 반환한다.
SELECT employees.name, departments.department_name
FROM employees
FULL OUTER JOIN departments
ON employees.department = departments.department_id;
이런 구성이다.
예를 들어, employees
테이블과 departments
테이블을 결합하려면 다음과 같은 SQL 문을 사용할 수 있다:
SELECT e.first_name, d.department_name
FROM employees e
INNER JOIN departments d ON e.department_id = d.department_id;
추가적으로 더 볼수 있는 것은 서브쿼리가 있다.
단일 행 서브쿼리: 하나의 값만 반환하는 서브쿼리 이다.
SELECT name
FROM employees
WHERE age = (SELECT MAX(age) FROM employees);
다중 행 서브쿼리: 여러 값을 반환하는 서브쿼리 이다.
SELECT name
FROM employees
WHERE department IN (SELECT department_id FROM departments WHERE department_name = 'Engineering');
상관 서브쿼리: 외부 쿼리와 연관된 서브쿼리 이다.
SELECT name
FROM employees e1
WHERE salary > (SELECT AVG(salary) FROM employees e2 WHERE e1.department = e2.department);
집계 함수는 데이터를 요약하는 데 사용된다.
주요 집계 함수는 다음과 같다:
예시를 통해 보자.
COUNT: 행의 수를 센다.
SELECT COUNT(*) FROM employees;
SUM: 값의 합계를 계산한다.
SELECT SUM(salary) FROM employees;
AVG: 값의 평균을 계산한다.
SELECT AVG(salary) FROM employees;
MIN: 최소 값을 찾는다.
SELECT MIN(salary) FROM employees;
MAX: 최대 값을 찾는다.
SELECT MAX(salary) FROM employees;
예를 들어, employees
테이블에서 직원 수를 계산하려면 다음과 같은 SQL 문을 사용한다면:
SELECT COUNT(*) FROM employees;
서브쿼리는 다른 쿼리의 결과를 사용하는 쿼리이다.
서브쿼리는 SELECT
, INSERT
, UPDATE
, DELETE
문에서 사용될 수 있다.
예를 들어, employees
테이블에서 가장 높은 급여를 받는 직원을 조회하려면 다음과 같은 SQL 문을 사용할 수 있다:
SELECT * FROM employees
WHERE salary = (SELECT MAX(salary) FROM employees);
데이터베이스 테이블의 검색 성능을 향상시키기 위한 데이터 구조이며, 인덱스를 사용하면 검색 속도가 크게 향상될 수 있다.
인덱스 생성:
CREATE INDEX idx_salary
ON employees(salary);
인덱스 삭제:
DROP INDEX idx_salary;
인덱스는 데이터베이스 테이블의 검색 성능을 향상시키는 데 사용된다.
인덱스를 생성하려면 CREATE INDEX
명령어를 사용한다.
예를 들어, employees
테이블의 last_name
열에 인덱스를 추가하려면 다음과 같은 SQL 문을 사용하면 된다:
CREATE INDEX idx_last_name
ON employees (last_name);
데이터베이스 작업의 일련의 연산을 하나의 작업 단위로 묶는 것이다.
트랜잭션은 ACID 속성(원자성, 일관성, 고립성, 지속성)을 보장한다.
트랜잭션 시작:
START TRANSACTION;
트랜잭션 커밋:
COMMIT;
트랜잭션 롤백:
ROLLBACK;
NoSQL(Not Only SQL) 데이터베이스는 비관계형 데이터베이스로, 다양한 데이터 모델을 지원한다.
NoSQL 데이터베이스는 대규모 데이터 저장과 높은 성능을 제공하며, 수평 확장이 용이하다.
NoSQL 데이터베이스는 여러 가지 데이터 모델을 지원한다.
주요 데이터 모델은 다음과 같다:
oSQL(Not Only SQL) 데이터베이스는 비관계형 데이터베이스 시스템으로, 구조화되지 않은 데이터를 저장하고 처리하는 데 적합하다.
NoSQL 데이터베이스는 다음과 같은 네 가지 주요 유형으로 나눌 수 있다: 문서 기반, 열 기반, 키-값 저장소, 그래프 기반.
문서 지향 데이터베이스는 JSON과 유사한 문서 형태로 데이터를 저장합니다. 문서 지향 데이터베이스의 주요 특징은 다음과 같다:
예를 들어, MongoDB에서 문서를 삽입하려면 다음과 같은 명령어를 사용할 수 있다:
db.employees.insertOne({
employee_id: 1,
first_name: "John",
last_name: "Doe",
email: "john.doe@example.com",
hire_date: new Date("2022-01-15")
});
문서 기반 데이터베이스는 데이터를 문서 형태로 저장한다. 각 문서는 키-값 쌍으로 구성되며, JSON 형식으로 저장된다.
MongoDB 예제:
{
"_id": "1
"name": "Alice",
"age": 29,
"address": {
"street": "123 Elm Street",
"city": "Springfield"
}
}
문서 삽입:
db.employees.insertOne({
"_id": "1",
"name": "Alice",
"age": 29,
"address": {
"street": "123 Elm Street",
"city": "Springfield"
}
});
문서 조회:
db.employees.find({ "name": "Alice" });
문서 업데이트:
db.employees.updateOne(
{ "name": "Alice" },
{ $set: { "age": 30 } }
);
문서 삭제:
db.employees.deleteOne({ "name": "Alice" });
열 기반 데이터베이스는 데이터를 열 단위로 저장한다. 이는 대규모 데이터 분석과 쿼리 성능을 향상시키는 데 유리하다.
Cassandra 예제:
CREATE TABLE employees (
id UUID PRIMARY KEY,
name TEXT,
age INT,
department TEXT
);
열 삽입:
INSERT INTO employees (id, name, age, department)
VALUES (uuid(), 'Bob', 35, 'Marketing');
열 조회:
SELECT * FROM employees WHERE name = 'Bob';
열 업데이트:
UPDATE employees
SET age = 36
WHERE name = 'Bob';
열 삭제:
DELETE FROM employees
WHERE name = 'Bob';
키-값 저장소는 간단한 데이터 모델을 가지고 있으며, 키와 값을 쌍으로 저장한다. 매우 빠른 조회 성능을 제공한다.
Redis 예제:
SET user:1000 "Alice"
키 조회:
GET user:1000
키 업데이트:
SET user:1000 "Bob"
키 삭제:
DEL user:1000
그래프 기반 데이터베이스는 데이터와 관계를 그래프 형태로 저장한다. 복잡한 관계를 모델링하고 쿼리하는 데 유리하다.
Neo4j 예제:
CREATE (a:Person {name: 'Alice', age: 29})
CREATE (b:Person {name: 'Bob', age: 35})
CREATE (a)-[:KNOWS]->(b)
노드 조회:
MATCH (n:Person) WHERE n.name = 'Alice' RETURN n
관계 조회:
MATCH (a:Person)-[:KNOWS]->(b:Person) RETURN a, b
노드 업데이트:
MATCH (n:Person {name: 'Alice'}) SET n.age = 30
노드 삭제:
MATCH (n:Person {name: 'Alice'}) DELETE n
Spring Boot는 Spring 프레임워크의 확장으로, 빠르고 간편하게 스프링 애플리케이션을 개발할 수 있도록 도와준다. Spring Boot는 자동 설정, 내장 서버, 운영 상태 점검 등의 기능을 제공한다.
Spring Boot 프로젝트를 생성하려면 Spring Initializr를 사용할 수 있다. 다음 단계를 따라 프로젝트를 생성하자:
src/main/resources/application.properties
파일에 데이터베이스 연결 정보를 설정한다:
# MySQL 데이터베이스 설정
spring.datasource.url=jdbc:mysql://localhost:3306/mydatabase
spring.datasource.username=myuser
spring.datasource.password=mypassword
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
JPA(Entity) 클래스를 생성하여 데이터베이스 테이블과 매핑한다.
예를 들어, Employee
엔티티 클래스를 생성하려면 다음과 같이 작성한다:
package com.example.myapplication.model;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;
@Entity
@Table(name = "employees")
public class Employee {
@Id
private int employeeId;
private String firstName;
private String lastName;
private String email;
private Date hireDate;
// Getters and Setters
}
EmployeeRepository
인터페이스를 생성하여 데이터베이스 작업을 수행한다:
package com.example.myapplication.repository;
import com.example.myapplication.model.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
public interface EmployeeRepository extends JpaRepository<Employee, Integer> {
}
서비스 클래스에서 비즈니스 로직을 구현한다:
package com.example.myapplication.service;
import com.example.myapplication.model.Employee;
import com.example.myapplication.repository.EmployeeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class EmployeeService {
@Autowired
private EmployeeRepository employeeRepository;
public List<Employee> getAllEmployees() {
return employeeRepository.findAll();
}
public Employee getEmployeeById(int id) {
return employeeRepository.findById(id).orElse(null);
}
public Employee saveEmployee(Employee employee) {
return employeeRepository.save(employee);
}
public void deleteEmployee(int id) {
employeeRepository.deleteById(id);
}
}
RESTful API를 제공하는 컨트롤러 클래스를 생성한다:
package com.example.myapplication.controller;
import com.example.myapplication.model.Employee;
import com.example.myapplication.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/employees")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@GetMapping
public List<Employee> getAllEmployees() {
return employeeService.getAllEmployees();
}
@GetMapping("/{id}")
public Employee getEmployeeById(@PathVariable int id) {
return employeeService.getEmployeeById(id);
}
@PostMapping
public Employee createEmployee(@RequestBody Employee employee) {
return employeeService.saveEmployee(employee);
}
@PutMapping("/{id}")
public Employee updateEmployee(@PathVariable int id, @RequestBody Employee employee) {
employee.setEmployeeId(id);
return employeeService.saveEmployee(employee);
}
@DeleteMapping("/{id}")
public void deleteEmployee(@PathVariable int id) {
employeeService.deleteEmployee(id);
}
}
MySQL을 설치하려면 MySQL 공식 웹사이트에서 설치 파일을 다운로드하고 설치하면 된다.
설치 후, MySQL 서버를 시작하자.
MySQL 데이터베이스와 사용자를 생성하려면 MySQL 명령줄 클라이언트 또는 MySQL Workbench를 사용한다.
다음 SQL 명령어를 사용하여 데이터베이스와 사용자를 생성한다:
CREATE DATABASE mydatabase;
CREATE USER 'myuser'@'localhost' IDENTIFIED BY 'mypassword';
GRANT ALL PRIVILEGES ON mydatabase.* TO 'myuser'@'localhost';
FLUSH PRIVILEGES;
Spring Boot 애플리케이션을 실행하여 데이터베이스 연결을 테스트한다.
애플리케이션이 성공적으로 실행되면, 데이터베이스와의 연결이 성공한 것이다.
Postman 또는 cURL을 사용하여 RESTful API를 테스트한다.
예를 들어, 다음과 같은 요청을 사용하여 직원 데이터를 조회, 추가, 수정 및 삭제할 수 있다:
위 과정을 따르면, SQL, NOSQL에 대해 알 수 있다.