Learn & Record

SQL MariaDB (1:다 관계, 다:다 관계, 정규화, 역정규화, JDBC, 인텔리제이 JDBC 연결, JDBC 과정, 주요 클래스) 본문

Dev/SQL

SQL MariaDB (1:다 관계, 다:다 관계, 정규화, 역정규화, JDBC, 인텔리제이 JDBC 연결, JDBC 과정, 주요 클래스)

Walker_ 2024. 2. 14. 13:48

1. 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문을 사용하기에 이용 편리, 미리 만들어두고 변수를 따로 입력하는 방식