๐ค ์ DB ์คํค๋ง ๋ง์ด๊ทธ๋ ์ด์ ๋๊ตฌ์ ๋์ ์ ๊ณ ๋ฏผํ๊ฒ ๋์๋๊ฐ
์์์ผ ํ ๋ฐฉ์์ผ๋ก 1์ฐจ ๋ฐ๋ชจ๋ฐ์ด / 2์ฐจ ๋ฐ๋ชจ๋ฐ์ด๋ฅผ ๊ฑฐ์น๋ฉด์ ๊ฐ๋ฐ์ ์ํ๊ณ ์๋ ํ์ฌ, ๊ณ์ํด์ ์ํฐํฐ์ ๊ตฌ์ฑ์ด ๋ฌ๋ผ์ง๋ ๊ฒ์ ๋น์ฐํ๋ค. ์ฐ๋ฆฌ ํ์ ๊ฒฝ์ฐ์๋ ๊ธฐํ์ 2-3๋ฒ์ ์์ด์ง๊ณ , ์ผ๋ถ๊ฐ ์กฐ๊ธ์ฉ ์์ ๋๊ธฐ๋ ํ๋ค. ๋ฟ๋ง ์๋๋ผ ํ์ ๊ฐ์ ์ดํด๊ฐ ์กฐ๊ธ์ฉ ์ด๊ธ๋์ ์ํฐํฐ์ ๊ตฌ์กฐ๊ฐ ๋ฌ๋ผ์ง๋ ๊ฒฝ์ฐ๋ ํ๋คํ๋ค. ๊ทธ๋ ๊ธฐ์ DB ์คํค๋ง ๋ง์ด๊ทธ๋ ์ด์ ๋๊ตฌ๊ฐ ํ์ํ ๊ฒ์ด๋ผ๋ ์์์ ํ๊ณ ์์๋ค. ๊ทธ๋ฌ๋ ์๊ฐ๋ณด๋ค ๋นจ๋ฆฌ ํ์์ฑ์ ๋๋ผ๊ฒ ๋์๋ค. ๋ฐฐํฌ ํ๊ฒฝ์์ 500 ์๋ฌ๊ฐ ํฐ์ก๊ธฐ ๋๋ฌธ์ด๋ค.
์ ๋ฌธ์ ์ํฉ์ด ๋ฐ์ํ์๊น?
๊ธฐ์กด์ amount ๋ผ๋ ํ๋๊ฐ ์กด์ฌํ๋ค. ๊ทธ๋ฌ๋ ์ด์ ๋ช ํ์ฑ์ ์ํด cupAmount ๋ผ๋ ํ๋๋ช ์ผ๋ก ๋ณ๊ฒฝํ๋ค.
๊ทธ๋ฌ๋ ์ด์ ํ๊ฒฝ์ ddl-auto ๊ฐ update ์๊ธฐ์ amount ๋ผ๋ ํ๋๋ ์ฌ๋ผ์ง์ง ์๊ณ , cupAmount ๋ผ๋ ํ๋๊ฐ ์ถ๊ฐ ๋๋ค.
์ด๋ ํด๋น API ๊ฐ ์ค์ ๋ก ์คํ์ด ๋ ๋, ๋ฐํ์์ 500 ์๋ฌ๋ฅผ ๋ฑ์ด๋๊ณ ์ฐ๋ฆฌ๋ ํจ๋์ด ์์๋ค. ๊ทธ ๋ ๋ฐ๋ก ๋ง์ด๊ทธ๋ ์ด์ ๋๊ตฌ๋ฅผ ๋์ ํด์ผ๊ฒ ๋ค๋ ๊ฒฐ๋ก ์ ๋ด๋ ธ๋ค!
ddl-auto ๋ก๋ ์ถฉ๋ถ์น ์์๊ฐ?
create | ์คํ ์ ํ ์ด๋ธ์ ๋ชจ๋ ์ ๊ฑฐ ํ ์๋ก ์์ฑ | โ ์ด์ ๋ฐ์ดํฐ ์ญ์ |
create-drop | ์ข ๋ฃ ์์ ์ ํ ์ด๋ธ๋ ์ญ์ | โ ํ ์คํธ ์ธ ๋ถ๊ฐ |
update | ๊ตฌ์กฐ ๋ณ๊ฒฝ ๊ฐ์ง ์ DB์ ๋ฐ์ | โ ๏ธ ๋ณ๊ฒฝ ๋ด์ญ ์ถ์ ๋ถ๊ฐ / ์ผ๋ถ ๋ณ๊ฒฝ ๋๋ฝ ๊ฐ๋ฅ |
validate | DB์ Entity์ ์ผ์น ์ฌ๋ถ๋ง ํ์ธ | โ ์์ ํ์ง๋ง ๋ณ๊ฒฝ ๋ฐ์์ ์ง์ ํด์ผ ํจ |
none | ์๋ฌด ์์ ๋ ์ํํ์ง ์์ | โ ๋ง์ด๊ทธ๋ ์ด์ ๋๊ตฌ ์ฌ์ฉ ์ ์ ํฉ |
์ ๋ ์ถฉ๋ถ์น ์๋ค. ddl-auto ๋ฅผ ์๋ฌด๋ ๊ฒ๋ ์ด์ ํ๊ฒฝ์์ ์ฌ์ฉํ๋ฉด ์์ฒญ๋ ์ํ์ด ๋ฐ๋ฅธ๋ค.
์์ ํ์ ์ ๋ฆฌํ ๊ฒ๊ณผ ๊ฐ์ด ์ด์ํ๊ฒฝ์์๋ validate ํน์ none ์ผ๋ก ์ค์ ํด๋๊ณ , ์ง์ ๋ณ๊ฒฝ์ ๋ฐ์ํด์ค์ผ ํ๋ค.
๐ค Liquibase vs Flyway
์๋ก์ด ๊ธฐ์ ์ ๋์ ํ ๋์๋ ๋ญ๋ ์ด์ ๊ฐ ํ์ํ๋ค.
๊ทธ๋ ๊ธฐ์ ๊ธฐ์กด์ ์ฌ์ฉํด๋ณธ ๊ฒฝํ์ด ์๋ Flyway ๋ฅผ ์ ์ฉํ๊ธฐ ์ ์ ์ฃผ๋ก ์ฌ์ฉ๋๋ ๋ค๋ฅธ ํด๊ณผ ๋น๊ตํด๋ณด์๋ค.
๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ๋๋ ๋๊ตฌ๋ Liquibase ์ Flyway ์๋ค. ์ด๋ฅผ ํ ๋๋ก ๋น๊ต๋ฅผ ์์ํ๋ค.
๋ค์์ ํ์๋ค๊ณผ ๋ ผ์ํ๊ธฐ ์ํด ๋จ๊ฒจ๋๋ discussions ๋ด์ฉ์ ์ ๋ฌธ์ด๋ค.
https://github.com/woowacourse-teams/2025-mul-kkam/discussions/122
๐ฌ DB ๋ง์ด๊ทธ๋ ์ด์ ๋๊ตฌ ๋น๊ต: `Flyway` vs `Liquibase` · woowacourse-teams 2025-mul-kkam · Discussion #122
์์ ํ ์ํฐํฐ์ ๋ณ๊ฒฝ ๋ฐ ์ ์ง๋ฅผ ์ํด DB ๋ง์ด๊ทธ๋ ์ด์ ๋๊ตฌ๋ฅผ ๋์ ํ๊ณ ์ ํฉ๋๋ค. ์ ๋ flyway ๊ฐ ๋ ์ ํฉํ ๊ฒ์ด๋ผ๋ ๊ฒฐ๋ก ์ ๋ด๋ ธ์ด์! ๋ค๋ฅธ ์๊ฒฌ์ด๋ ๋ฐ๋ฐ ํ์ํด์ ๐ค ๋ค์ ๊ธ์ ์ฝ์ด๋ณด๊ณ , ์
github.com
๐ ์ ์ ๊ธฐ์ค
- ์ค๋ฌด์์ ๊ฐ์ฅ ๋๋ฆฌ ์ฐ์ด๋ ๋ง์ด๊ทธ๋ ์ด์ ๋๊ตฌ
- ๋ ๋๊ตฌ๋ฅผ ์ค์ฌ์ผ๋ก ๋น๊ตํ ๋ธ๋ก๊ทธ๋ ๋ฌธ์๊ฐ ๋ค์ ์กด์ฌํจ
1. ์ ์ธ ๋ฐฉ์ ์ฐจ์ด
โ Liquibase ์์ (XML DSL)
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd">
<changeSet id="1" author="jinseunghui">
<createTable tableName="member">
<column name="id" type="BIGINT" autoIncrement="true">
<constraints primaryKey="true"/>
</column>
<column name="nickname" type="VARCHAR(50)">
<constraints nullable="false"/>
</column>
<column name="gender" type="VARCHAR(10)">
<constraints nullable="false"/>
</column>
<column name="weight" type="DOUBLE"/>
</createTable>
</changeSet>
</databaseChangeLog>
๐ก ์ XML์ ์๋ SQL๊ณผ ๋์ผ
```sql
CREATE TABLE member (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
nickname VARCHAR(50) NOT NULL,
gender VARCHAR(10) NOT NULL,
weight DOUBLE
);
Liquibase XML๋์๋๋ SQL
<createTable> | CREATE TABLE ... |
<column name="x" type="..."/> | ๊ฐ ์ปฌ๋ผ ์ ์ |
<constraints primaryKey="true"/> | PRIMARY KEY, NOT NULL, UNIQUE ๋ฑ ์ ์ฝ์กฐ๊ฑด |
<changeSet id="1">...</changeSet> | ํ๋์ ๋ฒ์ ๋จ์. Git ์ปค๋ฐ์ฒ๋ผ ๊ด๋ฆฌ๋จ |
โ Flyway ์์ (SQL ๊ธฐ๋ฐ)
-- V1__create_member.sql
CREATE TABLE member (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
nickname VARCHAR(50) NOT NULL,
gender VARCHAR(10) NOT NULL,
weight DOUBLE
);
๐ ์ ๋ฆฌ
- Flyway: SQL ์ง์ ์์ฑ → ํ์ต ๋น์ฉ ๋ฎ์, ์ง๊ด์
- Liquibase: DSL ํํ → ๋๋ฉ์ธ ์ธ์ด์ ๊ฐ๊น์ (์ถ์ํ ๋์), ๋ฌ๋์ปค๋ธ ์กด์ฌ
2. ๋กค๋ฐฑ ์ง์ ์ฌ๋ถ
โ Liquibase
<changeSet id="2" author="jin">
<addColumn tableName="member">
<column name="age" type="int"/>
</addColumn>
<rollback>
<dropColumn tableName="member" columnName="age"/>
</rollback>
</changeSet>
- Liquibase๋ ๋กค๋ฐฑ์ด ๊ฐ๋ฅ
โ Flyway
-- V3__remove_age.sql
ALTER TABLE member DROP COLUMN age;
- ์ง์ DROP COLUMN SQL ์คํฌ๋ฆฝํธ๋ฅผ ์ ํ์ผ๋ก ์์ฑํด์ผ ํจ
- ๋ฒ์ ์ “๋๋๋ฆฌ๋ ๊ฒ”์ ๋ถ๊ฐ๋ฅ → ์๋ก์ด ๋ฒ์ ์ผ๋ก ๋ฎ๋ ๋ฐฉ์
๐ ์ ๋ฆฌ
- Liquibase๋ rollback ๋ฌธ๋ฒ ๋ด์ฅ
- Flyway๋ ๋กค๋ฐฑ ์ ์๋ก์ด ์คํฌ๋ฆฝํธ๋ฅผ ์ถ๊ฐํด์ผ ํจ (๋๋๋ฆผ์ด ์๋๋ผ ‘๋ฎ์ด์ฐ๊ธฐ’)
3. Java API ์ ๊ณต ์ฌ๋ถ
โ Flyway (์ง์ ์คํ ๊ฐ๋ฅ)
Flyway flyway = Flyway.configure()
.dataSource("jdbc:mysql://localhost:3306/test", "user", "pw")
.locations("classpath:db/migration")
.load();
flyway.clean();
flyway.migrate();
Java ์ฝ๋๋ฅผ ํตํด์๋ ๋ง์ด๊ทธ๋ ์ด์ ์ฌ์ฉ ๊ฐ๋ฅ
๋ค์๊ณผ ๊ฐ์ ์ํฉ์์ ์ฌ์ฉํ๊ธฐ ์ฉ์ด
- ํ ์คํธ์์ ์ง์ DB ์ด๊ธฐํ/์ฌ์ ์ฉ
- ๋ค์ค DB ๋ง์ด๊ทธ๋ ์ด์ ์ ๋์ ์ผ๋ก ์ํํ ๋
- ํน์ ์กฐ๊ฑด/ํ๊ฒฝ์ ๋ฐ๋ผ ๋์ ์คํํ ๋
ํ ์คํธ ์์ ํนํ ์ฉ์ด
@BeforeEach
void setUp() {
flyway.clean();
flyway.migrate();
}
์์ ๊ฐ์ ํํ๋ก ํ ์คํธ ์ ํ์ํ๋ฉด ์ฌ์ฉ ๊ฐ๋ฅ
โ Liquibase (SpringLiquibase ์ฌ์ฉ)
@Configuration
public class LiquibaseConfig {
@Bean
public SpringLiquibase liquibase(DataSource dataSource) {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setDataSource(dataSource);
liquibase.setChangeLog("classpath:db/changelog/db.changelog-master.yaml");
liquibase.setContexts("dev,test");
return liquibase;
}
}
LiquiBase ๋ Java API ๋ ์ ๊ณต๋์ง ์์ง๋ง, Spring ๊ณผ ํตํฉ๋ ์ํฉ์์๋ ์ฉ์ดํ๊ฒ ์ฌ์ฉ ๊ฐ๋ฅ
@LisuiBaseBean ์ด ์กด์ฌ
Spring Boot ํ๊ฒฝ์์ Liquibase๋ฅผ Java Bean์ผ๋ก ์๋ ๊ตฌ์ฑํ ๋ ์ฌ์ฉํ๋ Spring์ฉ ์ค์ ํด๋์ค
- ๋ณดํต์ application.yml๋ก Liquibase๋ฅผ ์๋ ์คํํ์ง๋ง, ํน๋ณํ ์ค์ ์ด ํ์ํ ๋ ์ง์ SpringLiquibase ๋น์ ๋ฑ๋กํด ์ ์ด ๊ฐ๋ฅ
- ์ํฉ์ ๋ฐ๋ผ์ ๋ค๋ฅธ SpringLiquibase ๋น์ ์ฃผ์ ํด ์ ์ฐํ๊ฒ ์ฌ์ฉ ๊ฐ๋ฅ
๋ค์ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํํ ์ ๊ณต
โ flyway ๋ RDBMS ๋ง ์ ๊ณต
โ
LiquiBase ๋ NoSQL ์ค MongoDB ๋ง ๊ณต์์ ์ผ๋ก ์ง์
Spring Boot ํตํฉ
โ ๋ ๋๊ตฌ ๋ชจ๋ Spring Boot ์์ ๊ณต์์ ์ผ๋ก ์ง์
์๋ ์คํ | Spring Boot ์์ ์ ์๋์ผ๋ก ๋ง์ด๊ทธ๋ ์ด์ ์ํ |
JDBC ์ฐ๋ | DB URL, username/password ์ง์ ๊ฐ๋ฅ |
Profile์ ๋ฐ๋ผ ๋ถ๊ธฐ ๊ฐ๋ฅ | ์: application-dev.yml, application-prod.yml๋ก ๋ถ๋ฆฌ |
ํ ์คํธ ์ ์ ์ฉ | H2 ๋ฑ ๋ด์ฅ DB ํ ์คํธ์์๋ ์๋ ๋ฐ์ ๊ฐ๋ฅ |
spring:
flyway:
enabled: true
locations: classpath:db/migration
baseline-on-migrate: true
user: myuser
password: secret
url: jdbc:mysql://localhost:3306/mydb
spring:
liquibase:
enabled: true
change-log: classpath:db/changelog/db.changelog-master.yaml
contexts: test
default-schema: public
user: myuser
password: secret
url: jdbc:postgresql://localhost:5432/mydb
์คํค๋ง ์๋ ์์ฑ
flyway ์ LiquiBase ๋ชจ๋ ๋ถ๊ฐ๋ฅ
์๋์ผ๋ก ์ฌ์ฉ์๊ฐ ์ ์ํด์ค์ผ ํจ
๊ทธ๋ฌ๋ flyway ๋ ์ง์ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ์ง๋ง, Liquibase ๋ DSL ๊ณผ ๊ฐ์ด ๋๋ฉ์ธ์ ๋ ๊ฐ๊น๊ฒ ์ ์ํ๋ฉด ์ด๋ฅผ SQL ๋ก ๋ณํํด์ค๋ค๋ ์ฐจ์ด์ ์ ์กด์ฌ.
์กฐ๊ธ ๋ LiquiBase ๊ฐ ๋๋ฉ์ธ ์ธก๋ฉด์ ๊ฐ๊น์ด ์ถ์ํ๋ ํํ
databaseChangeLog:
- changeSet:
id: 1
author: jin
changes:
- createTable:
tableName: member
columns:
- column:
name: id
type: bigint
autoIncrement: true
constraints:
primaryKey: true
- column:
name: name
type: varchar(255)
์์ ๊ฐ์ด ์กฐ๊ธ ๋ '์ธ์ด'์ ๊ฐ๊น์ ๋น๊ฐ๋ฐ์๋ ์ดํดํ๊ธฐ ์ฉ์ดํ ์ ์์
๐ ์ต์ข ํ๋จ
โ
Flyway
• SQL ์น์ํ๊ณ ์ง๊ด์ ์ธ ๋ฐฉ์
• ๋ฌ๋์ปค๋ธ ์ ์
• ํ
์คํธ ์ ์ ์ฐํ๊ฒ ํ์ฉ ๊ฐ๋ฅ
โ
Liquibase
• DSL ๊ธฐ๋ฐ ์ ์ธ → ๋น๊ฐ๋ฐ์๋ ์ ๊ทผ ๊ฐ๋ฅ
• ๋กค๋ฐฑ ๊ธฐ๋ฅ ๋ฑ ํ๋ถํ ๊ธฐ๋ฅ ์ ๊ณต
• ๋จ, DSL ํ์ต์ด ํ์ → ํ ์ํฉ ๊ณ ๋ ค
๐ฌ ํ์ฌ ๋ฌผ๊น ํ๋ก์ ํธ ํ ์ํฉ์์๋
→ ๋ฌ๋์ปค๋ธ๊ฐ ์ ๊ณ , SQL ๊ธฐ๋ฐ์ Flyway๊ฐ ์ ํฉํ๋ค๊ณ ํ๋จ๋จ
๐งโ๏ธ DB ๋ ๊ฒฐ๊ตญ ์์์ผํด์ผ ํ๋ค
์ด๋ ๊ฒ ์ฌ๋ ธ๋ ๋์ค์ปค์ ์ ํ์์ธ ์นผ๋ฆฌ๐๐ป ๊ฐ ์์ ๊ฐ์ ์ฝ๋ฉํธ๋ฅผ ๋จ๊ฒจ์ฃผ์๋ค. ์ด ์ฝ๋ฉํธ์์ ๋๋ ์ฃผ๋ชฉํ ๋จ์ด๊ฐ ์์๋ค. ์์์ผ! โ๏ธ
DB ๋ ๊ฒฐ๊ตญ ์ฐ๋ฆฌ์ ์๋น์ค๋ฅผ ์ด๋ฃจ๋ ์ฃผ์ํ ๋ถ๋ถ ์ค ํ๋์ธ๋ฐ, ์ ์์์ผํด์ผ ํ๋ค๋ ์๊ฐ์ ํ์ง ๋ชปํ์๊น? ํ๋ ์๊ฐ์ ํ๊ฒ ๋๋ค.
๊ทธ๋์ ์ด๋ฐ ์ ๋ฐ ์์ค๋ค์ ์ฐพ์๋ณด๋ ์ค, ๋ค์ ๊ธ์ ๋ณด๊ฒ ๋๋ค.
https://martinfowler.com/articles/evodb.html
Evolutionary Database Design
Techniques to allow you to evolve the schema and contents of a production database
martinfowler.com
์ด ๊ธ์ ์ฃผ๋ ์์ง๋ ๋ค์๊ณผ ๊ฐ๋ค.
- ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ฝ๋๋ฟ๋ง ์๋๋ผ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ญ์๋ ์ ์์ผํ๊ฒ ๊ด๋ฆฌ๋์ด์ผ ํ๋ค
- ํด๋น ๋ฒ์ ์ผ๋ก ๋กค๋ฐฑ์ ํ๊ฒ ๋๋ค๋ฉด, ์ฝ๋ ๋ฟ๋ง ์๋๋ผ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ด์ ๋ง์ถฐ ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋์๊ฐ ์ ์๋ ํ๊ฒฝ์ด ๊ฐ์ถฐ์ ธ์ผ ํ๋ค
- ์์ sql ์ ์ ๋๋ก ์คํํ๋ฉด ์๋๊ณ , ๋ง์ด๊ทธ๋ ์ด์ ๋๊ตฌ์์ ์ ๊ณตํด์ฃผ๋ ์คํฌ๋ฆฝํธ๋ก๋ง ๊ตฌ๋๋์ด์ผ ํ๋ค
๊ทธ๋ ๋ค๋ฉด, ์์์ผํ๊ฒ ๊ด๋ฆฌ๋ ์ ์๋๋ก ๋๋ DB ๋ง์ด๊ทธ๋ ์ด์ ๋๊ตฌ๋ ๋ค์๊ณผ ๊ฐ์์ผ ํ๋ค๋ ๊ฒ ๋ด ์๊ฐ์ด์๋ค.
1. ๋กค๋ฐฑ์ด ์ฌ์์ผ ํ๋ค. -> ์ธ์ ๋ ์ ํ๋ฆฌ์ผ์ด์ ๋๊ตฌ์ ํจ๊ป ๋ฒ์ ๋์ด ์์ฝ๊ฒ ๋์ด์ผ ํ๋ค.
2. ๋๊ตฐ๊ฐ ๊นํ๋ธ์ ๊ฐ์ ๋ฒ์ ์ผ๋ก ๊ด๋ฆฌ๋๋ ์คํฌ๋ฆฝํธ ์ด์ธ์ ์์๋ก ์คํํ ์คํฌ๋ฆฝํธ๊ฐ ์๋์ง ๊ฒ์ฆ์ด ๋์ด์ผ ํ๋ค.
์ด๋ฌํ ์์๋ก ๋ฐ์ ธ๋ณด์์ ๋์๋, Liquibase ์ ๋ค์ ์์๋ค์ ๋ ์ฌ๋ ค๋ดค์ ๋ ๊ฐ์ฅ ์ ํฉํ ๋๊ตฌ๋ผ๋ ์๊ฐ์ ํ๋ค.
1. Liquibase ๋ ๋ช ์์ ์ผ๋ก ๋กค๋ฐฑ์ด ์กด์ฌํ๋ค.
2. diff ๋ฅผ ํตํด ๋ณ๊ฒฝ ์ฌํญ์ ์ถ์ ํ๋ ๋ฑ ์์ ์คํฌ๋ฆฝํธ์ ์คํ์ ci ๋ฑ์ ํตํด ์๊ฒฉํ ๊ฐ์ํ ์ ์๋ค.
ํ์ง๋ง ๊ฒฐ๊ตญ Flyway ๋ก..
๊ทธ๋ผ์๋ ์ฐ๋ฆฌ ํ์ Flyway ๋ฅผ ์ ํํ๊ฒ ๋๋ค. ๊ทธ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ๋ค.
1. ๋ฌ๋ ์ปค๋ธ๊ฐ ์กด์ฌํ๋ค.
- MVP ๋ฅผ ๋น ๋ฅด๊ฒ ๋ฝ์๋ด๋ณด๋ ๊ฒ์ ๋ชฉํ๋ก ํ ์ง๊ธ, SQL ๊ธฐ๋ฐ ๋์ DSL ๊ธฐ๋ฐ์ ์ธ์ด๋ฅผ ๋ฐฐ์๋ณด๋ ๊ฒ ํจ์จ์ ์ธ๊ฐ?
- SQL ์ด ์คํ๋ ค ์ฐ๋ฆฌ์๊ฒ๋ ์ง๊ด์ ์ผ ์๋ ์๋ค.
- ํ์ฌ๋ ์์์ผ์ด๋ผ๋ ๊ฐ์น๋ ์๋ก์ด ํด์ ๋ฐฐ์๋ณด๋ ๊ฒ์ ๋ํ ๊ฐ์น๋ณด๋ค ์๋๊ฐ ์๋ช !
2. Flyway ๋ ์ด๋ ์ ๋ ํด๋ธ๋ค..
- ๋ด๊ฐ ์ค์์ํ๋ ๋กค๋ฐฑ์ ์๋ก์ด ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํด ๋กค๋ฐฑ์ 'ํ ๊ฒ๊ณผ ๊ฐ์' ์ผ์ข ์ ํจ๊ณผ๋ฅผ ๋ผ ์๋ ์๋ค.
- ์ฒดํฌ์ฌ / ๋ฒ์ ๊ธฐ๋ก ๋ฑ๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ผ๋ก '์ด๋ ์ ๋๋' ์๋ํ ๋ฐ๋๋ก ์์์ผํ๊ณ ์ ํฉ์ฑ ์๊ฒ ํ์ฉํ ์ ์๋ค.
๊ทธ๋์ ์ฐ์ ์ Flyway ๋ก ์ธํ ์ ํด๋๊ณ , ๋กค๋ฐฑ์ ํ์์ฑ์ด๋ / ๋ ์๊ฒฉํ ๋ฒ์ ๋์ด ํ์ํ๋ค๊ณ ํ๋จ์ด ๋ ๋ ๋์ ํ๋ ๊ฒ์ผ๋ก ๊ฒฐ์ ํ๋ค!