UPDATE `user` 
     		SET user_password=(HEX(AES_ENCRYPT(#{user_password}, 'code'))) WHERE id = #{id};

 

실무로 들어와 처음 보는 데이터 베이스 속성과 코드 암호와 방법이였다. 자바 로직에서 코드 암호화 처리를 하지 않고 데이터 베이스 쿼리문에서 넣을떄 들어가는 벨류 값과 키값을 세팅해서 넣은다음 조회쿼리문에서도 똑같은방법으로 조회를 하면 인증이 되면서 들어가는 비밀번호나 다른 암호화가 되어있는 데이터 값들이 매칭이 되어 인증 처리후 결과값 반환이 된다.  

<select id="select_user_userLogin" parameterType="com.spring.project.Dto.dataDTO" resultType="com.spring.project.Dto.dataDTO">
		select exists(select * from `user` where user_id = #{user_id} 
		AND user_pw = (HEX(AES_ENCRYPT(#{user_pw}, 'code')))
		) as `status`;	
	</select>

 

'MYSQL' 카테고리의 다른 글

DB 접근 프로그램 만들기  (0) 2023.03.23
GROUP BY 절  (0) 2023.03.16
N : M 관계  (0) 2023.03.16
MySQL FUNCTION  (0) 2023.03.16
JOIN 구문  (0) 2023.03.16

인터페이스 설계

package ch04;

import java.util.ArrayList;

public interface IUserDAO {
	
	// memberTBL 전체 조회 기능 
	ArrayList<UserDTO> select(); 
	// user 정보 저장 기능 
	int insert(UserDTO dto); 
	// user 정보 수정 기능 
	int update(UserDTO dto, String targetUserName); 
	// user 정보 삭제 기능 
	boolean delete(String username); 
}

DTO 설계

package ch04;

public class UserDTO {
	String username; 
	String birthYear; 
	String addr; 
	String mobile;
	
	public UserDTO(String username, String birthYear, String addr, String mobile) {
		this.username = username;
		this.birthYear = birthYear;
		this.addr = addr;
		this.mobile = mobile;
	}

	public String getUsername() {
		return username;
	}

	public String getBirthYear() {
		return birthYear;
	}

	public String getAddr() {
		return addr;
	}

	public String getMobile() {
		return mobile;
	} 
}

기능 구현하기

package ch04;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

public class UserDAO implements IUserDAO {

	private DBClient dbClient;

	public UserDAO() {
		initData();
	}

	private void initData() {
		dbClient = new DBClient();
	}

	@Override
	public ArrayList<UserDTO> select() {
		ArrayList<UserDTO> list = new ArrayList<>();
		Connection conn = dbClient.getConnection();
		Statement stmt = null;
		ResultSet rs = null;
		try {
			stmt = conn.createStatement();
			rs = stmt.executeQuery("SELECT * FROM usertbl ");
			while (rs.next()) {
				String username = rs.getString("username");
				String birthYear = rs.getString("birthYear");
				String addr = rs.getString("addr");
				String mobile = rs.getString("mobile");

				UserDTO dto = new UserDTO(username, birthYear, addr, mobile);
				list.add(dto);
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				rs.close();
				stmt.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

		return list;
	}

	@Override
	public int insert(UserDTO dto) {

		String sqlFormat = "INSERT INTO " + "						usertbl(username, birthYear, addr, mobile) "
				+ "					 VALUES('%s', '%s', '%s', '%s') ";
		String sql = String.format(sqlFormat, dto.getUsername(), dto.getBirthYear(), dto.getAddr(), dto.getMobile());
		Connection conn = dbClient.getConnection();
		int resultRowCount = 0;
		Statement stmt = null;
		try {
			stmt = conn.createStatement();
			resultRowCount = stmt.executeUpdate(sql);

		} catch (Exception e) {
			// e.printStackTrace();
			System.err.println("잘 확인해주세요");
		} finally {
			try {
				stmt.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return resultRowCount;
	}

	@Override
	public int update(UserDTO dto, String targetUserName) {

		String sqlFormat = "UPDATE userTbl " + "	SET birthYear = '%s', addr = '%s', mobile = '%s' "
				+ "    WHERE username = '%s' ";
		String sql = String.format(sqlFormat, dto.getBirthYear(), dto.getAddr(), dto.getMobile(), targetUserName);
		int resultRow = 0;

		try (Connection conn = dbClient.getConnection(); Statement stmt = conn.createStatement();) {
			resultRow = stmt.executeUpdate(sql);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return resultRow;
	}

	@Override
	public boolean delete(String username) {
		boolean isOk = true; 
		
		String sqlFormat = "DELETE FROM userTBL WHERE username = '%s' ";
		String sql = String.format(sqlFormat, username);
		
		Connection conn = dbClient.getConnection();
		Statement stmt = null;
		
		try {
			stmt = conn.createStatement();
			stmt.executeUpdate(sql);
		} catch (SQLException e) {
			isOk = false; 
			// 실행에 흐름이 여기로 빠졌을 경우 
			// 구매 테이블에 데이터가 남아 있어서 유저 테이블에 삭제가 가능하다. 
		} catch (Exception e) {
			// TODO: handle exception
		}	finally {
			try {
				stmt.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		
		return isOk;
	}

}

테스트

package ch04;

import java.util.ArrayList;

public class MainTest {

	public static void main(String[] args) {
		// 데이터 베이스에 접근해서 memberTBL에 대한 정보
		// 데이터 베이스에 접근해서 userTBL에 대한 정보

		UserDAO userDAO = new UserDAO();
		// 자식 테이블에 데이터를 먼저 삭제하고 부모테이블에 정보를 삭제할 수 있다.
		// 이승기는 구매 테이블 이력이 남아 있기 때문에 유저테이블에서 바로 삭제 할 수 없다. 
		boolean isDelete = userDAO.delete("이승기");
		System.out.println("isDelete : " + isDelete);
		if(isDelete == false) {
			System.out.println("구매테이블에 이력이 남아 있을 수 있습니다.");
		}
//		// insert 확인 
//		UserDTO dto = new UserDTO("유진스", "1995", "부산", "010-2222-2222");
//		int updateRowCount = userDAO.update(dto, dto.getUsername());
//		System.out.println("updateRowCount : " + updateRowCount);
		
		//int rowCount = userDAO.insert(insertDto);
		// 오류 발생 - 테이브 제약 조건 확인 addr 컬럼에는 문자열 2글자 까지만 입력 가능하다. 
		// int rowCount = userDAO.insert(new UserDTO("아이즈원", "2020", "경기도", "010-1234-1234"));
		//System.out.println("rowCount : " + rowCount);

		// select 확인
//		ArrayList<UserDTO> list = userDAO.select();
//		
//		for (int i = 0; i < list.size(); i++) {
//			System.out.println(list.get(i).getUsername());
//			System.out.println(list.get(i).getBirthYear());
//			System.out.println(list.get(i).getAddr());
//			System.out.println(list.get(i).getMobile());
//			System.out.println("----------------------");
//		}

	}

}

'MYSQL' 카테고리의 다른 글

hex 속성  (0) 2023.08.11
GROUP BY 절  (0) 2023.03.16
N : M 관계  (0) 2023.03.16
MySQL FUNCTION  (0) 2023.03.16
JOIN 구문  (0) 2023.03.16
- GROUP BY 절은 데이터들을 원하는 그룹으로 나눌 수 있다.
- 나누고자 하는 그룹의 컬럼명을 SELECT절과 GROUP BY절 뒤에 추가하면 된다.
- 집계 함수와 함께 사용되는 상수는 GROUP BY 절에 추가하지 않아도 된다. (많이 실수 하는 부분)
use employees;
show TABLES;
SELECT * FROM salaries
LIMIT 10; 

SELECT *
FROM salaries
GROUP BY emp_no
HAVING emp_no = 10001;

-- 그룹바이절에 조건절을 사용하 때는 having 절을 사용 
-- 2단계 
SELECT *, count(salary) 
FROM salaries
GROUP BY emp_no;

-- 3단계 max, min 
SELECT *, count(salary) as count, 
		max(salary) as max, min(salary) as min, 
        sum(salary) as sum, round(avg(salary)) as avg 
FROM salaries
GROUP BY emp_no;

 

 

-- 1단계 
SELECT * 
FROM employees
GROUP BY gender; 

-- 2단계 
SELECT *, count(gender) 
FROM employees
GROUP BY gender;

-- 조건 두개 걸기 
SELECT *, count(hire_date)  
FROM employees
GROUP BY hire_date, gender;


--
SELECT * FROM employees;
-- employees (1)  : dept_emp(N)
SELECT * FROM dept_emp;
 -- dept_emp (N)   :  (1) -- 1 : N  
SELECT * FROM departments;

-- employees :  departments  --> N : M 관계 차수를 가진다. 
-- 중간 테이블 dept_emp 만들어서 N : M 를 표현하고 있다. 

-- employees : dept_emp  ---> 1 : N 관계로 풀어 진다. 
-- departments : dept_emp ---> 1 : N 관계로 풀어 진다. 

-- 1단계 dept_emp  조인해보기 
SELECT * 
FROM employees as e 
LEFT JOIN dept_emp as d 
ON e.emp_no = d.emp_no;

-- 2 단계 departments 
SELECT  * 
FROM employees as e 
LEFT JOIN dept_emp as d 
ON e.emp_no = d.emp_no 
LEFT JOIN departments as dp
ON  d.dept_no = dp.dept_no;

-- 3 단계 
SELECT  e.emp_no, e.first_name, d.dept_no, dp.dept_name 
FROM employees as e 
LEFT JOIN dept_emp as d 
ON e.emp_no = d.emp_no 
LEFT JOIN departments as dp
ON  d.dept_no = dp.dept_no;


-- 4 단계 - 결과 집합에서 GROUB BY 사용 
SELECT  e.emp_no, e.first_name, d.dept_no, dp.dept_name 
FROM employees as e 
LEFT JOIN dept_emp as d 
ON e.emp_no = d.emp_no 
LEFT JOIN departments as dp
ON  d.dept_no = dp.dept_no
GROUP BY dept_no 
HAVING dept_no = 'd001';

 

'MYSQL' 카테고리의 다른 글

hex 속성  (0) 2023.08.11
DB 접근 프로그램 만들기  (0) 2023.03.23
N : M 관계  (0) 2023.03.16
MySQL FUNCTION  (0) 2023.03.16
JOIN 구문  (0) 2023.03.16
N:M(다대다) 관계란, 두 개 이상의 테이블이 서로 복수 개의 레코드를 가질 때 발생하는 관계입니다. 
예를 들어, 한 명의 학생이 여러 과목을 수강하고, 한 과목에 여러 명의 학생이 수강하는 경우입니다. 
이때, 학생 테이블과 과목 테이블은 N:M 관계를 가지며, 중간에 수강 테이블을 둬서 두 테이블 사이의 
관계를 나타냅니다. 이를 통해 데이터의 중복을 최소화하고, 데이터 일관성과 정확성을 유지할 수 있습니다.

중간 테이블을 만들어서 다시 정리 해보기

다대다(N : M) 관계 만들어 보기

CREATE TABLE student(
	student_id INT PRIMARY KEY, 
    name VARCHAR(50) NOT NULL, 
    major VARCHAR(50) NOT NULL
);

CREATE TABLE subject(
	subject_id INT PRIMARY KEY, 
    name VARCHAR(50) NOT NULL, 
    professor VARCHAR(50) NOT NULL
);

-- 중간 테이블 만들기 
-- 학생 : 수강 테이블에 관계는 1 : N 
-- 과목 : 수강 테이블에 관계는 
CREATE TABLE enrollment(
	enrollment_id INT PRIMARY KEY, 
    student_id INT NOT NULL, 
    subject_id INT NOT NULL, 
    FOREIGN KEY(student_id) REFERENCES student(student_id), 
    FOREIGN KEY(subject_id) REFERENCES subject(subject_id)
); 

-- 한 사람이 여러 개의 도시에서 여러 번 여행을 다녀온 경우를 테이블로 구축해보세요. 
-- 여기서 사람, 도시에 관계를 관계차수 표현해보세요 
-- 한 사람이 여러 도시를 방문하고, 한 도시에 여러 사람이 방문을 한다. 
-- person, city , travel 

CREATE TABLE person(
	person_id INT PRIMARY KEY, 
    name VARCHAR(50) NOT NULL
);

CREATE TABLE city(
	city_id INT PRIMARY KEY, 
    name VARCHAR(50) NOT NULL
);

-- 중간 테이블 만들기 
CREATE TABLE travel(
	person_id INT, 
    city_id INT, 
    trip_date DATE,
    PRIMARY KEY(person_id, city_id, trip_date),
    FOREIGN KEY(person_id) REFERENCES person(person_id),
    FOREIGN KEY(city_id) REFERENCES city(city_id)
);

INSERT INTO person VALUES
	(1, '김영희'), 
    (2, '박철수'), 
    (3, '이민호'), 
    (4, '한지민'), 
    (5, '송혜교');
    
INSERT INTO city VALUES
	(1, '서울'), 
    (2, '부산'), 
    (3, '제주'), 
    (4, '홍콩'), 
    (5, '도쿄');
    
INSERT INTO travel VALUES
	(1, 1, '2023-01-10'),
    (1, 2, '2021-07-11'),
    (2, 5, '2022-02-20'),
    (2, 4, '2022-04-30'),
    (3, 3, '2022-01-15'),
    (4, 5, '2022-07-22'),
    (1, 4, '2022-07-10');
    
select * from travel;

고객, 상품, 주문 목록

-- 고객, 주문목록 -->  1 : N 
-- 홍길동 --> 신발,  홍길동 
--      --> 컴퓨터, 홍길동 

-- 고객, 상품정보, 주문목록 -->  (고객: 주문목록) N : M --> 중간 테이블 주문 목록 
-- 주문목록(중간테이블)  --    1(홍길동), 1(신발), "일자" 
 
-- 테이블 설계해 주세요 
-- 고객, 상품, 주문 목록

-- 테이블 설계해주세요 
-- 고객, 상품, 주문 목록 
CREATE TABLE customer (
	id INT PRIMARY KEY,
	name VARCHAR(20) NOT NULL
);

CREATE TABLE product (
	id INT PRIMARY KEY,
	name VARCHAR(20) NOT NULL,
	price INT NOT NULL
);

CREATE TABLE `order` (
	id INT PRIMARY KEY,
	customer_id INT NOT NULL,
	product_id INT NOT NULL,
	amount INT NOT NULL,
	FOREIGN KEY (customer_id) REFERENCES customer(id),
	FOREIGN KEY (product_id) REFERENCES product(id)
);

'MYSQL' 카테고리의 다른 글

DB 접근 프로그램 만들기  (0) 2023.03.23
GROUP BY 절  (0) 2023.03.16
MySQL FUNCTION  (0) 2023.03.16
JOIN 구문  (0) 2023.03.16
1 : 1 관계  (0) 2023.03.16

함수는 특정한 작업을 수행하거나 값을 반환하는 일련의 SQL 문입니다.

1. 수학 함수 : ABS(), CEIL(), FLOOR(), ROUND(), TRUNCATE() 등
2. 문자열 함수 : CONCAT(), LENGTH(), UPPER(), LOWER(), SUBSTR(), REPLACE() 등
3. 날짜 및 시간 함수 : NOW(), CURDATE(), CURTIME(), YEAR(), MONTH(), DAY(), HOUR(), MINUTE(), SECOND(), DATE_FORMAT() 등
4. 조건 함수 : IF(), CASE(), COALESCE() 등
5. 집계 함수 : COUNT(), SUM(), AVG(), MAX(), MIN() 등

샘플 자료(다운로드)

https://drive.google.com/file/d/1e6J4dVbR4fPxYvU1sCQwcqWcvLSBIekJ/view?usp=sharing

 

employees.zip

 

drive.google.com

C 드라이버에 employees 폴더를 생성하고 그 폴더에서 바로 압축을 풀어 주세요 (폴더가 하나더 나오면 안됩니다)

명령프롬프트 실행해서 경로 이동 후 C:\employees mysql 서버에 접속해주세요

source employees.sql 엔터

CREATE TABLE userTBL(
	username char(3) not null, 
  birthYear int not null, 
  addr char(2) not null, 
  mobile char(10) not null,
  primary key(username)
); 


CREATE TABLE buyTBL(
	username char(3) not null, 
  prodName char(3) not null, 
  price int not null, 
  amount int not null, 
  foreign key(username) references userTBL(username)
);

insert into userTBL values('이승기', 1987, '서울', '010-1234-1234');
insert into userTBL values('홍길동', 1911, '부산', '010-2222-3333');
insert into userTBL values('이순신', 1999, '대구', '010-3333-4444');

insert into buyTBL values('이승기', '운동화', 50, 1);
insert into buyTBL values('이승기', '노트북', 150, 1);
insert into buyTBL values('홍길동', '책', 10, 5);
insert into buyTBL values('홍길동', '모니터', 200, 2);
insert into buyTBL values('이순신', '청바지', 40, 1);
insert into buyTBL values('이순신', '책', 10, 3);
In aggregated query without GROUP BY, expression 
#1 of SELECT list contains nonaggregated column 'shopdb.buyTBL.prodName'; 
this is incompatible with sql_mode=only_full_group_by



[mysqld]

sql_mode=NO_ENGINE_SUBSTITUTION


sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,
NO_ENGINE_SUBSTITUTION

— 집계 함수 사용 안될 경우 실행 해 주세요 
SET GLOBAL sql_mode = 'NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES';

 

'MYSQL' 카테고리의 다른 글

GROUP BY 절  (0) 2023.03.16
N : M 관계  (0) 2023.03.16
JOIN 구문  (0) 2023.03.16
1 : 1 관계  (0) 2023.03.16
1 : N 관계와 INSERT 구문  (0) 2023.03.16

-- inner join 
SELECT * 
FROM userTBL
INNER JOIN buyTBL
ON userTBL.username = buyTBL.username;  

-- left join 
SELECT * 
FROM userTBL
LEFT JOIN buyTBL 
ON userTBL.username = buyTBL.username;

SELECT * 
FROM userTBL;

-- 야스오 회원 가입 함 
INSERT INTO userTBL(username, birthYear, addr, mobile)
values('야스오', 2020, '부산', '010-1234-1234');


SELECT * 
FROM userTBL 
LEFT JOIN buyTBL 
ON userTBL.username = buyTBL.username
WHERE buyTBL.username IS NOT NULL; 

-- AS (별칭)  사용해서 다시 inner join 

SELECT * 
FROM userTBL AS U 
INNER JOIN buyTBL AS B  
ON U.username = B.username; 

-- 별칭 사용 left join, left join is not null 작성해보기

-- LEFT JOIN 기준 테이블 선정 
-- 기준 테이블 선정에 따라 결과집합이 다를 수 있다. 
-- 기준 테이블 선정 기준은 작은 데이터를 기준으로 하는 것이 좋다 
SELECT * 
FROM buyTBL as b 
LEFT JOIN userTBL as u 
ON b.username = u.username; 


-- right join 
SELECT u.username, b.prodName, b.price, b.amount  
FROM userTBL as u 
RIGHT JOIN buyTBL as b
ON u.username = b.username;


-- 연산자 사용해 보기 
SELECT u.username, b.prodName, b.price, b.amount, (b.price * b.amount) AS 'sum'
FROM userTBL as u 
RIGHT JOIN buyTBL as b
ON u.username = b.username;

JOIN 구문 작성

CREATE DATABASE shopdb; 
USE shopdb;

CREATE TABLE userTBL(
	username char(3) not null, 
  birthYear int not null, 
  addr char(2) not null, 
  mobile char(10) not null,
  primary key(username)
); 
-- 전화번호 형식을 01012341234 에서 010-1234-1234 형식으로 수정하기 위해 스키마 변경  
alter table userTBL modify mobile varchar(13);

CREATE TABLE buyTBL(
	username char(3) not null, 
  prodName char(3) not null, 
  price int not null, 
  amount int not null, 
  foreign key(username) references userTBL(username)
);

insert into userTBL values('이승기', 1987, '서울', '010-1234-1234');
insert into userTBL values('홍길동', 1911, '부산', '010-2222-3333');
insert into userTBL values('이순신', 1999, '대구', '010-3333-4444');

insert into buyTBL values('이승기', '운동화', 50, 1);
insert into buyTBL values('이승기', '노트북', 150, 1);
insert into buyTBL values('홍길동', '책', 10, 5);
insert into buyTBL values('홍길동', '모니터', 200, 2);
insert into buyTBL values('이순신', '청바지', 40, 1);
insert into buyTBL values('이순신', '책', 10, 3);


-- 에러 발생 
-- 부모 테이블 현재 userTBL에 야스오는 없는 사람이기 때문에 존재할 수 없다.
insert into buyTBL values('야스오', '책', 10, 3);

JOIN 예제문제

-- 1. 성이 이씨이면서 태어난 년도가 1999년인 구매한 아이템 정보와 총 구입금액를 표시해주세요!
SELECT prodName, (b.price * b.amount) AS '총 구입금액'
FROM buyTBL AS b
INNER JOIN userTBL AS u
ON b.username = u.username
WHERE u.username LIKE '이%' AND birthYear=1999;

-- 2. 기준 테이블은 userTBL로 하고 LEFT JOIN을 사용하여 
-- 주문자 이름과, 주소, 전화번호, 상품 이름, 가격, 주문 수량 을 출력해보자 
-- (단, 주문 정보가 없는 경우 출력하지 않는다.)
SELECT u.username, u.addr, u.mobile,b.prodName,
b.price,b.amount
FROM userTBL AS u
LEFT JOIN buyTBL AS b
ON u.username = b.username
WHERE b.username IS NOT NULL;

-- 3. LEFT JOIN 을 사용하여 NULL 값도 확인할 수 있게 출력 
SELECT *
FROM userTBL AS u
LEFT JOIN buyTBL AS b
ON u.username = b.username;

-- 4. userTBL 기준으로 INNER JOIN하고 buyTBL에서 수량이 3개 이상인 데이터만 조회해라
SELECT * 
FROM userTBL AS u
INNER JOIN buyTBL AS b
ON u.username = b.username
WHERE b.amount >= 3;

-- 5. buyTBL 기준으로 RIGHT JOIN하고 username이 '이승기'이거나 '야스오'이면서
-- userTBL의 username이 null이 아닌 데이터를 조회해라
SELECT 
    *
FROM
    buyTBL AS b
        RIGHT JOIN
    userTBL AS u ON b.username = u.username
WHERE
    (u.username = '이승기' OR u.username = '야스오')
        AND u.username IS NOT NULL;

-- 6. 기준 테이블로 buyTBL을 사용해서 LEFT JOIN을 수행하고,
-- 1999년에 태어난 사람은 총 몇 개의 물품을 구매했는지 구하시오.
SELECT b.amount
FROM buyTBL AS b
LEFT JOIN userTBL AS u
ON b.username = u.username
WHERE birthYear = 1999;

-- 7. 기준 테이블로 userTBL을 사용해서 INNER JOIN을 수행하고,
-- '책'을 구매한 사람들의 이름과 전화번호를 출력하시오.
SELECT u.username,u.mobile
FROM userTBL AS u
INNER JOIN buyTBL AS b
ON u.username = b.username
WHERE b.prodName = '책';

-- 8. 기준 테이블로 buyTBL을 사용해서 RIGHT JOIN을 수행하고,
-- '대구'에 사는 사람이 구매한 물품들을 출력하시오.
SELECT b.prodName
from buyTBL AS b
RIGHT JOIN userTBL AS u
ON b.username = u.username
WHERE addr = '대구';

 

'MYSQL' 카테고리의 다른 글

N : M 관계  (0) 2023.03.16
MySQL FUNCTION  (0) 2023.03.16
1 : 1 관계  (0) 2023.03.16
1 : N 관계와 INSERT 구문  (0) 2023.03.16
1 : N (One-to-Many Relationship) 차수에 대한 고찰  (0) 2023.03.16
MySQL에서 1:1 관계는 두 개의 테이블 간에 1:1 대응 관계가 있는 경우에 사용됩니다. 
예를 들어, 학생 정보를 저장하는 테이블과 학생의 상세 정보를 저장하는 테이블이 있을 때,
이 두 테이블은 1:1 관계를 가질 수 있습니다. 이 경우 학생 정보를 저장하는 테이블과 
학생 상세 정보를 저장하는 테이블 각각의 기본키(primary key)와 외래키(foreign key)를 연결하여 
관계를 설정합니다. 이를 통해 데이터의 중복을 최소화하고 불필요한 데이터의 저장을 방지할 수 있습니다. 
1:1 관계에서는 두 테이블 중 하나의 테이블에서만 외래키를 가질 수 있습니다
1:1 관계를 사용하는 경우는 보통 테이블의 칼럼 중에 일부가 NULL 값을 가지거나, 
특정 칼럼의 값이 자주 변경되지 않는 경우입니다. 이러한 경우 1:1 관계를 사용하면 
테이블의 정규화를 유지하면서도 데이터를 보다 효율적으로 관리할 수 있습니다.

정규화란 데이터베이스 설계에서 가능한 중복을 제거하고 데이터를 구조화 하는 프로세스 입니다. 
이를 통해 테이터의 일관성, 유지보수, 검색 속도 등을 개선할 수 있습니다.
-- 회원 정보와 회원 등급 정보  1 : 1 관계로 설계 
DROP TABLE IF EXISTS member;
CREATE TABLE `member`(
	id INT PRIMARY KEY AUTO_INCREMENT, 
    name varchar(50) NOT NULL, 
    email VARCHAR(100), 
    address VARCHAR(100)
);

CREATE TABLE member_grade(
	member_id INT PRIMARY KEY, 
    grade VARCHAR(10), 
    point INT,
    FOREIGN KEY(member_id) REFERENCES member(id)
);


-- 직원 정보와 직위 정보를 저장하는 테이블 설계 1 : 1 관계 
 
CREATE TABLE employee(
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL,
    hire_date DATE NOT NULL
);

CREATE TABLE employee_position(
    employee_id INT PRIMARY KEY,
    position VARCHAR(50) NOT NULL,
    dismissal_date DATE,
    FOREIGN KEY (employee_id) REFERENCES employee(id)
);

-- 상품과 상품 상세 정보 1 : 1 관계 설계 
drop table product; 
CREATE TABLE product(
	id INT PRIMARY KEY, 
    name VARCHAR(100) NOT NULL, 
    price INT
);

CREATE TABLE product_detail(
	product_id INT PRIMARY KEY, 
    description TEXT, 
    FOREIGN KEY (product_id) REFERENCES product(id) 
);

'MYSQL' 카테고리의 다른 글

MySQL FUNCTION  (0) 2023.03.16
JOIN 구문  (0) 2023.03.16
1 : N 관계와 INSERT 구문  (0) 2023.03.16
1 : N (One-to-Many Relationship) 차수에 대한 고찰  (0) 2023.03.16
관계 차수  (0) 2023.03.16
FK(외래키)

MySQL에서 FK(외래키)는 다른 테이블의 기본키(primary key)를 참조하여 현재 테이블의 필드를 정의할 때
사용되는 제약 조건입니다. 즉, FK를 사용하여 두 개 이상의 테이블 간에 관계를 설정할 수 있습니다.”

예를 들어 학생 테이블과 학교 테이블이 있다고 가정해보면, 
학교 테이블의 id(school_id) 필드는 primary key로 설정되어 있고, 
학생 테이블의 school_id 필드는 학교 테이블의 id 필드를 참조하는 외래키(FK)로 설정될 수 있습니다.
**이렇게 설정된 외래키 제약 조건을 통해 학생과 학교 간에 1:N 관계를 설정할 수 있습니다.**

부모 테이블과 자식 테이블은 RDBMS에서 테이블 간의 관계를 표현하는 데 사용되는 용어입니다.
부모 테이블은 관계에서 상위에 위치하며, 자식 테이블은 하위에 위치합니다. 
부모 테이블은 일반적으로 자식 테이블에 대한 주요 키(PK)를 가지고 있으며,
자식 테이블은 부모 테이블의 키를 참조하는 외래 키(FK)를 가지고 있습니다.
CREATE TABLE school (
  school_id INT PRIMARY KEY,
  school_name VARCHAR(20) NOT NULL,
  city VARCHAR(20)
);

CREATE TABLE student (
  student_id INT PRIMARY KEY,
  student_name VARCHAR(50) NOT NULL,
  grade VARCHAR(3) NOT NULL, 
  school_id INT,
  FOREIGN KEY (school_id) REFERENCES school (school_id)
);


INSERT INTO school (school_id, school_name, city)
VALUES
  (1, '서울대학교', '서울'),
  (2, '고려대학교', '서울'),
  (3, '연세대학교', '서울'),
  (4, '한양대학교', '서울');
  

  
  
INSERT INTO student (student_id, student_name, grade, school_id)
VALUES
  (1, '홍길동', '1학년', 1),
  (2, '김유신', '2학년', 2),
  (3, '이순신', '1학년', 3),
  (4, '유관순', '3학년', 1),
  (5, '안중근', '2학년', 4),
  (6, '정약용', '3학년', 3),
  (7, '장영실', '1학년', 2),
  (8, '윤봉길', '2학년', 1);  
  
-- ------------------  
select * from school;
select * from student;
  
  
-- FK 관계를 가질 때 잘못된 값 확인해 보기 
INSERT INTO student (student_id, student_name, grade, school_id)
VALUES
  (9, '홍길동', '1학년', 10);  
  
-- 오류가 발생되는 이유는 school_id 컬럼은 외래키이고 
-- 참조 하고 있는 부모 테이블에 PK(school_id 컬럼) 값에 
-- 10이라는 데이터가 없기 때문에 데이터의 무결성을 해치기 때문이다.

야구 팀과 야구 선수 관계 1:N

FK 설정하기 

-- 야구 팀과 야구 선구 관계 1 : N 
create table team (
	id INT primary key auto_increment,
    team_name varchar(50) NOT NULL
); 

create table player (
	player_id int primary key auto_increment,
    paler_name varchar(50) not null, 
    team_id int, 
    foreign key(team_id) references team(id)
);

부서와 직원의 관계 - 1 : N

create table department(
	id int primary key, 
    department_name varchar(50) not null
);

create table employee(
	id int primary key, 
    name varchar(20) not null, 
    department_id int, 
    foreign key(department_id) references department(id) 
);

상품과 주문 목록 관계 - 1 : N

create table department(
	id int primary key, 
    department_name varchar(50) not null
);

create table employee(
	id int primary key, 
    name varchar(20) not null, 
    department_id int, 
    foreign key(department_id) references department(id) 
);

상품과 주문 목록 관계 - 1 : N

create table product(
	id int primary key auto_increment, 
    name varchar(30) not null, 
    price int not null
); 

create table `order`(
	order_id int primary key,  
    order_date DATE NOT NULL, 
    product_id INT, 
    foreign key(product_id) references product(id)
);

'MYSQL' 카테고리의 다른 글

JOIN 구문  (0) 2023.03.16
1 : 1 관계  (0) 2023.03.16
1 : N (One-to-Many Relationship) 차수에 대한 고찰  (0) 2023.03.16
관계 차수  (0) 2023.03.16
요구 분석과 시스템 설계 모델링  (0) 2023.03.15

+ Recent posts