Learn & Record
SQL MariaDB (1:다 관계, 다:다 관계, 정규화, 역정규화, JDBC, 인텔리제이 JDBC 연결, JDBC 과정, 주요 클래스) 본문
SQL MariaDB (1:다 관계, 다:다 관계, 정규화, 역정규화, JDBC, 인텔리제이 JDBC 연결, JDBC 과정, 주요 클래스)
Walker_ 2024. 2. 14. 13:481. 1:다 관계
- 가장 흔하며, 대표적으로 부서와 직원 관계가 있다
- 지원은 한 부서에 소속되며, 한 부서에는 여러 명의 직원이 있음
2. 다:다 관계
- 양쪽 엔티티가 서로 복수개의 엔티티로 연결
- 예시) 학생과 과목간의 수강 관계
- 관계형 DB로는 다:다 관계를 표현할 수 없어 두 개의 1:다 관계로 변환하여 표현
3. 정규화
- 테이블을 재구성하여 논리적 구조를 개선하는 절차
- 불필요하게 중복되는 데이터를 제거하여 저장 공간을 절약하고 전체적인 성능을 향상시킴
- 제 1 정규화 : 필드의 데이터를 원자화(Ayomicity) 함. 필드에는 단일 값을 저장하고 필드끼리는 독립적이어야 함
- 한 필드에 여러 값을 저장하면, 필드 길이가 낭비가 됨. / 연산자로 비교 못 해서 LIKE를 사용하여 성능 저하
- 수정은 더 문제가 됨 / 그래서 필드값은 더 나눌 수 없는 하나의 값으로 저장 / 테이블 분리하는 것이 좋음
- 외부 테이블에 대한 참조를 가지는 키를 외래키라 하며, 양 테이블의 연결고리 역할을 함
- 제 2 정규화 : 일반 필드를 모두 기본키에 종속시키는 것
- 모든 필드는 복합키 전체에 종속되어야 하며 일부에만 종속되서는 안됨
- 제 3 정규화 : 기본키가 아닌 일반 필드끼리 서로 종속되지 않도록 하는 것.
- 일반 필드끼리는 독립적이어야 한다는 규칙
4. 역정규화
- 정규화 과정을 거치면 중복이 제거되고 구조가 치밀해짐
- 정규화가 너무 과하면 이중 삼중 조인이 되어 결코 무시할 수 없는 성능 저하가 발생
- 이럴 때, 의도적으로 데이터를 중복시켜 성능을 향상시키는 등 역정규화 시행
5. JDBC
- JDBC(Java DataBase Connectivity)
- JDBC는 데이터베이스 관리시스템의 종류와 상관없이 동일하게 사용할 수 있는 클래스와 인터페이스로 구성
6. 인텔리제이 JDBC 연결
- https://mariadb.com/downloads/connectors/ 접속 > JAVA 8+ 설정 > 다운로드

- 프로젝트에 jar 폴더 생성 후 > 파일 복사

- File > Project Structure 클릭

- Libraries > + 클릭 > Java 선택

- jar 선택 후 > OK

- .idea > libraies > XML 파일 확인

7. JDBC 프로그램 과정
- 1) 사용하고자 하는 RDBMS에서 제공하는 JDBC 드라이버를 설치
- 2) JDBC 드라이버를 로딩
- 드라이버를 로딩할 때는 클래스의 동적 바인딩을 제공한 Class 클래스의 static 메서드인 forName() 사용
public class My_01_LoadDriver {
public static void loadDriver() {
try {
Class.forName("org.mariadb.jdbc.Driver");
System.out.println("Driver Load Success!");
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
loadDriver();
}
}
// Driver Load Success!
- 3) DBMS와 연결을 설정
- java.sql 패키지가 제공하는 connection 객체를 사용
- Connection
package ch_01.day240214;
import java.sql.*;
public class DB {
Connection conn = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
public void connectDB() {
final String driver = "org.mariadb.jdbc.Driver"; // JDBC 드라이버
final String DB_HOST = "127.0.0.1"; // DB IP
final String DB_PORT = "3306"; // DB PORT 번호
final String DB_NAME = "sample"; // 접속 데이터베이스 이름
final String DB_URL = "jdbc:mariadb://" + DB_HOST + ":" + DB_PORT + "/" + DB_NAME; // 경로 URL 생성
final String DB_USER = "root"; // 유저 root 명
final String DB_PASS = "5046"; // DB 패스워드
try {
Class.forName(driver); // JDBC 드라이버 등록
conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASS); // 디비 연결
if (conn != null) {
System.out.println("DB 접속 성공");
}
} catch (ClassNotFoundException e) { // JDBC 드라이버 등록실패시
System.out.println("드라이버 로드 실패");
e.printStackTrace();
} catch (SQLException e) { // DriverManager.getConnection() 실패시
System.out.println("DB 접속 실패");
e.printStackTrace();
}
}
public void closeDB() {
/* 데이터베이스 연결 해제 */
try {
if (resultSet != null) {
resultSet.close();
}
if (preparedStatement != null) {
preparedStatement.close();
}
if (conn != null && !conn.isClosed()) {
conn.close();
System.out.println("DB 접속 해제");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package ch_01.day240214;
public class My_02_ConnectDB {
// Connection 객체를 생성해 DataBase 연결하기
public static void main(String[] args) {
DB myDB = new DB();
myDB.connectDB();
myDB.closeDB();
}
}
- IP(127.0.0.1) = localhost3306 같다
- 4) SQL을 실행
- select 구문을 실행할 때는 java.sql 패키지가 제공하는 Statement 객체와 ResultSet 객체를 사용
- Statement 객체는 SQL 구문을 위한 것이고 ResultSet는 select 구문을 실행한 결과를 다루기 위한 객체
package ch_01.day240214;
import ch_01.day240115.Person;
public class DBcreat extends DB {
public void createTableUser() {
String tableName = "tuser";
String sql = "CREATE TABLE " + tableName + " (userID VARCHAR(100) PRIMARY KEY, "
+ "name VARCHAR(100), age INT, job VARCHAR(100)) ";
createTable(tableName, sql);
}
public void createTable(String tableName, String sql) {
// 테이블을 생성하는 메서드
// 생성할 테이블 이름과 생성하는 sql 문을 매개 변수로 받음
// 1) 테이블이 존재하는 지 확인 후 2) 없으면 생성
System.out.println(sql);
try {
// 테이블이 존재하는 지 확인
String tableSql = "show tables";
boolean isTable = false;
// 아래 두 항목은 부모 클래스에서 정의
// SQL문을 전송할 수 있는 PreparedStatement 객체를 생성
preparedStatement = conn.prepareStatement(tableSql); // 쿼리 실행 준비
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
if (tableName.equals(resultSet.getString(1))) {
isTable = true;
break;
}
}
if (isTable) {
System.out.println(tableName + "이란 이름의 테이블이 이미 존재합니다.");
} else {
preparedStatement = conn.prepareStatement(sql);
resultSet = preparedStatement.executeQuery();
if (resultSet != null) {
System.out.println(tableName + " 테이블 생성에 성공했습니다.");
}
else {
System.out.println(tableName + " 테이블 생성에 실패했습니다.");
}
}
} catch (Exception e) {
System.out.println("db connect err : " + e);
}
}
}
package ch_01.day240214;
import java.sql.SQLException;
public class My_03_CreateTable {
public static void main(String[] args) throws SQLException {
DBcreat myDB = new DBcreat();
myDB.connectDB();
myDB.createTableUser();
myDB.closeDB();
}
}
- 쿼리 syntax error 발생 시 : 작성 쿼리 HeidiSQL 등에서 실행하여 에러 확인
8. JDBC 사용 시 주요 클래스
- DriverManager : JDBC Driver를 관리하며 DB와 연결해서 Connection 구현 객체를 생성
- Connection : Statement, PreparedStatement, CallableStatement 구현 객체를 생성, 트랜잭션 처리 및 연결 끊을 때 사용
- Statement : 주로 변경되지 않는 정적 SQL 문을 실행할 때 사용
- PreparedStatement : 매개변수화 된 SQL문을 사용하기에 이용 편리, 미리 만들어두고 변수를 따로 입력하는 방식