DATABASE (3)

 

 

메인 프로젝트를 진행하면서 ERD를 사용해서 DB를 설계할 때 PK로 id 칼럼을 따로 만들 필요가 없어서 외래키 2개를 묶어서 테이블의 PK로 사용하도록 하는 테이블이 몇가지 있었다.

보통의 테이블에선 PK로 id 칼럼을 만들지만 '다대다' 연관관계에 있는 테이블은 중간에 테이블을 생성해서 '1대다', '다대1' 로 나눠주어야 서로 참조할 수 있기 때문에 중간에 데이터는 안들어가고 두 테이블의 PK만 가지고 있는 테이블이 생겼다.

메인 프로젝트(냥빌리지) ERD 일부

위와 같이 FK 2개만 가지고 테이블을 생성하였기 때문에 두개의 FK를 테이블의 PK로 사용한다.

DB에 테이블 생성할 때는 테이블을 먼저 다 생성한 다음 PK 제약조건으로 'TagToBoard'의 'boardId'와 'boardTagId'를 PK로 만든 후 외래키 제약 조건을 걸어주면 설정이 완료 된다!

 

그런데 Spring에서는 Entity에 PK를 하나밖에 지정하지 못하기 때문에 buid error가 발생한다.

해결 방법으로는 크게 3가지가 있는데 'Spring 복합 PK' 라고 검색하면 자세한 글들이 많다.

그중에 우리팀은 @IdClass 를 이용한 방법을 사용하였다.

사실 이 방법이 가장 간단한것 같다.

 

먼저 PK로 사용할 변수들에 @Id 애너테이션을 붙여준다. (2개 사용하므로 2개에 각각 붙여준다.)

먼저 Id를 묶어줄 Id 클래스를 만들어야 한다. 주로 TagToBoardId 이런식으로 ~Id 라고 지으면 나중에 보기 편하다!

그리고 Serializable을 구현한 구현체로 만들어 준다.

 

그리고 Id 클래스 위에 3가지 애너테이션을 꼭 추가해주어야 한다.

1. @Data

2. @NoArgsConstructor

3. @AllArgsConstructor

Id 클래스의 필드로 TagToBoard의 Id 필드 이름을 그대로 넣어준다.

이때 DB에 실제 저장되는 타입으로 넣어주어야 한다!!

예를 들어 JPA 를 사용하기 때문에 클래스 객체로 참조하였지만 실제 PK에 값은 boardId와 boardTagId값인 Long타입으로 들어갈 거기 때문에 Long 으로 해야한다. 변수명은 동일하게 지어준다.

@Data
@NoArgsConstructor
@AllArgsConstructor
public class TagToBoardId implements Serializable {
    private Long board;
    private Long boardTag;
}

 

그리고 다시 TagToBoard 로 돌아와서 클래스 위에 @IdClass(TagToBoardId.class) 애너테이션을 추가해준다.

@Getter
@Entity(name = "TAG_TO_BOARD")
@NoArgsConstructor
@IdClass(TagToBoardId.class)
public class TagToBoard {
    @Id
    @ManyToOne
    @JoinColumn(name = "BOARD_ID")
    @JsonBackReference
    private Board board;

    @Id
    @ManyToOne
    @JoinColumn(name = "BOARD_TAG_ID")
    @JsonBackReference
    private BoardTag boardTag;
}

이렇게 묶어주면 오류 없이 복합 PK를 사용할 수 있다.

그리고 repository를 JpaRepository를 extends 해서 사용할 경우 id에 보통은 Long 등 숫자 타입이 들어가는데 대신에 생성한 id 클래스명(TagToBoardId)을 작성해주면 된다!

public interface TagToBoardRepository extends JpaRepository<TagToBoard, TagToBoardId> {
}

 

 

 

테이블명이나 칼럼명이 MariaDB 예약어에 등록되어 있으면 생성할 때 오류가 발생한다.

▷ MariaDB 예약어 목록

 

 

ddl auto를 사용하지 않고 DB에서 직접 테이블을 생성하다보면 제약조건이 꼬이거나 하는 문제가 발생할 수 있다.

이때 제약조건을 확인할 수 있는 쿼리문이 있어서 같이 올려놓는다.

모든 제약조건 확인하는 쿼리

SELECT *
FROM information_schema.table_constraints;

 

 

 

'DATABASE' 카테고리의 다른 글

[MySQL] 데이터베이스 테이블 생성 후 column 속성 변경  (0) 2022.09.06
[MySQL] 유용한 쿼리문  (2) 2022.09.03

 

 

 

 

이미 테이블을 생성한 이후 칼럼의 속성을 변경하려는 경우 문법이 헷갈릴 수 있다.

그래서 테이블 생성 후에 칼럼을 추가하거나 속성 변경, 외래키 등 추가하는 문법을 정리해 놓는다.

 

☑️ MySQL에서 명령어는 대소문자 구분이 없기 때문에 소문자로 작성해도 된다.

 

 

🐙 column 추가하기

ALTER TABLE [table명] ADD [column명] [자료형];

 

 

🐙 column에 not null 속성 부여하기

ALTER TABLE [table명] MODIFY [column명] [자료형] NOT NULL;

☑️ 'NULL' 로 변경하고 싶다면 'NOT NULL' 부분을 지우면 된다.

☑️ 자료형을 바꾸고 싶다면 [자료형]에 바꾸고 싶은 자료형을 입력한다.

 

 

🐙 column에 unique 속성 부여하기(Unique key)

ALTER TABLE [table명] MODIFY [column명] [자료형] UNIQUE;

☑️ MySQL에는 Unique key(UNI), Primary key(PRI), Multiple key(MUL) 이렇게 총 3종류의 key가 있는데 unique 키는 중복성이 허용되지 않지만 null에 대한 허용이 가능하다. unique 속성을 부여하면 table key에 'UNI'라고 적혀있다.

☑️ 만약에 key가 uni, pri, mul 중 여러개에 해당된다면 PRI < UNI < MUL 순의 우선순위로 출력된다.

 

 

🐙 column 이름 변경

ALTER TABLE [table명] CHANGE [기존column명] [변경할column명] [자료형];

 

 

🐙 column 삭제하기

ALTER TABLE [table명] DROP COLUMN [column명];

 

 

🐙 column default 값 변경하기

ALTER TABLE [table명] COLUMN [column명] SET DEFAULT [디폴트값];

 

 

🐙 column에 값 자동 증가(auto_increment) 설정하기

ALTER TABLE [table명] MODIFY [column명] [자료형] AUTO_INCREMENT;

 

 

🐙 column에 auto_increment 값 초기화 하기

ALTER TABLE [table명] AUTO_INCREMENT=[초기화 후 시작숫자];

 

 

🐙 column 순서 변경하기

ALTER TABLE [talbe명] MODIFY [순서바꿀column명] [자료형] AFTER [앞에오는column명];

 

 

🐙 column에 외래키(FK) 부여하기

ALTER TABLE [table명] ADD FOREIGN KEY([column명]) REFERENCES [참조table명]([참조column명]);
ALTER TABLE USER ADD FOREIGN KEY(ORDER_ID) REFERENCES ORDER;

// 제약조건 부여하기
ALTER TABLE [table명] ADD CONSTRAINT [제약조건명] FOREIGN KEY([column명])
REFERENCES [참조table명]([참조column명]);

☑️ 두번째 줄에 작성한 것과 같이 해당 테이블에 PK가 하나밖에 없는 경우는 참조칼럼은 생략가능하다.

☑️ MySQL 결과에선 FK는 'MUL'로 나온다. (MUL은 보통은 외래키이다. 논유니크 인덱스(중복 가능)의 첫번째 칼럼을 나타낸다.)

 

 

 

 

'DATABASE' 카테고리의 다른 글

[MariaDB/MySQL] JPA Foreign Key 2개를 Primary Key로 사용하기  (0) 2022.10.01
[MySQL] 유용한 쿼리문  (2) 2022.09.03

 

 

 

▶️ 테이블 DROP

 

테이블 삭제 시 외래키 제약 조건이 걸려 있다면 그대로 삭제하려하면 외래키로 등록되어 있는 테이블 먼저 삭제하라는 에러가 발생한다.

그래서 테이블 삭제 시 먼저 외래키 제약 조건을 확인할 필요가 없도록 설정을 바꿔줘야 한다.

SET FOREIGN_KEY_CHECKS = 0;

이제 테이블을 삭제해준다.

DROP TABLE [talbe명];

삭제할 테이블을 모두 삭제했다면 다시 외래키 제약 조건 확인을 기본값으로 돌려놓는다.

SET FOREIGN_KEY_CHECKS = 1;

 

 

 

▶️ Query 결과 예쁘게 출력하기

 

터미널같은 CLI 환경에서 쿼리문으로 데이터를 조회하면 칼럼이 여러개인 경우나 데이터가 길게 나오면 보기가 불편하다.

이럴때는 쿼리문 마지막에 세미콜론(;) 대신 \G 를 입력하면 쿼리 결과가 예쁘게 출력되서 보기 편하다!

SELECT * FROM [table명]\G

실행 결과

 

 

 

 

 

 

 

오개념, 오타에 대한 지적은 언제나 환영입니다~ 😄

1