๐ ๊ธฐ์กด ์ํฉ
๋๋ฉ์ธ
์ฐ๋ฆฌ ๊ฐ๊ณ๋ถ์์ ํ๋์ ๊ฐ๊ณ๋ถ ๋ด์ญ์ ์ง์ถ/์์ /์ด์ฒด๋ก ๊ตฌ๋ถ๋๊ณ , ์์ฐ๊ณผ ๋ถ๋ฅ ํญ๋ชฉ์ผ๋ก ์ธ๋ถ์ ์ผ๋ก ๋ค์ ๊ตฌ๋ถ๋๋ค.
์ด ์ธ ๊ฐ์ง๋ฅผ ํธ์์ ์นดํ ๊ณ ๋ฆฌ๋ก ํต์นญํ๋ค.
- ์ง์ถ/์์ /์ด์ฒด (์ดํ ์์ ์นดํ ๊ณ ๋ฆฌ๋ผ ์นญํจ): ๊ฐ๊ณ๋ถ ๋ด์ญ์ ์ข ๋ฅ
- ๋ถ๋ฅ (์ดํ ํ์ ์นดํ ๊ณ ๋ฆฌ๋ผ ์นญํจ): ์ ์ง์ถ/์์ /์ด์ฒด์ ํ์ ๋ถ๋ฅ (ex. ์๋น, ์๊ธ ๋ฑ)
- ์์ฐ (์ดํ ํ์ ์์ฐ ์นดํ ๊ณ ๋ฆฌ๋ผ ์นญํจ): ๊ฐ๊ณ๋ถ ๋ด์ญ์ ์์ฐ ์ถ์ฒ (ex. ํ๊ธ, ์นด๋ ๋ฑ)
์ด๋ฅผ ๊ณ์ธต์ ์ผ๋ก ์ ๋ฆฌํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
์ด ์นดํ ๊ณ ๋ฆฌ๋ค์ ๊ฐ๊ณ๋ถ ๋ณ๋ก ๊ด๋ฆฌ๋๋ค.
์ด ๋ ํ์ ์นดํ ๊ณ ๋ฆฌ๋ ๊ฐ๊ณ๋ถ ์์ฑ ์ ๊ธฐ๋ณธ์ ์ผ๋ก N๊ฐ๊ฐ ์ฃผ์ด์ง๋ค. ์ด๋ฅผ ๊ธฐ๋ณธ ์นดํ ๊ณ ๋ฆฌ๋ผ๊ณ ๋ถ๋ฅด๊ฒ ๋ค. ๊ธฐ๋ณธ ์นดํ ๊ณ ๋ฆฌ๋ ์ฌ์ฉ์๊ฐ ์์๋ก ์ญ์ ๋ฐ ์์ ์ ํ ์ ์๋ค. ์ ํ๋ฉด์ ๋ณด์ด๋ ์์ฐ์ ํ๊ธ~์ํ ํ์ ์นดํ ๊ณ ๋ฆฌ๊ฐ ๊ทธ๋ฌํ๋ค.
๋ค๋ง ์ฌ์ฉ์๊ฐ ์ง์ ์นดํ ๊ณ ๋ฆฌ๋ฅผ ์ถ๊ฐํ ์ ์๋ค. ์ด๋ฅผ ์ปค์คํ ์นดํ ๊ณ ๋ฆฌ๋ผ๊ณ ๋ถ๋ฅด๊ฒ ๋ค. ํ๋ฉด์ ์ถ๊ฐํญ๋ชฉ1 ํ์ ์นดํ ๊ณ ๋ฆฌ๊ฐ ๊ทธ๋ฌํ๋ค.
๊ตฌํ
๋์ ์๋ฒ๋ฅผ ๋ด๋นํ๋ ํ์ ๋ถ์ ์ด ๋๋ฉ์ธ์ ๊ตฌํํ๊ธฐ ์ํด ์ฌ๋ฌ ๊ณ ๋ฏผ์ ํ๊ณ (๊ทธ ๋์ ๊ณ ๋ฏผ ๊ณผ์ ์ ์ด ํฌ์คํ ์์ ํ์ธํ ์ ์๋ค), ์ต์ข ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํํ๋ค.
โ ์นดํ ๊ณ ๋ฆฌ
@Inheritance(strategy = SINGLE_TABLE)
public abstract class Category {
@Column
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
private Category parent;
}
// ์์ ์นดํ
๊ณ ๋ฆฌ
@DiscriminatorValue("DefaultRoot")
public class RootCategory extends Category {
}
// ๊ธฐ๋ณธ ํ์ ์นดํ
๊ณ ๋ฆฌ
@DiscriminatorValue("Default")
public class DefaultCategory extends Category {
}
// ์ปค์คํ
ํ์ ์นดํ
๊ณ ๋ฆฌ
@DiscriminatorValue("Book")
public class BookCategory extends Category {
@ManyToOne
private Book book;
}
๊ธฐ๋ณธ์ ์ผ๋ก ์นดํ ๊ณ ๋ฆฌ๋ผ๋ ๋๋ฉ์ธ์ ์ํด ์๊ธฐ ๋๋ฌธ์ Category ์ถ์ ํด๋์ค๋ฅผ ์์ฑํ๋ค. ๊ทธ๋ฆฌ๊ณ ์์ ์นดํ ๊ณ ๋ฆฌ, ํ์ ๊ธฐ๋ณธ ์นดํ ๊ณ ๋ฆฌ, ํ์ ์ปค์คํ ์นดํ ๊ณ ๋ฆฌ๋ฅผ ์์(@Inheritance)์ ์ด์ฉํด ๊ฐ๊ฐ์ ๊ฐ์ฒด๋ก ๋๋ด๋ค.
id | dtype | name | parent_id | book_id |
1 | DefaultRoot | ์ง์ถ | null | null |
2 | Default | ์๋น | 1 | null |
3 | Book | ๋ด๊ฐ ๋ง๋ ์นดํ ๊ณ ๋ฆฌ | 1 | 1 |
์์ ์ ๋ต์ SINGLE_TABLE ์ ์ฌ์ฉํ๋ค. ๋ฐ๋ผ์ ์ธ ๊ฐ์ Category ๊ฐ์ฒด๊ฐ DB์์ ํ๋์ ํ ์ด๋ธ์ ์ ์ฅ๋๋ค. ๋์ ๊ฐ ๊ฐ์ฒด๋ dType์ผ๋ก ๊ตฌ๋ถ๋๋ค.
โ ๊ฐ๊ณ๋ถ ๋ด์ญ - ์นดํ ๊ณ ๋ฆฌ ์ฐ๊ฒฐ
ํ๋์ ๊ฐ๊ณ๋ถ ๋ด์ญ์ ์ธ ๊ฐ์ ์นดํ ๊ณ ๋ฆฌ๋ฅผ ์ฐธ์กฐํ๋ค. ํ๋์ ์นดํ ๊ณ ๋ฆฌ๋ ์ฌ๋ฌ ๊ฐ๊ณ๋ถ ๋ด์ญ๋ค์ ์ฐธ์กฐํ๋ค.
์๋ก๊ฐ ๋ค๋๋ค ๊ด๊ณ๋ฅผ ๋งบ๊ณ ์์ผ๋ฏ๋ก DB์์ ๋ ํ ์ด๋ธ์ ์ฐธ์กฐํ๋ ์ฐ๊ฒฐ ํ ์ด๋ธ์ ์์ฑํ๋ค. ์ด ๋ ๋ด์ญ์ด ์ฐธ์กฐํ๋ ์ธ ๊ฐ์ ์นดํ ๊ณ ๋ฆฌ๋ ๊ฐ์ ์์ ์ ์์ฑ์ด ์์ผ๋ฏ๋ก, ์ด๋ฅผ category_type ์ปฌ๋ผ์ผ๋ก ๊ตฌ๋ถํ๋ค.
id | book_id (์ฐ๊ฒฐ ๊ฐ๊ณ๋ถ) | category_id (์ฐ๊ฒฐ ์นดํ ๊ณ ๋ฆฌ) | category_type (์นดํ ๊ณ ๋ฆฌ ์ข ๋ฅ) |
1 | 1 | 1 | FLOW (์์ ์นดํ ๊ณ ๋ฆฌ - ์ง/์/์ด) |
2 | 1 | 2 | ASSET (์์ฐ ํ์ ์นดํ ๊ณ ๋ฆฌ) |
3 | 1 | 3 | FLOW_LINE (ํ์ ์นดํ ๊ณ ๋ฆฌ) |
์ดํ๋ฆฌ์ผ์ด์ ์์๋ ๊ฐ๊ณ๋ถ ๋ด์ญ์ด EnumMap์ผ๋ก ์ธ ๊ฐ์ ์นดํ ๊ณ ๋ฆฌ ์ฐ๊ฒฐ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๋ค. ๋ด์ญ์ ์กฐํํ ๋ ๊ฑฐ์ ์ฐ๊ด ์นดํ ๊ณ ๋ฆฌ๊น์ง ์กฐํํ๊ณ , ๋ ผ๋ฆฌ์ ์ผ๋ก๋ ๋ด์ญ์ ์นดํ ๊ณ ๋ฆฌ ์ ๋ณด๊ฐ ํฌํจ๋๋ค๊ณ ํ๋จํ๋ค.
// ๊ฐ๊ณ๋ถ ๋ด์ญ
@Entity
public class BookLine {
@OneToMany(fetch = FetchType.LAZY, mappedBy = "bookLine")
@MapKeyEnumerated(EnumType.STRING)
private final Map<CategoryEnum, BookLineCategory> bookLineCategories = new EnumMap<>(CategoryEnum.class);
}
// ํ ๊ฐ๊ณ๋ถ ๋ด์ญ๊ณผ ์ฐ๊ด๋ ์นดํ
๊ณ ๋ฆฌ ์ข
๋ฅ
public enum CategoryEnum {
FLOW,
ASSET,
FLOW_LINE;
}
๐ฉ ๋ณํ๊ฐ ํ์ํ๋ค
์ดํ ์ฌ๋ฌ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ฉด์ ๊ธฐ์กด ์ค๊ณ ๋ฐ ์ฝ๋์ ๋ํด ๋ง์ ๋ถํธํจ์ ๋๊ผ๋ค.
QueryDSL์ projection
๊ฐ๊ณ๋ถ ๋ด์ญ์ ์กฐํํ ๋ ์ฐ๊ด๋ ์นดํ ๊ณ ๋ฆฌ๋ค์ JOIN ํ๋ฉด ์ผ๋๋ค๋ก ์ฐธ์กฐํ bookLineCategories ์ ์๋ง๊ฒ ์ฐ๊ฒฐ๋๋ค.
// QueryDSL ์ฌ์ฉ
public BookLine getBookLine() {
return jpaQueryFactory.from(bookLine)
.innerJoin(bookLine.bookLineCategories, bookLineCategory)
.fetchOne();
}
๋ฌธ์ ๋ QueryProjection, ์ฆ ์กฐํ์ฉ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ๋๋ค.
// QueryProjection ์ฌ์ฉ
public CustomBookLine getBookLine() {
return jpaQueryFactory
.select(new QCustomBookLine(bookLineCategory.name)) // X
.from(bookLine)
.innerJoin(bookLine.bookLineCategories, bookLineCategory)
.fetchOne();
}
ํ๋์ ๊ฐ๊ณ๋ถ ๋ด์ญ์ ์ธ ๊ฐ์ ์นดํ ๊ณ ๋ฆฌ๊ฐ ์ฐ๊ฒฐ๋ ๋ ์ด ์ ๋ณด๋ฅผ bookLineCategories ๋ก ๋ชจ์ผ์ง ์์ผ๋ฏ๋ก ๊ฐ๊ฐ ๋ฐ๋ก ์กฐํ๋๋ค.
๋น์์๋ ๋ง๋ ํ ํด๊ฒฐ์ฑ ์ ๋ชป ์ฐพ์ 3๊ฐ์ ํ์ ๋ฐ๋ก ๋ถ๋ฌ์ค๋, ์ดํ๋ฆฌ์ผ์ด์ ์์ ์ง์ ํฉ์ณ์คฌ๋ค.
// ์ ์ฝ์ด๋ ๋จ
// ๊ฐ๊ณ๋ถ ๋ด์ญ์ ์ฌ๋ฌ ๊ฐ์ ์นดํ
๊ณ ๋ฆฌ๋ฅผ ํ๋์ ๊ฐ์ฒด๋ก ํฉ์น๋ ํจ์
public List<DayLines> transfer(List<CustomBookLine> dayLines) {
Map<Long, DayLineInfo> dayLineWithCategories = new HashMap<>();
dayLines.forEach((dayLine) ->
{
DayLineInfo dayLineInfo = dayLineWithCategories.get(dayLine.getId());
// ์นดํ
๊ณ ๋ฆฌ ์ธ์ ๋ฐ์ดํฐ ์ต์ด ๋ฑ๋ก
if (dayLineInfo == null) {
dayLineWithCategories.put(dayLine.getId(), DayLineInfo.toDayViewInfos(dayLine));
} else {
dayLineInfo.addCategory(dayLine.getCategories());
}
});
return;
}
๋์ถฉ ๋ด๋ ๋ณต์กํ๋ค.
SINGLE_TABLE ์์ ์ ๋ต๊ณผ ์ ๋ํฌ ์ธ๋ฑ์ค
DB์ Category ํ ์ด๋ธ์ ๋ค์๊ณผ ๊ฐ์ด dtype ์ผ๋ก ์นดํ ๊ณ ๋ฆฌ๋ฅผ ๊ตฌ๋ณํ๋ค.
id | dtype | name | parent_id | book_id |
1 | DefaultRoot | ์ง์ถ | null | null |
2 | Default | ์๋น | 1 | null |
3 | Book | ๋ด๊ฐ ๋ง๋ ์นดํ ๊ณ ๋ฆฌ | 1 | 1 |
์ด ๋ dtype ์ ๋ฐ๋ผ constraints ๋ ๋ฌ๋ผ์ง๋ค.
DefaultRoot ๋ ์์ ์นดํ ๊ณ ๋ฆฌ๋ฉฐ ๋ชจ๋ ๊ฐ๊ณ๋ถ๊ฐ ๊ณต์ ํ๋ค. ๋ฐ๋ผ์ parent_id ์ book_id ๊ฐ ๋ชจ๋ null ์ด๋ค.
Default ๋ ๊ธฐ๋ณธ ํ์ ์นดํ ๊ณ ๋ฆฌ๋ผ ๋ชจ๋ ๊ฐ๊ณ๋ถ๊ฐ ๊ณต์ ํ๋ค. ๋ฐ๋ผ์ book_id ๊ฐ null ์ด๋ค.
Book ์ ์ปค์คํ ํ์ ์นดํ ๊ณ ๋ฆฌ๋ผ ๊ฐ๊ณ๋ถ ๋ง๋ค ์์ฑ ๊ฐ๋ฅํ๋ค. ๋ฐ๋ผ์ ๋ชจ๋ ์ปฌ๋ผ์ null ์ด ํ์ฉ๋์ง ์๋๋ค.
๋ ผ๋ฆฌ์ ์ผ๋ก๋ ์์ ๊ฐ์ง๋ง, ๋ชจ๋ ํ๋์ ํ ์ด๋ธ์ ์ฌ์ฉํ๋ฏ๋ก parent_id ์ book_id ๋ null ์ ๋ฌด์กฐ๊ฑด ํ์ฉํด์ผ ํ๋ค.
์ด ๋ ๋๋ฉ์ธ ์ ์ปค์คํ ์นดํ ๊ณ ๋ฆฌ๋ (์ด๋ฆ, ๊ฐ๊ณ๋ถ, ์์ ์นดํ ๊ณ ๋ฆฌ) ์กฐํฉ์ด ์ ์ผํ๋ค. ๊ธฐ๋ณธ ์นดํ ๊ณ ๋ฆฌ์๋ ์ด๋ฆ์ด ๊ฒน์น๋ฉด ์ ๋๋ค.
์ฆ ์ฌ๊ธฐ์ ์์ฐ์ ๋ถ๋ฅ ํญ๋ชฉ์ ์ถ๊ฐํ ๋ ํ๊ธ๋ถํฐ ์ถ๊ฐํญ๋ชฉ1 ๊น์ง ์ด๋ฆ์ด ๊ฒน์น๋ฉด ์ ๋๋ค.
์ด๋ฅผ ์ดํ๋ฆฌ์ผ์ด์ ์์ ์กฐ๊ฑด์ ๋ง๋ ํ์ ์นดํ ๊ณ ๋ฆฌ๋ฅผ ๋จผ์ ์กฐํํ๊ณ , ์์ผ๋ฉด ์์ธ๋ฅผ ๋์ง๊ณ ์์ผ๋ฉด ์ถ๊ฐํ๋ ๋ฐฉ์์ผ๋ก ๊ตฌํํ๋ค.

...๋ญ๊ฐ ์ต์ํ ๋ฐฉ์์ด๋ค.
๋ง๋ค. ์์ฐ ์ด์์์ ๋๊ฐ์ด '์กฐํ ํ ๋ฐ์ดํฐ ์ฝ์ '์ ํ๋ค๊ฐ ๋์์ฑ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์๋ค.
์ด ๋ ํด๋น ์ด์์์๋ MySQL์ upsert ๋ฌธ๋ฒ(INSERT ... ON DUPLICATE KEY UPDATE)์ ์ฌ์ฉํ Atomic Query๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค. ๊ทธ๋์ ๋๊ฐ์ด ์ ์ฉํ๋ ค๊ณ ํ์ผ๋, ์ํ๊น๊ฒ๋ MySQL์์๋ ํน์ ์ปฌ๋ผ์ null ๊ฐ์ด ํฌํจ๋๋ฉด unique index๊ฐ ์๋๋๋ก ์๋ํ์ง ์๋๋ค. MySQL์์ null์ '์ ์ ์๋ ๊ฐ'์ผ๋ก ์ทจ๊ธ๋๊ธฐ ๋๋ฌธ์ด๋ค.
The concept of the NULL value is a common source of confusion for newcomers to SQL, who often think that NULL is the same thing as an empty string ''. This is not the case.
Conceptually, NULL means “a missing unknown value” and it is treated somewhat differently from other values.
NULL ๊ฐ์ ๊ฐ๋ ์ SQL์ ์ฒ์ ์ ํ๋ ์ฌ๋๋ค์ด ํํ ํผ๋ํ๋ ๋ถ๋ถ์ผ๋ก, NULL์ด ๋น ๋ฌธ์์ด ''๊ณผ ๊ฐ์ ์๋ฏธ๋ผ๊ณ ์๊ฐํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ผ๋ ๊ทธ๋ ์ง ์๋ค. ๊ฐ๋ ์ ์ผ๋ก NULL์ "์ ์ ์๋ ๋๋ฝ๋ ๊ฐ"์ ์๋ฏธํ๋ฉฐ ๋ค๋ฅธ ๊ฐ๊ณผ ๋ค์ ๋ค๋ฅด๊ฒ ์ทจ๊ธ๋๋ค.
- MySQL 8.0 references ์ค
๋ฐ๋ผ์ nullable ์ปฌ๋ผ์ unique ์ ์ฝ ์กฐ๊ฑด์ ์ถ๊ฐํ๋ ๊ฒฝ์ฐ null ๊ฐ์ธ ํ์ ์ฌ๋ฌ ๊ฐ๊ฐ ๋ ์ ์๋ค. ๊ธฐ์กด์ null ๊ฐ๊ณผ ์๋ก ์ถ๊ฐ๋ null ๊ฐ์ด ๊ฐ๋ค๊ณ ํ๋จํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
Atomic Query๋ก ๋์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ผ๋ฉด ์ํฉ์ด ๋ณต์กํด์ง๋ค. MySQL์ Named Lock ํน์ Redis ๋ฝ ๋ฑ์ ์ฌ์ฉํด์ผ ํ๋ค. ๊ณ ์ ์นดํ ๊ณ ๋ฆฌ ์ค๋ณต ๋ฐฉ์ง์ ์ด๋งํ ์๊ฐ์ ๋ค์ฌ์ผํ๋ ์ถ์ด์ง๋ค.
๋ ์ข ๋ฅ์ ํ์ ์นดํ ๊ณ ๋ฆฌ - ๊ธฐ๋ณธ๊ณผ ์ปค์คํ
ํ์ ์นดํ ๊ณ ๋ฆฌ๋ ํน์ฑ์ ๋ฐ๋ผ ๋ค์ ๊ธฐ๋ณธ๊ณผ ์ปค์คํ ์นดํ ๊ณ ๋ฆฌ๋ก ๋๋๋ค. ์ด๋ฅผ ์ดํ๋ฆฌ์ผ์ด์ ์์๋ ๊ฐ๊ฐ์ ๊ฐ์ฒด(DefaultCategory, BookCategory)๋ก ๊ตฌ๋ถํ๋ค.
ํ์ง๋ง ๋๋ถ๋ถ์ ์กฐํ ์ฟผ๋ฆฌ์์ ๊ทธ ๋์ ๊ตฌ๋ถํ์ง ์๊ณ ์กฐํํ๋ค. ํ์ ์นดํ ๊ณ ๋ฆฌ๋ฅผ ์์ฑํ ์ด์, ํด๋น ์นดํ ๊ณ ๋ฆฌ๋ฅผ ์กฐํํ ๋๋ ๋์ ๊ตฌ๋ณํ๋ ๊ฒ ๋ฌด์๋ฏธํ๊ธฐ ๋๋ฌธ์ด๋ค. ํ์ง๋ง ๊ฐ์ฒด๋ก๋ ์์ฐํ ๊ตฌ๋ถ๋์ด ์๊ณ ์กฐ๊ฑด๋ ๋ค๋ฅด๊ฒ ์ฃผ์ด์ผ ํ๋ฏ๋ก ์ฟผ๋ฆฌ๋ฅผ ๋ ๋ฒ ๋ ๋ ค์ผ ํ๋ค. ๋ถํธํ๋ค.
public Optional<Category> findFlowLineCategory() {
// ๊ธฐ๋ณธ ์นดํ
๊ณ ๋ฆฌ ๋จผ์ ์กฐํ
Optional<Category> target = Optional.ofNullable(jpaQueryFactory.selectFrom(category)
.where(
category.name.eq(name),
category.parent.eq(parentFlowCategory),
category.instanceOf(DefaultCategory.class)
)
.fetchOne());
// ๊ธฐ๋ณธ ์นดํ
๊ณ ๋ฆฌ์์ ์ํ๋ ์นดํ
๊ณ ๋ฆฌ๋ฅผ ์ฐพ์ง ๋ชปํ ๊ฒฝ์ฐ, ์ปค์คํ
์นดํ
๊ณ ๋ฆฌ ์กฐํ
if (target.isEmpty()) {
target = Optional.ofNullable(jpaQueryFactory
.selectFrom(bookCategory)
.innerJoin(bookCategory.book, book)
.where(
book.bookKey.eq(bookKey),
bookCategory.name.eq(name),
bookCategory.parent.eq(parentFlowCategory),
)
.fetchOne());
}
return target;
}
๋๋ฉ์ธ ์ฉ์ด
์ธ์๋ ์ฝ๋ ๋ด์ ์ฐ์ธ ์ฉ์ด๋ค์ด ํท๊ฐ๋ฆฌ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์๋ค. ํ๊ธ๋ก ๋ ๋๋ฉ์ธ ์ฉ์ด๋ฅผ ์์ด๋ก ๋ฒ์ญํ๋ ๊ณผ์ ์์ ๋ค๋ฅธ ์ฉ์ด์ ๊ฒน์น๋ ๊ฒฝ์ฐ๋ ์์๊ณ , ์ด๋ฆ๋ง ๋ดค์ ๋ ๋ฌด์จ ๋๋ฉ์ธ์ธ์ง ํท๊ฐ๋ฆฌ๋ ๊ฒฝ์ฐ๋ ์์๋ค.
์๋ฅผ ๋ค์ด ๊ฐ๊ณ๋ถ ๋ด์ญ๊ณผ ๊ด๋ จ๋ ์นดํ ๊ณ ๋ฆฌ๋ฅผ ๊ด๋ฆฌํ๋ CategoryEnum ์ด ์์๋ค.
// ํ ๊ฐ๊ณ๋ถ ๋ด์ญ๊ณผ ์ฐ๊ด๋ ์นดํ
๊ณ ๋ฆฌ ์ข
๋ฅ
public enum CategoryEnum {
FLOW("๋ด์ญ"),
ASSET("์์ฐ"),
FLOW_LINE("๋ด์ญ ๋ถ๋ฅ");
}
์ฌ๊ธฐ์๋ FLOW ๊ฐ ๋ด์ญ์ด๋ค. ํ์ง๋ง ๊ฐ๊ณ๋ถ ๋ด์ญ์ Book'Line' ์ด๋ค.
๋ ์ด ๊ฐ์ฒด์ ASSET ์ ์์ฐ ๋ถ๋ฅ ํญ๋ชฉ์ ์๋ฏธํ๋ค. ํ์ง๋ง ์ฐ๋ฆฌ๋ ๊ฐ๊ณ๋ถ ์์ ๋ฐ ์ง์ถ ๋ด์ญ์ผ๋ก ๊ณ์ฐํ๋ ์์ฐ ๋๋ฉ์ธ์ด ๋ฐ๋ก ์๊ณ , DB์์ asset ํ ์ด๋ธ์ ์ ์ฅํ๋ค.
์ด๋ ๊ฒ ์ฉ์ด๊ฐ ํท๊ฐ๋ฆฌ๋ ๊ฒ ๊ฐ๋ฐํ๋ฉด์ ์๊ฐ๋ณด๋ค ํฐ ์ฅ์ ๋ฌผ์ด ๋์๋ค.
๐ฆ ์ฌ์ค๊ณ
๊ณ ๋ ค์ฌํญ
๊ทธ๋์ ๊ฒช์ ๋ถํธํจ์ ๋ฐํ์ผ๋ก ์๊ธด ์กฐ๊ฑด์ ๋ค์๊ณผ ๊ฐ๋ค.
- ๊ธฐ๋ณธ ํ์ ์นดํ ๊ณ ๋ฆฌ์ ์ปค์คํ ํ์ ์นดํ ๊ณ ๋ฆฌ๋ ์กฐํ๋ ๋ ํ๋๋ก ์ทจ๊ธ๋์ด์ผ ํ๋ค.
- ํ๋์ ํ ์ด๋ธ๋ก ๋ฌถ์ธ ์นดํ ๊ณ ๋ฆฌ๋ค์ ๋๋์ด ์ ๋ํฌ ์ธ๋ฑ์ค๋ฅผ ์ถ๊ฐํ๋ค.
- ํ๋์ ๊ฐ๊ณ๋ถ ๋ด์ญ์ ์ฐธ์กฐํ๋ ์ธ ๊ฐ์ ์นดํ ๊ณ ๋ฆฌ ์ฐ๊ฒฐ ๋ฐ์ดํฐ๋ ํ๋๋ก ๋ฌถ๋๋ค.
- ๋ณ๊ฒฝํ๋ ๊น์ ์ฉ์ด๋ค ๋ํ ๊ฐ๋ ์ฑ ์ข๊ฒ ์์ ํ๋ค.
๋ง์นจ ๊ธฐ๋ณธ ์นดํ ๊ณ ๋ฆฌ๋ ํธ์งํ๊ฒ ํด๋ฌ๋ผ๋ ์์ฒญ์ด ๋ง์์ ธ ์ปค์คํ ์นดํ ๊ณ ๋ฆฌ์ ๋๊ฐ์ด ํธ์ง์ด ๊ฐ๋ฅํ๋๋ก ๊ธฐํ์ด ์ถ๊ฐ๋์๋ค. ๋ฐ๋ผ์ ์ฒซ ๋ฒ์งธ ์กฐ๊ฑด์ ํด๊ฒฐํ ์ ์๊ฒ ๋์๋ค.
๋ ์ฌ๋ฌ ๊ณ ๋ฏผ ๋์ ์ดํ๋ฆฌ์ผ์ด์ ์์ ์นดํ ๊ณ ๋ฆฌ ๊ฐ์ ์์ ๊ด๊ณ๋ฅผ ์์ ๊ธฐ๋ก ํ๋ค. ์ฐ๋ฆฌ๋ ๋ ๋ฒ์งธ ์กฐ๊ฑด์ ์ํด ์์ ์ ๋ต ์ค TABLE_PER_CLASS ๋ฅผ ์ฌ์ฉํ๊ณ ์ถ์๋ค. ํ์ง๋ง ์ด ์ ๋ต๊ณผ ์๋ณ์(id) ์์ฑ ๋ฐฉ์ ์ค IDENTITY ๋ฅผ ๊ฐ์ด ์ฌ์ฉํ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค(์ฐธ๊ณ ). ๋ ผ๋ฆฌ์ ์ผ๋ก๋ ๊ตณ์ด ๊ฐ ์ํฐํฐ๋ค์ด ๋ฌถ์ฌ ์์ ํ์๊ฐ ์๋ค๊ณ ํ๋จํ๋ค.
์ต์ข ์ค๊ณ
๊ณ ๋ฏผ ๋์ ๋ค์๊ณผ ๊ฐ์ ์ค๊ณ๋ฅผ ์์ฑํ๋ค.
โ ์นดํ ๊ณ ๋ฆฌ
- Category ํ ์ด๋ธ: ์์ ์นดํ ๊ณ ๋ฆฌ (์ง์ถ/์์ /์ด์ฒด/์์ฐ)
- Subcategory ํ ์ด๋ธ: ํ์ ์นดํ ๊ณ ๋ฆฌ
- DefaultSubcategory ํ
์ด๋ธ: ๊ธฐ๋ณธ ํ์ ์นดํ
๊ณ ๋ฆฌ
(๊ฐ๊ณ๋ถ๋ฅผ ์์ฑํ ๋๋ง ํด๋น ํ ์ด๋ธ์ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ Subcategory ๋ฐ์ดํฐ๋ก ์ ์ฅํ๋ค.)
โ ๊ฐ๊ณ๋ถ ๋ด์ญ-์นดํ ๊ณ ๋ฆฌ
์ธ ๊ฐ์ ์นดํ ๊ณ ๋ฆฌ๋ฅผ ์ธ ๊ฐ์ ํ์ผ๋ก ์ ์ฅํ์ง ์๊ณ , ์ธ ๊ฐ์ column ์ ํตํด ํ๋์ ํ์ผ๋ก ์ ์ฅํ๋ค.
๐ง ํ ์คํธ ์๋ ๋ฆฌํฉํ ๋ง
์ค๊ณ๋ ์์ฑํ๋ค. ์ด์ ๊ตฌํ์ด ํ์ํ๋ค.
๊ธฐ์กด ์ํฉ
์ํ๊น๊ฒ๋ ์ถ์ ์ผ์ ์ ์น์ฌ ๊ฐ๋ฐํ๋๋ผ ํ ์คํธ๊ฐ ๋งค์ฐ ๋ถ์กฑํ๋ค. ๋ ์ํ๊น์ด ์ ์ ๊ทธ ์ ์ ํ ์คํธ๋ ๋ชจ๋ ๋จ์ ํ ์คํธ๋ผ, ๊ฐ์ฒด ์์ฒด๊ฐ ๋ณํ๋ฉด์ ๋จ์ ํ ์คํธ๋ค์ด ๋ชจ๋ ์ฌ๋ผ์ ธ์ผํ๋ค. ๊ทธ๋์ ํ ์คํธ๊ฐ ์๋ ๋ฆฌํฉํ ๋ง์ ์งํํด์ผ ํ๋ค.
๋ํ ๊ฐ๊ณ๋ถ ๋ด์ญ๊ณผ ์นดํ ๊ณ ๋ฆฌ๋ ๋งค์ฐ ๋น์ค์ด ๋์ ํ์ ๋๋ฉ์ธ์ด๋ผ ํ๋ก๋์ ์ฝ๋์ ๋๋ถ๋ถ์ด ๋ฐ๋์๋ค.
์ฐ๋ฆฌ๋ ๋ฆฌํฉํ ๋ง ์ค ํน์ฌ๋ ์๋ชป ๋ณ๊ฒฝํ ์ฝ๋๊ฐ ์์ ์ง ๋งค์ฐ ๋ถ์ํ๋ค. ์ด๋ฏธ ํ ์คํธ ์์ด ๊ธํ๊ฒ ์ค๋ฅ๋ฅผ ์์ ํ๋ค๊ฐ ๋ฐค์ ์๋ฉฐ ์ด์ ๋ฐ์ดํฐ๋ฅผ ์์ ํ ์ ์ ์ด ์๊ธฐ ๋๋ฌธ์ด๋ค.
๊ทธ๋์ ์๊ฐ์ด ๊ฑธ๋ฆฌ๋๋ผ๋ ํ ์คํธ๋ฅผ ์ต๋ํ ์ถ๊ฐํ๊ธฐ๋ก ํ๋ค.
DCI ํจํด ๋์
๊ธฐ์กด์ ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ๋ฉด์ ๋ถํธํ๋ ์ ์, ํ๋์ ๊ธฐ๋ฅ์ ๋ํด ์ฌ๋ฌ ์ฑ๊ณต ๋ฐ ์คํจ ํ ์คํธ๊ฐ ์กด์ฌํ๋ ๋ฐ ์ด๋ฅผ ํ์ธํ๊ธฐ ์ฝ์ง ์์๋ค. ์ผ๋ ฌ๋ก ๋์ด๋ ํ ์คํธ ๊ฒฐ๊ณผ์ฐฝ์ ๋ณด๊ณ ์ด๋ค ํ ์คํธ๋ฅผ ๋นผ๋จน์๋์ง ํน์ ์ด๋ค ํ ์คํธ๊ฐ ์ค๋ณต๋์๋์ง ๋ฐ๋ก ํ์ ํ ์ ์์๋ค.
๊ทธ๋์ ๊ตฌ์กฐํ ๋ ํ ์คํธ ์ฝ๋๋ฅผ ์ํด DCI ํจํด(์ฐธ๊ณ )์ ์ ์ํด ๋์ ํ๋ค.
ํจํด์ ๋ง์ถ์ด ์ฝ๋๋ฅผ ์์ฑํ๋ฉด์ ์ฝ๋ ์์ด ๋์ด๋๋ค๋ ๋จ์ ์ด ์์ง๋ง, class ๋จ์๋ก ํ ์คํธ ๋์(Describe) ๋ฐ ํ๊ฒฝ(Context)์ ๋ถ๋ฆฌํ๋ ์ผ์ด์ค ๊ตฌ๋ณ์ด ์ฌ์ ๋ง์กฑ์ค๋ฝ๋ค.
๋ฌด์๋ณด๋ค๋ ์คํ ์ฐฝ์ด ๋งค์ฐ ์๋ฆ๋ต๋ค. ๐จ
์๋ก์ด ํ์ ์์
DCI ํจํด๊ณผ ๋ณ๊ฐ๋ก ์ถ๊ฐํด์ผ ํ ํ ์คํธ๊ฐ ๋ง์๋ค. ํ์ง๋ง ์๋ก ๊ตฌํํด์ผ ํ ๊ธฐ๋ฅ๋ ์์ด ์ธ๋ ฅ์ด ๋ถ์กฑํ๋ค๊ณ ํ๋จํ๋ค. ๊ทธ๋์ ์ด์ํ์๊ฒ ์๋ฒ ๊ฐ๋ฐ์ ์ถฉ์์ ์์ฒญํ๊ณ , ํ ๋ถ์ด ์๋ก ๋ค์ด์์ ๊ฐ์ด 200์ฌ ๊ฐ์ ํ ์คํธ๋ฅผ ์ถ๊ฐํ๋ค. ์ง๊ธ๋ ์ถ๊ฐํ๋ ์ค์ด๋ค.
โ ๏ธ ๋ฐ์ดํฐ ๋ง์ด๊ทธ๋ ์ด์
์๋ก์ด ์ค๊ณ๋ฅผ ๋ฐํ์ผ๋ก ์ฝ๋ ์์ฑ๋ ๋๋ฌ๋ค. ์ด์ DB์ ์ ์ฅ๋ ๊ธฐ์กด ๋ฐ์ดํฐ๋ค์ ์ ํ ์ด๋ธ๋ก ์๋ง๊ฒ ์ด๋ํ๋ฉด ๋๋ค.
๋ฌธ์ ์ํฉ
์์ํ๊ธด ํ์ง๋ง ๊ฐ๋จํ ์์ ์ด ์๋์๋ค. id๊ฐ 1์ธ ํ ๊ฐ๊ณ๋ถ ๋ด์ญ์ด ์๋ค๊ณ ๊ฐ์ ํ์.
โ ๊ธฐ์กด ์นดํ ๊ณ ๋ฆฌ ํ ์ด๋ธ (old_category)
id | dType (์ข ๋ฅ) | parent_id (์์ ์นดํ ๊ณ ๋ฆฌ) | book_id (์ฐ๊ฒฐ ๊ฐ๊ณ๋ถ) | name (์ด๋ฆ) |
1 | DefaultRoot | null | null | ์์ |
2 | DefaultRoot | null | null | ์ง์ถ |
3 | DefaultRoot | null | null | ์ด์ฒด |
4 | DefaultRoot | null | null | ์์ฐ |
5 | Default | 1 | null | ์๊ธ |
6 | Book | 4 | 1 | ์ ์์ฐ ๋ถ๋ฅ |
โ ๊ธฐ์กด ๊ฐ๊ณ๋ถ ๋ด์ญ-์นดํ ๊ณ ๋ฆฌ ์ฐ๊ฒฐ ํ ์ด๋ธ (old_book_line_category)
id | book_id (์ฐ๊ฒฐ ๊ฐ๊ณ๋ถ) | category_id (์ฐ๊ฒฐ ์นดํ ๊ณ ๋ฆฌ) | category_type (์นดํ ๊ณ ๋ฆฌ ์ข ๋ฅ) |
1 | 1 | 1 | FLOW (์ง์ถ/์์ /์ด์ฒด) |
2 | 1 | 5 | ASSET (์์ฐ ๋ถ๋ฅ) |
3 | 1 | 6 | FLOW_LINE (์ง/์/์ด ๋ถ๋ฅ) |
์ด ์ํฉ์์ ์ธ ๊ฐ์ ํ์ผ๋ก ์ชผ๊ฐ์ ธ์๋ ๊ฐ๊ณ๋ถ ๋ด์ญ-์นดํ ๊ณ ๋ฆฌ ์ฐ๊ฒฐ ๋ฐ์ดํฐ๋ฅผ ํ๋์ ํ์ผ๋ก ํฉ์ณ์ผ ํ๋ค.
Q. ์ฐ๊ฒฐ๋ ์นดํ ๊ณ ๋ฆฌ ์ ๋ณด๋ฅผ(category_id = 1, 5, 6)์ ์๋ก์ด ํ์ ๊ฐ ์ปฌ๋ผ์ ๋ฃ์ด์ฃผ๋ฉด ๋๋ ๊ฑฐ ์๋๊ฐ์?
A. ๊ทธ๊ฑฐ ์๋์ผ...
โ ์ ์์ ์นดํ ๊ณ ๋ฆฌ ํ ์ด๋ธ (category)
id | name (์ด๋ฆ) |
1 | ์์ |
2 | ์ง์ถ |
3 | ์ด์ฒด |
4 | ์์ฐ |
โ ์ ํ์ ์นดํ ๊ณ ๋ฆฌ ํ ์ด๋ธ (subcategory)
id | parent_id (์์ ์นดํ ๊ณ ๋ฆฌ) | book_id (์ฐ๊ฒฐ ๊ฐ๊ณ๋ถ) | name (์ด๋ฆ) |
1 | 1 | 1 | ์๊ธ |
2 | 4 | 1 | ์ ์์ฐ ๋ถ๋ฅ |
โ ์ ๊ฐ๊ณ๋ถ ๋ด์ญ-์นดํ ๊ณ ๋ฆฌ ์ฐ๊ฒฐ ํ ์ด๋ธ (book_line_category)
id | flow_category_id (์์ ์นดํ ๊ณ ๋ฆฌ) |
asset_category_id (์์ฐ ํ์ ์นดํ ๊ณ ๋ฆฌ) |
flow_line_category_id (ํ์ ์นดํ ๊ณ ๋ฆฌ) |
1 | 1 | 2 | 1 |
๊ธฐ์กด์ ํ๋๋ง ์์ฑ๋๋ ๊ธฐ๋ณธ ์นดํ ๊ณ ๋ฆฌ๊ฐ ๊ฐ ๊ฐ๊ณ๋ถ ๋ง๋ค ์์ฑ๋๋๋ก ๋ณ๊ฒฝ๋๋ฉฐ ์นดํ ๊ณ ๋ฆฌ id๋ ๋ฐ๋์๋ค. ์ฆ ๊ธฐ์กด ์นดํ ๊ณ ๋ฆฌ์ ์ ๋ณด๋ก ์ ์นดํ ๊ณ ๋ฆฌ ํ ์ด๋ธ์์ id ๋ฅผ ์ฐพ์์ผํ๋ ๊ฒ์ด๋ค. ๋คํ์ธ ์ ์ ์นดํ ๊ณ ๋ฆฌ์์ (์ด๋ฆ, ์์ ์นดํ ๊ณ ๋ฆฌ, ๊ฐ๊ณ๋ถ) ์กฐํฉ์ด ์ ์ผํด์ผ ํ๋ฏ๋ก ์ด ์ธ ๊ฐ์ง๋ฅผ ์ด์ฉํด id๋ฅผ ์ฐพ์ผ๋ฉด ๋๋ค.
๋ง์ด๊ทธ๋ ์ด์ ์คํฌ๋ฆฝํธ ์์ฑ
๋ง์ด๊ทธ๋ ์ด์ ์กฐ๊ฑด์ด ๋ณต์กํ๊ธฐ ๋๋ฌธ์ ์ฒ์์๋ ์ด๋ฅผ ๋ด๋นํ๋ ์ดํ๋ฆฌ์ผ์ด์ ์ ์์ฑํ๋ ค๊ณ ํ๋ค. ํ์ง๋ง ์ ์ดํ๋ฆฌ์ผ์ด์ ์ ์์ฑํ๊ธฐ ์ํด ์์ฑํด์ผ ํ ์ฝ๋๊ฐ ๊ธธ๊ณ , ์ด๋ฏธ ์ด์ ์ค์ธ ์๋น์ค๊ธฐ ๋๋ฌธ์ ๋ง์ด๊ทธ๋ ์ด์ ์๊ฐ์ ์ต์ํํ๊ณ ์ถ์๋ค. ์ถ๊ฐ๋ก ํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์คํค๋ง๋ฅผ flyway ๋ฅผ ํตํด ๊ด๋ฆฌํ๊ณ ์์ด ๋ง์ด๊ทธ๋ ์ด์ sql ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ๊ธฐ๋ก ๊ฒฐ์ฌํ๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก flyway๋ ์คํฌ๋ฆฝํธ๋ฅผ ๋ฒ์ ๋ณ๋ก ์คํํ๊ณ , ๊ฐ ์คํฌ๋ฆฝํธ ๋ง๋ค ํธ๋์ญ์ ์ด ์ ์ฉ๋๋ค. ์ค๊ฐ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด ์ดํ ์คํฌ๋ฆฝํธ๋ ์คํํ์ง ์๋๋ค. ์ด๋ฅผ ์ด์ฉํด ๋ค์๊ณผ ๊ฐ์ด ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ๋ค.
โ ์คํฌ๋ฆฝํธ 1 - ํ ์ด๋ธ ์์ฑ
- ๊ธฐ์กด category & book_line_category ํ ์ด๋ธ ์ด๋ฆ ๋ณ๊ฒฝ (์๋ก์ด ํ ์ด๋ธ๊ณผ ์ด๋ฆ์ด ๊ฒน์น๋ค.)
- ์ category & subcategory & book_line_category ํ ์ด๋ธ ์์ฑ
โ ์คํฌ๋ฆฝํธ 2 - ๋ฐ์ดํฐ ์ด๋
- ์ category ํ ์ด๋ธ์ ์ง์ถ/์์ /์ด์ฒด/์์ฐ ๋ฐ์ดํฐ ์์ฑ
- ์ subcategory ํ ์ด๋ธ์ ๊ธฐ๋ณธ ํ์ ์นดํ ๊ณ ๋ฆฌ๋ฅผ ๊ฐ๊ณ๋ถ ๋ณ๋ก ์์ฑ
- ๊ธฐ์กด category ํ ์ด๋ธ์์ ์ subcategory ํ ์ด๋ธ๋ก ์ปค์คํ ํ์ ์นดํ ๊ณ ๋ฆฌ๋ฅผ ์ด๋
- ๊ธฐ์กด book_line_category ํ ์ด๋ธ์ ๋ฐ์ดํฐ๋ค์ ์ book_line_category ํ ์ด๋ธ๋ก ์ด๋
- ๊ธฐ์กด ํ ์ด๋ธ ์ญ์
์ด ๋ book_line_category ๋ง์ด๊ทธ๋ ์ด์ ์ฟผ๋ฆฌ๋ ๋ณต์กํ๊ธฐ ๋๋ฌธ์ ์ ๋๋ก ๋์ํ ์ง ํ์ ์ด ์์๋ค.
-- ์คํฌ์ผ๋ฌ: ์คํจํ ์ฟผ๋ฆฌ์ด๋ฏ๋ก ๋ฐ๋ก ์ค๋ช
์ ๋ฌ์ง ์์๋ค
INSERT INTO `book_line_category`(book_line_id,
line_category_id,
line_subcategory_id,
asset_subcategory_id,
created_at)
(SELECT oblc.book_line_id,
linesub.parent_id,
linesub.id,
assetsub.id,
oblc.created_at
FROM `subcategory` linesub
INNER JOIN `old_category` old_linesub
ON old_linesub.name = linesub.name
AND
old_linesub.book_id = linesub.book_id
AND
old_linesub.parent_id = linesub.parent_id
INNER JOIN `old_book_line_category` oblc
ON oblc.category_id = old_linesub.id
INNER JOIN `old_book_line_category` oblc_asset
ON oblc_asset.book_line_id = oblc.book_line_id
INNER JOIN `old_category` old_assetsub
ON old_assetsub.id = oblc_asset.category_id
INNER JOIN `subcategory` assetsub
ON assetsub.name = old_assetsub.name
AND
assetsub.book_id = old_assetsub.book_id
AND assetsub.parent_id =
old_assetsub.parent_id
WHERE old_linesub.dtype = 'Book'
AND old_linesub.parent_id < 4
AND old_assetsub.dtype = 'Book'
AND old_assetsub.parent_id = 4);
์คํจ์ ๋๋นํด ์คํฌ๋ฆฝํธ๊ฐ ์คํ๋๊ธฐ ์ง์ DB๋ฅผ ๋ฐฑ์ ํ๋ค. RDS๋ฅผ ์ฌ์ฉํ๊ณ ์์ด์ ์ ๊ณตํ๋ ๋ฐฑ์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ค.
๋ง์ด๊ทธ๋ ์ด์ ์คํจ์ ์ฌ์๋
์ ์ฒด ํ์๋ค์๊ฒ ๊ฐ๋ฐ ์ฑ์ด ์ ๊น ์ ๋๋ก ์๋ํ์ง ์์ ์ ์๋ค๊ณ ์๋ฆฌ๊ณ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๋ค. flyway ๋ก๊ทธ๋ฅผ ์ดํผ๋ ๋คํํ ์ค๊ฐ์ ์๋ฌ๊ฐ ๋์ง๋ ์์๋ค. ๊ทธ๋์ ์ฑ๊ณตํ๋? ์ถ์๋๋ฐ ๋ฌธ์ ์ ์ฟผ๋ฆฌ๊ฐ ์๋ชป ์์ฑ๋์ด book_line_category ๋ฐ์ดํฐ๊ฐ ์ ๋๋ก ์ด์ ๋์ง ์์๋ค.
๋ฐฑ์ ํ DB์์ ๋ฐ์ดํฐ๋ง ๋ฐ์(mysqldump ์ด์ฉ) ๋ก์ปฌ์์ ๋ค์ ํ ์คํธํด๋ณด๋ฉฐ ์ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋ค.
insert into `book_line_category` (book_line_id,
line_category_id,
line_subcategory_id,
asset_subcategory_id,
created_at)
(select bl.id,
line_sub.parent_id,
line_sub.id,
asset_sub.id,
old_line_sub_blc.created_at
from old_book_line_category old_line_blc
-- 3๊ฐ์ ํ์ผ๋ก ๋๋ ๊ธฐ์กด book_line_category๋ฅผ ํ๋์ ํ์ผ๋ก JOIN
inner join old_book_line_category old_line_sub_blc
on old_line_sub_blc.book_line_id = old_line_blc.book_line_id
inner join old_book_line_category old_asset_sub_blc
on old_asset_sub_blc.book_line_id = old_line_sub_blc.book_line_id
-- book์ id๋ฅผ ์ฐพ๊ธฐ ์ํ JOIN
inner join book_line bl
on bl.id = old_line_blc.book_line_id
-- ๊ธฐ์กด category์ id๋ฅผ ์ฐพ๊ธฐ ์ํ JOIN
inner join old_category old_line_sub
on old_line_sub.id = old_line_sub_blc.category_id
inner join old_category old_asset_sub
on old_asset_sub.id = old_asset_sub_blc.category_id
-- (์ด๋ฆ, ์ํ ๊ฐ๊ณ๋ถ, ๋ถ๋ชจ ์นดํ
๊ณ ๋ฆฌ)๋ฅผ ๋ฐํ์ผ๋ก ์๋ก์ด category์ id ๋ฅผ ์ฐพ๊ธฐ ์ํ JOIN
inner join subcategory line_sub
on line_sub.name = old_line_sub_blc.name
and line_sub.parent_id = old_line_blc.category_id
and line_sub.book_id = bl.book_id
inner join subcategory asset_sub
on asset_sub.name = old_asset_sub_blc.name
and asset_sub.parent_id = 4
and asset_sub.book_id = bl.book_id
-- 3๊ฐ์ ํ์ผ๋ก ๋๋ ๊ธฐ์กด book_line_category๋ฅผ ํ๋์ ํ์ผ๋ก JOIN ํ๋ ์กฐ๊ฑด
where old_line_blc.book_line_categories_key = 'FLOW'
and old_line_sub_blc.book_line_categories_key = 'FLOW_LINE'
and old_asset_sub_blc.book_line_categories_key = 'ASSET');
๋คํํ ์ ์ฟผ๋ฆฌ๋ ์ ๋์ํ๋ค.
๐คฏ ์๊ฐ
์๋ฒํ์ ํฐ ์ด์๋ฅผ ๋๋์ด ๋๋๋ค. ์ฝ๋๋ง ํด๋ ์ต์ 9์ฒ์ค์ด ๋ณ๊ฒฝ๋ ๋๊ณต์ฌ์๋ค.
์ต์ ์ ์ค๊ณ๋ ์ด๋ป๊ฒ ํ ๊น?
์ง๊ธ ๋ ๊ฑฐ์๋ก ์ทจ๊ธํ๊ณ ๋ณ๊ฒฝํ ์ด์ ์ค๊ณ๋ ๊ทธ ๋น์์์ ์ต์ ์ผ๋ก ์ฌ๊ฒผ๋ ์ค๊ณ๋ค. ๊ทธ๋ ๋ค๋ฉด ์ง๊ธ ์ค๊ณ๋ ๋ฏธ๋์ ๋ ๊ฑฐ์๊ฐ ๋์ง ์์๊น?
์์ฆ์ ์ฅ์ ์ํฉ์ด ์ผ์ด๋์ง ์๋๋ก 100% ์๋ฐฉํ๋ ๊ฑด ๋ถ๊ฐ๋ฅํ๋, ์ฅ์ ์ํฉ์ด ์ผ์ด๋ฌ์ ๋ ๋น ๋ฅด๊ฒ ๋ณต๊ตฌ๋๋๋ก ์๋น์ค๋ฅผ ๊ฐ๋ฐํ๋ค๊ณ ํ๋ค. ๋๋ฉ์ธ์ด ์ด๋ป๊ฒ ๋ณ๊ฒฝ๋ ์ง 100% ์์ธกํ๋ ๊ฑด ๋ถ๊ฐ๋ฅํ๋ ์ง๊ธ์ ์ค๊ณ๋ ์ถํ ๋ ๊ฑฐ์๊ฐ ๋ ๊ฐ๋ฅ์ฑ์ด ์๋ค. ๊ทธ๋ ๋ค๋ฉด ๊ทธ ๋ ์ต๋ํ ์์ ์ ์ผ๋ก ๋ณ๊ฒฝํ ์ ์๋๋ก ๋๋นํ๋ฉด ๋์ง ์์๊น? ๋๋น์ฑ ์ผ๋ก๋ ์์ง ์ธ์ ํ ์คํธ ์ถ๊ฐ๋ง ์๊ฐ๋๋๋ฐ(๊ฐ๋ฐ ์ธ์๋ QA ์๋๋ฆฌ์ค ์ ๋ฆฌ?)... ์์ง์ ์ ๋ชจ๋ฅด๊ฒ ๋ค.
๋ ๊ฑฐ์๋ ๋นจ๋ฆฌ ์น์ฐ์
์ฌ์ค ์ด๋ฒ์๋ ์๊ณ ๋ ์ผ์ ์ ๋ง์ถ๋๋ผ ๋ชป ์น์ ์ง๋ง... ์ญ์ ๊ฐ๋ฐํ๋ฉด์ ๊ฑธ๋ฆฌ๋ ์์๋ ์ต๋ํ ๋นจ๋ฆฌ ํด๊ฒฐํด์ผ๊ฒ ๋ค. ๋ณ๊ฒฝํ ์ฝ๋๊ฐ ๋ง์์ง๊ธฐ๋ ํ์ง๋ง ์๋น์ค๋ฅผ ์ด์ํ๋ ์๋ ๋ฐ์ดํฐ๋ ๋ง์์ง๋ค.
'ํ๋ก์ ํธ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[ZI9ZA9] ๊ฒฐ์ ์ฑ๋ฅ ๊ฐ์ ๊ธฐ (0) | 2024.03.17 |
---|---|
[Floney] ์์ฐ ๋ฐ์ดํฐ ๋์์ฑ ์ด์ ํด๊ฒฐ ์ฝ์ง๊ธฐ (7) | 2023.12.14 |