[UMC] 7์ฃผ์ฐจ : DB & DBMS
๐ย ํ์ต ๋ชฉํ
- ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ดํดํ๋ค.
- iOS์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๊ตฌ์ถํ๊ณ ๊ด๋ฆฌํ ์ ์๋ค.
- UserDefaults๋ฅผ ์ดํดํ๊ณ ํ์ฉํ ์ ์๋ค.
โ๐ปย ์์ ๋ด์ฉ ์ ๋ฆฌ
DB๋ฅผ ๊ณ์ข๋ก ์ค๋ช
์ํ์ ๊ณ ๊ฐ์ด ATM์ ํตํด ํ๊ธ์ ์ธ์ถํ๋ค
์๋น์ค ์ด์ฉ ๊ณผ์ ์์ DBMS์ ์ ๊ทผํ๊ณ DBMS์์ ๊ณ ๊ฐ ์ ๋ณด๋ฅผ ์์ ํด์ ๋์ ๋น ์ ธ๋๊ฐ๊ฒ ํ๋ค.
DBMS๋ DB๋ฅผ ๊ด๋ฆฌํ๋ sw
DBMS๋ ๋ฐ์ดํฐ๋ฅผ ํ์ผ ํํ๋ก ๋ค๋ฃจ๋๋ฐ
๋ฐ์ดํฐ๊ฐ ๋๊ณผ ๊ด๋ จ๋์ด์๊ธฐ์ ๋ณด์ ์์ ํฐ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์๋ ์์ด์
๋จ์ ์ ๋ณด์ํ RDBMS๊ฐ ํ์ํ๋ค.
์ด๋ R๋ relational ๊ด๊ณํ์ด๋ ๋ป์ด๋ค
๋ง ๊ทธ๋๋ก ๋ฐ์ดํฐ๋ค์ด ๊ด๊ณ๋ฅผ ์ง๋๊ฒ ๋๋ค.
์ ์๋ ๊ฐ๊ฐ ํ์ผ ํํ์๋๋ฐ
์ด์ ํ ์ด๋ธ์ด๋ ๊ฐ๋ ์ ํตํด ๊ด๋ฆฌ๋๋ค.
์ด ํ ์ด๋ธ๋ผ๋ฆฌ ๊ด๊ณ์ฑ์ ๋๊ณ ์๋ค.
์ ๊ธฐ ์ค๋ฅธ์ชฝ ํ ์ด๋ธ์ ํ์ ๊ธ์จ๊ฐ ๋ณด์ด๋๊ฐ
ํ ์ด๋ธ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๋ฉด์ ๋ํ๋ ํค๋ ๊ฐ๋ ์ด๋ค.
์ด RDBMS ์์ ํ ์ด๋ธ์ ๊ด๋ฆฌํ๊ณ ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํ ์ธ์ด๊ฐ
์ฐ๋ฆฌ๊ฐ ์ตํ ๋ค์ด๋ณธ
SQL์ด๋ค
SQL(Structured Query Language)
์ฑ์ ๊บผ๋ ๋ฐ์ดํฐ ์กด์ฌํ๋๋กโ UserDefaults ์ฌ์ฉ
๐ฏย ํต์ฌ ํค์๋
-
DB
์ค์ฌ์
ํน์ ๋ค์์ ์ด์ฉ์๋ค์๊ฒ ํ์ํ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ค๋ ์ง ์กฐ์ง ๋ด์์ ํ์๋ก ํ๋ ์ ๋ณด๋ฅผ ์ฒด๊ณ์ ์ผ๋ก ์ถ์ ํ์ฌ ๊ทธ ์กฐ์ง ๋ด์ ์ด์ฉ์์๊ฒ ํ์ํ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ ์ ๋ณด ์๋น์ค ๊ธฐ๊ด์ ์ฌ์ฅ๋ถ์ ํด๋น๋๋ค.
์ผ๋ฐ์ ์ผ๋ก ์์ฉ ํ๋ก๊ทธ๋จ๊ณผ๋ ๋ณ๊ฐ์ ๋ฏธ๋ค์จ์ด๋ฅผ ํตํด์ ๊ด๋ฆฌ๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ฒด๋ง์ผ๋ก๋ ๊ฑฐ์ ์๋ฌด ๊ฒ๋ ๋ชปํ๊ธฐ ๋๋ฌธ์ ๊ทธ๊ฑธ ๊ด๋ฆฌํ๋ ์์คํ ๊ณผ ํตํฉ๋ผ ์ ๊ณต๋๋ฉฐ ๋ฐ๋ผ์ ์ ํํ ๋ช ์นญ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ฆฌ ์์คํ DBMS์ด ๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ง ์ ๊ณต๋๋ ๊ฑด CSV ๊ฐ์ด ์์ฃผ ๋จ์ํ ๋ฐ์ดํฐ์ ๊ตญํ๋๋๋ฐ ์ด๊ฑธ ์ง์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๋ ๋ง์ง ์๊ณ ์ด๋ฐ ๋ฐ์ดํฐ๋ฅผ RAW๋ฐ์ดํฐ๋ก ๊ฐ์ฃผํด ๋ค๋ฅธ DBMS์์คํ ์ ์ ์ฌํ๊ณ ์ฌ์ฉํ๋ ๊ฒ ์ผ๋ฐ์ ์ด๋ค.
๊ฐ๋จํ ๋น์ ํ์๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ฒด๋ ํ๋ฌผ(๋ฐ์ดํฐ)์ ์ ์ฅํ ์ ์๋ ์ฐฝ๊ณ ๊ทธ ์์ฒด์ ์ญํ ๋ง ์ํํ๊ณ , ํ๋ฌผ์ ์ ์ฌํ๊ฑฐ๋ ์ ์ฌ๋ ํ๋ฌผ์ ์ฒ๋ฆฌํ ์ ์๋ ๋ฅ๋ ฅ์ ์๋ค. ์ด ๋๋ฌธ์ DBMS๋ผ๋ ๊ด๋ฆฌ์๋ค์ ๊ณ ์ฉํ์ฌ ํ๋ฌผ์ ์ ์ฌํ๊ฑฐ๋ ์ด๋์ํค๋ ๋ฑ ํฌ๋ ์ธ๊ณผ ๊ฐ์ ์ฌ๋ฌ๊ฐ์ง ์ ๋ฌด๋ฅผ ์ํํ๋๋ก ํ๋ ๊ฒ์ด๋ค.
๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค(RDBMS)๊ฐ ๊ฐ์ฅ ๋๋ฆฌ ์ฐ์ด๊ณ ์๋ค. ๊ทธ๋ฆฌ๊ณ ์ด ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ด์ฉํ๊ธฐ ์ํ ํ์ค ์ธ์ด๊ฐ ๋ง๋ค์ด์ ธ ์๋๋ฐ ๊ทธ๊ฒ์ด SQL์ด๋ค. ๊ตฌ์กฐํ ์ง์ ์ธ์ด(Structured Query Language)์ ์ฝ์. ์์ ์๋ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋๋ช ์ฌ์ฒ๋ผ ์ฌ๊ฒจ์ก์ผ๋ ์์ฆ์๋ ๋ค๋ฅธ ํํ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋ง์ด ๋์์๋ค. ๊ฐํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ถ์ถ์ ๊ตญ์๋. ์ด๋ฐ ๋น-๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ NoSQL์ด๋ผ ๋ถ๋ฆฐ๋ค.
SQL์ ์ฌ์ฉํ์ง ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ผ๋ ๋ค์ ์ฅ๋์ค๋ฐ ํํ. ๋ฌผ๋ก ์ ์ ๋ช ์นญ์ ๊ฐ์ ๊ฐ์ง๊ณ ์๋ค. ๊ฐ์ฒดํ, ๋ฌธ์ํ, ์ปฌ๋ผํ ๋ฑ๋ฑ์ด ํด๋น๋๋ค.
๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ด์ฉํ๊ธฐ ์ํด ๋ง๋ค์ด์ง SQL๋ฌธ์ ๋ฐฐ์ ๋๋ฉด ์ฌ๋ฌ๋ชจ๋ก ์ธ ๋ฐ๊ฐ ๋ง๋ค.
์ปดํจํฐ๋ก ํ๋ ์ผ์์ ๋๋ถ๋ถ์ ์ฐจ์งํ๋ ์์ ์ ๋ฐ๋ก ์ ๋ ฌ๊ณผ ํ์์ธ๋ฐ ์ด ๋ ์์ ์ ๊ฐ์ฅ ์ ๋ฌธ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๊ฑด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ด๋ค. ์ปดํจํฐ๋ก ๊ณ์ฐ์ ํ๋ ๊ฒฝ์ฐ๋ ์์ธ๋ก ์ ๋ ฌ๊ณผ ํ์์ ๋นํ๋ฉด ๋น์ค์ด ๋ฎ์ ํธ์ด๋ค.
-
DBMS
๋ฐ์ดํฐ๋ฒ ์ด์ค๋ผ๋ ๋ฐ์ดํฐ์ ์งํฉ์ ๋ง๋ค๊ณ , ์ ์ฅ ๋ฐ ๊ด๋ฆฌํ ์ ์๋ ๊ธฐ๋ฅ๋ค์ ์ ๊ณตํ๋ ์์ฉ ํ๋ก๊ทธ๋จ์ด๋ค. ์ฆ,ย ๋ฐ์ดํฐ์ ๊ด๋ฆฌ์ ํนํ๋ ํ๋ก๊ทธ๋จ์ด๋ผ๊ณ ์๊ฐํ๋ฉด ํธํ๋ค. ์ข ๋ฅ์ ๋ฐ๋ผ DataBase Server๊น์ง ์ง์ํ๊ธฐ๋ ํ๋ค.์ฃผ๋ก ์๋ฒ์ ์ฌ์ฉํ๋ ์ฉ๋๋ง DBMS๋ผ๊ณ ์๊ฐํ๋ ์ค๊ฐ๋ ์ด ๋ง๋ค. ๊ทธ๋ฌ๋ย Microsoft Access๋ผ๋ ๊ฐ์ธ์ฉ ์ปดํจํฐ์ ์ ์ฅํ๋ ์ฉ๋์ ํ๋ก๊ทธ๋จ๋ ํ๋ฅญํ DBMS์ด๋ค.ย ๋ธ๋ฃธ๋ฒ๊ทธย ํฐ๋ฏธ๋ ๊ฐ์ ๊ฒฝ์ฐ๋ ์์ฒด์ ์ผ๋ก DBMS๋ฅผ ๋ด์ฅํ๊ณ ์๋ค.
-
RDBMS
https://cloud.google.com/learn/what-is-a-relational-database?hl=ko
# ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ์
๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค(RDB)๋ ํ ์ด๋ธ, ํ, ์ด์ ์ ๋ณด๋ฅผ ๊ตฌ์กฐํํ๋ ๋ฐฉ์์ ๋๋ค. RDB์๋ ํ ์ด๋ธ์ ์กฐ์ธํ์ฌ ์ ๋ณด ๊ฐ ๊ด๊ณ ๋๋ ๋งํฌ๋ฅผ ์ค์ ํ ์ ์๋ ๊ธฐ๋ฅ์ด ์์ด, ์ฌ๋ฌ ๋ฐ์ดํฐ ํฌ์ธํธ ๊ฐ์ ๊ด๊ณ๋ฅผ ์ฝ๊ฒ ์ดํดํ๊ณ ์ ๋ณด๋ฅผ ์ป์ ์ ์์ต๋๋ค.
# ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ชจ๋ธ
###
1970๋ ๋ IBM์ EF Codd๊ฐ ๊ฐ๋ฐํ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ชจ๋ธ์ ์ฌ์ฉํ๋ฉด ๋ชจ๋ ํ ์ด๋ธ์ ๊ณตํต ์์ฑ์ ์ฌ์ฉํด ๋ค๋ฅธ ํ ์ด๋ธ๊ณผ ์ฐ๊ด์ํฌ ์ ์์ต๋๋ค. Codd๋ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฆฌํ๋ ๋์ ๋ฐ์ดํฐ๊ฐ ํฌํจ๋ ํ ์ด๋ธ์ ์ฌ๊ตฌ์ฑํ์ง ์๊ณ ํ ์ด๋ธ์ ๋ฐ์ดํฐ๊ฐ ์ ์ฅ, ์ก์ธ์ค ๋ฐ ์ฐ๊ฒฐ๋๋ ๋ฐ์ดํฐ ๋ชจ๋ธ์ ์ฌ์ฉํ๋ ๊ฒ์ผ๋ก ์ ํํ ๊ฒ์ ์ ์ํ์ต๋๋ค.
๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋น์ฆ๋์ค์์ ๋ฐ์ดํฐ๋ฅผ ๊ตฌ์ฑ, ๊ด๋ฆฌ, ์ฐ๊ฒฐํ๋ ๋ฐ ๋์์ด ๋๋ ์คํ๋ ๋์ํธ ํ์ผ ๋ชจ์์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋ฉ๋๋ค. ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ชจ๋ธ์์ ๊ฐ โ์คํ๋ ๋์ํธโ๋ ์ด(์์ฑ)๊ณผ ํ(๋ ์ฝ๋ ๋๋ย ํํ)์ผ๋ก ๋ํ๋๋ ์ ๋ณด๋ฅผ ์ ์ฅํ๋ ํ ์ด๋ธ์ ๋๋ค.
์์ฑ(์ด)์ ๋ฐ์ดํฐ ์ ํ์ ์ง์ ํ๋ฉฐ ๊ฐ ๋ ์ฝ๋(๋๋ ํ)๋ ๊ตฌ์ฒด์ ์ธ ๋ฐ์ดํฐ ์ ํ์ ๊ฐ์ ํฌํจํฉ๋๋ค. ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ชจ๋ ํ ์ด๋ธ์๋ ํ์์ ๊ณ ์ ํ๊ฒ ์๋ณ ๊ฐ๋ฅํย ๊ธฐ๋ณธ ํค๋ผ๋ ์์ฑ์ด ์์ผ๋ฉฐ,ย ์ธ๋ ํค(๋ค๋ฅธ ๊ธฐ์กด ํ ์ด๋ธ์ ๊ธฐ๋ณธ ํค๋ฅผ ์ฐธ์กฐ)๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ ํ์์ ์๋ก ๋ค๋ฅธ ํ ์ด๋ธ ๊ฐ์ ๊ด๊ณ๋ฅผ ๋ง๋๋ ๋ฐ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ด์ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ชจ๋ธ์ ์ค์ ์๋ ๋ฐฉ์์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
๊ณ ๊ฐย ํ ์ด๋ธ๊ณผย ์ฃผ๋ฌธย ํ ์ด๋ธ์ด ์๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค.
###
๊ณ ๊ฐย ํ ์ด๋ธ์๋ ๊ณ ๊ฐ์ ๊ดํ ๋ฐ์ดํฐ๊ฐ ํฌํจ๋ฉ๋๋ค.
- ๊ณ ๊ฐ ID(๊ธฐ๋ณธ ํค)
- ๊ณ ๊ฐ ์ด๋ฆ
- ์ฒญ๊ตฌ์ ์์ ์ฃผ์
- ๋ฐฐ์ก์ง ์ฃผ์
๊ณ ๊ฐย ํ ์ด๋ธ์์ ๊ณ ๊ฐ ID๋ ๊ณ ๊ฐ์ด ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๊ณ ์ ํ๊ฒ ์๋ณ๋๋ ๊ธฐ๋ณธ ํค์ ๋๋ค. ๋์ผํ ๊ณ ๊ฐ ID๋ฅผ ๊ฐ์ง๋ ๋ค๋ฅธ ๊ณ ๊ฐ์ ์์ต๋๋ค.
์ฃผ๋ฌธย ํ ์ด๋ธ์๋ ์ฃผ๋ฌธ์ ๊ดํ ๊ฑฐ๋ ์ ๋ณด๊ฐ ํฌํจ๋ฉ๋๋ค.
- ์ฃผ๋ฌธ ID(๊ธฐ๋ณธ ํค)
- ๊ณ ๊ฐ ID(์ธ๋ ํค)
- ์ฃผ๋ฌธ ๋ ์ง
- ๋ฐฐ์ก์ผ
- ์ฃผ๋ฌธ ์ํ
์ฌ๊ธฐ์์ ํน์ ์ฃผ๋ฌธ์ ์๋ณํ๋ ๊ธฐ๋ณธ ํค๋ ์ฃผ๋ฌธ ID์ ๋๋ค. ์ธ๋ ํค๋ฅผ ์ฌ์ฉํ์ฌย ๊ณ ๊ฐย ํ ์ด๋ธ์ ๊ณ ๊ฐ ID๋ฅผ ์ฐ๊ฒฐํ์ฌ ๊ณ ๊ฐ์ ์ฃผ๋ฌธ๊ณผ ์ฐ๊ฒฐํ ์ ์์ต๋๋ค.
์ด์ ๋ ํ ์ด๋ธ์ด ๊ณต์ ๋ ๊ณ ๊ฐ ID๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํฉ๋๋ค. ์ฆ, ๋ ํ ์ด๋ธ์ ์ฟผ๋ฆฌํ์ฌ ๊ณต์ ๋ณด๊ณ ์๋ฅผ ๋ง๋ค๊ฑฐ๋ ๋ค๋ฅธ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ์๋งค ์ง์ ๊ด๋ฆฌ์๋ ํน์ ๋ ์ง์ ๊ตฌ๋งคํ ๋ชจ๋ ๊ณ ๊ฐ์ ๊ดํ ๋ณด๊ณ ์๋ฅผ ์์ฑํ๊ฑฐ๋ ์ง๋ ๋ฌ์ ๋ฐฐ์ก์ผ์ด ์ง์ฐ๋ ์ฃผ๋ฌธ์ ๋ฐ์ ๊ณ ๊ฐ์ ํ์ ํ ์ ์์ต๋๋ค.
์์ ์ค๋ช ์ ๊ฐ๋จํ์ง๋ง, ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋ฐ์ดํฐ ๊ฐ์ ๋งค์ฐ ๋ณต์กํ ๊ด๊ณ๋ฅผ ๋ณด์ฌ์ฃผ๋ ๋ฐ์๋ ํ์ํ๊ธฐ ๋๋ฌธ์ ๋ฐ์ดํฐ๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฌ์ ์ ์๋ ๊ด๊ณํ ์คํค๋ง๋ฅผ ์ค์ํ๋ ํ ๋ ๋ง์ ํ ์ด๋ธ์ ๋ฐ์ดํฐ๋ฅผ ์ฐธ์กฐํ ์ ์์ต๋๋ค.
๋ฐ์ดํฐ๊ฐ ์ฌ์ ์ ์๋ ๊ด๊ณ๋ก ๊ตฌ์ฑ๋๋ฏ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์ธ์ ์ผ๋ก ์ฟผ๋ฆฌํ ์ ์์ต๋๋ค. ์ ์ธ์ ์ฟผ๋ฆฌ๋ ์์คํ ์ด ๊ฒฐ๊ณผ๋ฅผ ์ด๋ป๊ฒ ์ฐ์ฐํด์ผ ํ๋์ง ํํํ์ง ์๊ณ ์์คํ ์์ ์ถ์ถํ ๋ด์ฉ์ ์ ์ํ๋ ๋ฐฉ๋ฒ์ ๋๋ค. ์ด๋ ๋ค๋ฅธ ์์คํ ๊ณผ ๋ฌ๋ฆฌ ๊ด๊ณํ ์์คํ ์ ํต์ฌ์ ๋๋ค.
# ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์
###
์ด์ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์๋ ๋ฐฉ์์ ์ดํดํ์ผ๋ฏ๋ก ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ชจ๋ธ์ ์ฌ์ฉํ๋ ์ฌ๋ฌ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ฆฌ ์์คํ ์ ๋ํด ์์๋ณผ ์ ์์ต๋๋ค. ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ฆฌ ์์คํ (RDBMS)์ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ง๋ค๊ณ ์ ๋ฐ์ดํธํ๊ณ ๊ด๋ฆฌํ๋ ๋ฐ ์ฌ์ฉํ๋ ํ๋ก๊ทธ๋จ์ ๋๋ค. ์ ์๋ ค์ง RDBMS์ ์๋ก๋ MySQL, PostgreSQL, MariaDB, Microsoft SQL Server, Oracle Database๊ฐ ์์ต๋๋ค.
Cloud SQL,ย Cloud Spanner,ย AlloyDB์ ๊ฐ์ ํด๋ผ์ฐ๋ ๊ธฐ๋ฐ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ์ง๋ณด์, ํจ์น, ์ฉ๋ ๊ด๋ฆฌ, ํ๋ก๋น์ ๋, ์ธํ๋ผ ์ง์์ ์ํ ๊ด๋ฆฌํ ์๋น์ค๋ฅผ ์ ๊ณตํ๊ธฐ ๋๋ฌธ์ ์ ์ ๋ ๋ง์ ์ธ๊ธฐ๋ฅผ ์ป๊ณ ์์ต๋๋ค.
์์ํ ์ค๋น๊ฐ ๋์ จ๋์? 10GB ์คํ ๋ฆฌ์ง๋ฅผ ํฌํจํ 90์ผย Cloud Spanner ๋ฌด๋ฃ ์ฒดํํ ์ธ์คํด์ค๋ฅผ ๋ฌด๋ฃ๋ก ๋ง๋์ธ์.
# ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ด์
๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ชจ๋ธ์ ์ฃผ์ ์ด์ ์ ์ง๊ด์ ์ธ ๋ฐ์ดํฐ ํํ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๊ณ ๊ด๋ จ ๋ฐ์ดํฐ ํฌ์ธํธ์ ์ฝ๊ฒ ์ก์ธ์คํ ์ ์๋ค๋ ์ ์ ๋๋ค. ๊ทธ๋์ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ธ๋ฒคํ ๋ฆฌ ์ถ์ ๋ถํฐ ํธ๋์ญ์ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ๋ก๊น ์ ์ด๋ฅด๊ธฐ๊น์ง ๋๋์ ๊ตฌ์กฐํ๋ ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํด์ผ ํ๋ ์กฐ์ง์์ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํฉ๋๋ค.
๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๊ณ ์ ์ฅํ ๋ ๋ค์๊ณผ ๊ฐ์ ์ฌ๋ฌ ๊ฐ์ง ์ฅ์ ์ด ์์ต๋๋ค.
### ์ ์ฐ์ฑ
์ ์ฒด ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ตฌ์กฐ๋ฅผ ๋ณ๊ฒฝํ๊ฑฐ๋ ๊ธฐ์กด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํฅ์ ์ฃผ์ง ์๊ณ ํ์ํ ๋๋ง๋ค ๊ฐํธํ๊ฒ ํ ์ด๋ธ, ๊ด๊ณ๋ฅผ ์ถ๊ฐ ๋๋ ์ญ์ ํ๊ณ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
### ACID ๊ท์ ์ค์
๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ACID(์์์ฑ, ์ผ๊ด์ฑ, ๊ฒฉ๋ฆฌ, ๋ด๊ตฌ์ฑ) ์ฑ๋ฅ์ ์ง์ํ๋ฏ๋ก ์ค๋ฅ, ์คํจ, ๊ธฐํ ์ ์ฌ์ ์ค์๋์ ๊ด๊ณ์์ด ๋ฐ์ดํฐ ์ ํจ์ฑ์ ๊ฒ์ฌํ ์ ์์ต๋๋ค.
### ์ฌ์ฉ ํธ์์ฑ
๊ธฐ์ ์๊ฐ ์๋ ์ฌ์ฉ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ํธ์์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ธ ์ ์๋ SQL์ ์ฌ์ฉํ์ฌ ๋ณต์กํ ์ฟผ๋ฆฌ๋ฅผ ์ฝ๊ฒ ์คํํ ์ ์์ต๋๋ค.
### ๊ณต๋์์
์ฌ๋ฌ ์ฌ์ฉ์๊ฐ ๋์์ ๋ฐ์ดํฐ๋ฅผ ์ด์ํ๊ณ ์ก์ธ์คํ ์ ์์ต๋๋ค. ๊ธฐ๋ณธ ์ ๊ณต๋๋ ์ ๊ธ ๊ธฐ๋ฅ์ผ๋ก ์ ๋ฐ์ดํธ ๋์ค ๋ฐ์ดํฐ์ ๋์ ์ก์ธ์คํ ์ ์์ต๋๋ค.
### ๋ด์ฅ๋ ๋ณด์ ๊ธฐ๋ฅ
์ญํ ๊ธฐ๋ฐ ๋ณด์์ ํตํด ๋ฐ์ดํฐ ์ก์ธ์ค๊ฐ ํน์ ์ฌ์ฉ์๋ก ์ ํ๋ฉ๋๋ค.
### ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ๊ทํ
๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋ฐ์ดํฐ ์ค๋ณต์ฑ์ ์ค์ด๊ณ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ๊ฐ์ ํ๋ ์ ๊ทํ๋ผ๋ ์ค๊ณ ๊ธฐ๋ฒ์ ์ฌ์ฉํฉ๋๋ค.
# ๊ด๊ณํ ๋ฐ ๋น๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค
###
๊ด๊ณํ ๋ฐ ๋น๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค(NoSQL ๋ฐ์ดํฐ๋ฒ ์ด์ค)์ ์ฃผ์ ์ฐจ์ด์ ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ๊ตฌ์ฑํ๋ ๋ฐฉ๋ฒ์ ๋๋ค. ๋น๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๊ท์น ๊ธฐ๋ฐ์ ํ ์ด๋ธ ํ์ ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ์ง ์์ต๋๋ค. ๋์ ๋ฐ์ดํฐ๋ฅผ ์ฐ๊ฒฐ๋์ง ์์ ๊ฐ๋ณ ํ์ผ๋ก ์ ์ฅํ๋ฉฐ, ๋ฌธ์ ๋๋ ๋ฆฌ์น ๋ฏธ๋์ด ํ์ผ๊ณผ ๊ฐ์ ๋ณต์กํ๊ณ ๊ตฌ์กฐํ๋์ง ์์ ๋ฐ์ดํฐ ์ ํ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฌ๋ฆฌ NoSQL ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ ์ฐํ ๋ฐ์ดํฐ ๋ชจ๋ธ์ ๋ฐ๋ฅด๋ฏ๋ก ์์ฃผ ๋ณ๊ฒฝ๋๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ฑฐ๋ ๋ค์ํ ์ ํ์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ํฉํฉ๋๋ค.
-
SQL
https://aws.amazon.com/ko/what-is/sql/
## SQL์ด๋ ๋ฌด์์ธ๊ฐ์?
๊ตฌ์กฐ์ ์ฟผ๋ฆฌ ์ธ์ด(SQL)๋ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๋ณด๋ฅผ ์ ์ฅํ๊ณ ์ฒ๋ฆฌํ๊ธฐ ์ํ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ๋๋ค. ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ ๋ณด๋ฅผ ํ ํ์์ผ๋ก ์ ์ฅํ๋ฉฐ, ํ๊ณผ ์ด์ ๋ค์ํ ๋ฐ์ดํฐ ์์ฑ๊ณผ ๋ฐ์ดํฐ ๊ฐ ๊ฐ์ ๋ค์ํ ๊ด๊ณ๋ฅผ ๋ํ๋ ๋๋ค. SQL ๋ฌธ์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ ๋ณด๋ฅผ ์ ์ฅ, ์ ๋ฐ์ดํธ, ์ ๊ฑฐ, ๊ฒ์ ๋ฐ ๊ฒ์ํ ์ ์์ต๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฑ๋ฅ์ ์ ์ง ๊ด๋ฆฌํ๊ณ ์ต์ ํํ๋ ๋ฐ SQL์ ์ฌ์ฉํ ์๋ ์์ต๋๋ค.
-
UserDefaults
Class UserDefaults
An interface to the userโs defaults database, where you store key-value pairs persistently across launches of your app.
iOS 2.0+iPadOS 2.0+macOS 10.0+Mac Catalyst 13.0+tvOS 9.0+watchOS 2.0+
## Declaration
class UserDefaults : [NSObject](https://developer.apple.com/documentation/objectivec/nsobject)
## Overview
Theย
UserDefaults
ย class provides a programmatic interface for interacting with the defaults system. The defaults system allows an app to customize its behavior to match a userโs preferences. For example, you can allow users to specify their preferred units of measurement or media playback speed. Apps store these preferences by assigning values to a set of parameters in a userโs defaults database. The parameters are referred to asย defaultsย because theyโre commonly used to determine an appโs default state at startup or the way it acts by default.At runtime, you useย
UserDefaults
ย objects to read the defaults that your app uses from a userโs defaults database.ยUserDefaults
ย caches the information to avoid having to open the userโs defaults database each time you need a default value. When you set a default value, itโs changed synchronously within your process, and asynchronously to persistent storage and other processes.Important Donโt try to access the preferences subsystem directly. Modifying preference property list files may result in loss of changes, delay of reflecting changes, and app crashes. To configure preferences, use theย
defaults
ย command-line utility in macOS instead.With the exception of managed devices in educational institutions, a userโs defaults are stored locally on a single device, and persisted for backup and restore. To synchronize preferences and other data across a userโs connected devices, useย
[NSUbiquitousKeyValueStore](https://developer.apple.com/documentation/foundation/nsubiquitouskeyvaluestore)
ย instead.### Storing Default Objects
Theย
UserDefaults
ย class provides convenience methods for accessing common types such as floats, doubles, integers, Boolean values, and URLs. These methods are described inย Setting Default Values.A default object must be a property listโthat is, an instance of (or for collections, a combination of instances of)ย
[NSData](https://developer.apple.com/documentation/foundation/nsdata)
,ย[NSString](https://developer.apple.com/documentation/foundation/nsstring)
,ย[NSNumber](https://developer.apple.com/documentation/foundation/nsnumber)
,ย[NSDate](https://developer.apple.com/documentation/foundation/nsdate)
,ย[NSArray](https://developer.apple.com/documentation/foundation/nsarray)
, orย[NSDictionary](https://developer.apple.com/documentation/foundation/nsdictionary)
. If you want to store any other type of object, you should typically archive it to create an instance ofย NSData.Values returned fromย
UserDefaults
ย are immutable, even if you set a mutable object as the value. For example, if you set a mutable string as the value for โMyStringDefaultโ, the string you later retrieve using theย[string(forKey:)](https://developer.apple.com/documentation/foundation/userdefaults/1416700-string)
ย method will be immutable. If you set a mutable string as a default value and later mutate the string, the default value wonโt reflect the mutated string value unless you callย[set(_:forKey:)](https://developer.apple.com/documentation/foundation/userdefaults/1414067-set)
ย again.For more details, seeย Preferences and Settings Programming Guide.
### Persisting File References
A file URL specifies a location in the file system. If you use theย
[set(_:forKey:)](https://developer.apple.com/documentation/foundation/userdefaults/1414194-set)
ย method to store the location for a particular file and the user moves that file, your app may not be able to locate that file on next launch. To store a reference to a file by its file system identity, you can instead createยNSURL
ย bookmark data using theย[bookmarkData(options:includingResourceValuesForKeys:relativeTo:)](https://developer.apple.com/documentation/foundation/nsurl/1417795-bookmarkdata)
ย method and persist it using theย[set(_:forKey:)](https://developer.apple.com/documentation/foundation/userdefaults/1414067-set)
ย method. You can then use theย[URLByResolvingBookmarkData:options:relativeToURL:bookmarkDataIsStale:error:](https://developer.apple.com/documentation/foundation/nsurl/1572035-urlbyresolvingbookmarkdata)
ย method to resolve the bookmark data stored in user defaults to a file URL.### Responding to Defaults Changes
You can use key-value observing to be notified of any updates to a particular default value. You can also register as an observer forย
[didChangeNotification](https://developer.apple.com/documentation/foundation/userdefaults/1408206-didchangenotification)
ย on theย[default](https://developer.apple.com/documentation/foundation/notificationcenter/1414169-default)
ย notification center in order to be notified of all updates to a local defaults database.For more details, seeย Key-Value Observing Programming Guideย andย Notification Programming Topics.
### Using Defaults in Managed Environments
If your app supports managed environments, you can useย
UserDefaults
ย to determine which preferences are managed by an administrator for the benefit of the user. In a managed environment, such as a computer lab or classroom, an administrator or teacher can configure the systems by establishing a set of default preferences for users. If a preference is managed in this manner (as determined by the methods described inย Accessing Managed Environment Keys), your app should prevent users from editing that preference by disabling or hiding controls.For more details, seeย Mobile Device Management Protocol Reference.
An app running on a device managed by an educational institution can use the iCloud key-value store to share small amounts of data with other instances of itself on the userโs other devices. For example, a textbook app might store the current page number being read by the user so that other instances of the app can open to the same page when launched.
For more information, seeย Storing Preferences in iCloudย inย Preferences and Settings Programming Guide.
### Sandbox Considerations
A sandboxed app cannot access or modify the preferences for any other app, with the following exceptions:
- App extensions on macOS and iOS
- Other apps in your application group on macOS
Adding a third-party appโs domain using theย
[addSuite(named:)](https://developer.apple.com/documentation/foundation/userdefaults/1410294-addsuite)
ย method doesnโt allow your app to access to that appโs preferences. Attempting to access or modify another appโs preferences doesnโt result in an error; instead, macOS reads and writes files located within your appโs container, rather than the actual preference files for the other application.### Thread Safety
Theย UserDefaultsย class is thread-safe.
## Topics
**Getting the Standard User Defaults Object**
[class varย standard: UserDefaults](https://developer.apple.com/documentation/foundation/userdefaults/1416603-standard)
Returns the shared defaults object.
**Creating User Defaults Objects**
[init()](https://developer.apple.com/documentation/foundation/userdefaults/1414356-init)
Creates a user defaults object initialized with the defaults for the app and current user.
[init?(suiteName: String?)](https://developer.apple.com/documentation/foundation/userdefaults/1409957-init)
Creates a user defaults object initialized with the defaults for the specified database name.
**Getting Default Values**
[funcย object(forKey: String) -> Any?](https://developer.apple.com/documentation/foundation/userdefaults/1410095-object)
Returns the object associated with the specified key.
[funcย url(forKey: String) -> URL?](https://developer.apple.com/documentation/foundation/userdefaults/1408648-url)
Returns the URL associated with the specified key.
[funcย array(forKey: String) -> [Any]?](https://developer.apple.com/documentation/foundation/userdefaults/1414792-array)
Returns the array associated with the specified key.
[funcย dictionary(forKey: String) -> [String : Any]?](https://developer.apple.com/documentation/foundation/userdefaults/1408563-dictionary)
Returns the dictionary object associated with the specified key.
[funcย string(forKey: String) -> String?](https://developer.apple.com/documentation/foundation/userdefaults/1416700-string)
Returns the string associated with the specified key.
[funcย stringArray(forKey: String) -> [String]?](https://developer.apple.com/documentation/foundation/userdefaults/1416414-stringarray)
Returns the array of strings associated with the specified key.
[funcย data(forKey: String) -> Data?](https://developer.apple.com/documentation/foundation/userdefaults/1409590-data)
Returns the data object associated with the specified key.
[funcย bool(forKey: String) -> Bool](https://developer.apple.com/documentation/foundation/userdefaults/1416388-bool)
Returns the Boolean value associated with the specified key.
[funcย integer(forKey: String) -> Int](https://developer.apple.com/documentation/foundation/userdefaults/1407405-integer)
Returns the integer value associated with the specified key.
[funcย float(forKey: String) -> Float](https://developer.apple.com/documentation/foundation/userdefaults/1414027-float)
Returns the float value associated with the specified key.
[funcย double(forKey: String) -> Double](https://developer.apple.com/documentation/foundation/userdefaults/1416581-double)
Returns the double value associated with the specified key.
[funcย dictionaryRepresentation() -> [String : Any]](https://developer.apple.com/documentation/foundation/userdefaults/1415919-dictionaryrepresentation)
Returns a dictionary that contains a union of all key-value pairs in the domains in the search list.
**Setting Default Values**
[funcย set(Any?,ย forKey: String)](https://developer.apple.com/documentation/foundation/userdefaults/1414067-set)
Sets the value of the specified default key.
[funcย set(Float,ย forKey: String)](https://developer.apple.com/documentation/foundation/userdefaults/1413320-set)
Sets the value of the specified default key to the specified float value.
[funcย set(Double,ย forKey: String)](https://developer.apple.com/documentation/foundation/userdefaults/1408646-set)
Sets the value of the specified default key to the double value.
[funcย set(Int,ย forKey: String)](https://developer.apple.com/documentation/foundation/userdefaults/1413614-set)
Sets the value of the specified default key to the specified integer value.
[funcย set(Bool,ย forKey: String)](https://developer.apple.com/documentation/foundation/userdefaults/1408905-set)
Sets the value of the specified default key to the specified Boolean value.
[funcย set(URL?,ย forKey: String)](https://developer.apple.com/documentation/foundation/userdefaults/1414194-set)
Sets the value of the specified default key to the specified URL.
**Removing Defaults**
[funcย removeObject(forKey: String)](https://developer.apple.com/documentation/foundation/userdefaults/1411182-removeobject)
Removes the value of the specified default key.
**Maintaining Suites**
[funcย addSuite(named: String)](https://developer.apple.com/documentation/foundation/userdefaults/1410294-addsuite)
Inserts the specified domain name into the receiverโs search list.
[funcย removeSuite(named: String)](https://developer.apple.com/documentation/foundation/userdefaults/1408047-removesuite)
Removes the specified domain name from the receiverโs search list.
**Registering Defaults**
[funcย register(defaults: [String : Any])](https://developer.apple.com/documentation/foundation/userdefaults/1417065-register)
Adds the contents of the specified dictionary to the registration domain.
**Maintaining Persistent Domains**
[funcย persistentDomain(forName: String) -> [String : Any]?](https://developer.apple.com/documentation/foundation/userdefaults/1412197-persistentdomain)
Returns a dictionary representation of the defaults for the specified domain.
[funcย setPersistentDomain([String : Any],ย forName: String)](https://developer.apple.com/documentation/foundation/userdefaults/1408187-setpersistentdomain)
Sets a dictionary for the specified persistent domain.
[funcย removePersistentDomain(forName: String)](https://developer.apple.com/documentation/foundation/userdefaults/1417339-removepersistentdomain)
Removes the contents of the specified persistent domain from the userโs defaults.
~~[funcย persistentDomainNames() -> [Any]](https://developer.apple.com/documentation/foundation/userdefaults/1589081-persistentdomainnames)~~
Returns an array of the current persistent domain names.
Deprecated
**Maintaining Volatile Domains**
[varย volatileDomainNames: [String]](https://developer.apple.com/documentation/foundation/userdefaults/1414231-volatiledomainnames)
The current volatile domain names.
[funcย volatileDomain(forName: String) -> [String : Any]](https://developer.apple.com/documentation/foundation/userdefaults/1409592-volatiledomain)
Returns the dictionary for the specified volatile domain.
[funcย setVolatileDomain([String : Any],ย forName: String)](https://developer.apple.com/documentation/foundation/userdefaults/1413720-setvolatiledomain)
Sets the dictionary for the specified volatile domain.
[funcย removeVolatileDomain(forName: String)](https://developer.apple.com/documentation/foundation/userdefaults/1415955-removevolatiledomain)
Removes the specified volatile domain from the userโs defaults.
**Accessing Managed Environment Keys**
[funcย objectIsForced(forKey: String) -> Bool](https://developer.apple.com/documentation/foundation/userdefaults/1408635-objectisforced)
Returns a Boolean value indicating whether the specified key is managed by an administrator.
[funcย objectIsForced(forKey: String,ย inDomain: String) -> Bool](https://developer.apple.com/documentation/foundation/userdefaults/1416306-objectisforced)
Returns a Boolean value indicating whether the key in the specified domain is managed by an administrator.
**Domains**
[class letย argumentDomain: String](https://developer.apple.com/documentation/foundation/userdefaults/1410665-argumentdomain)
The domain consisting of defaults parsed from the applicationโs arguments. These are one or more pairs of the formย -default valueย included in the command-line invocation of the application.
[class letย globalDomain: String](https://developer.apple.com/documentation/foundation/userdefaults/1407355-globaldomain)
The domain consisting of defaults meant to be seen by all applications.
[class letย registrationDomain: String](https://developer.apple.com/documentation/foundation/userdefaults/1415953-registrationdomain)
The domain consisting of a set of temporary defaults whose values can be set by the application to ensure that searches will always be successful.
**Notifications**
[class letย didChangeNotification: NSNotification.Name](https://developer.apple.com/documentation/foundation/userdefaults/1408206-didchangenotification)
Posted when user defaults are changed within the current process.
[class letย sizeLimitExceededNotification: NSNotification.Name](https://developer.apple.com/documentation/foundation/userdefaults/1617187-sizelimitexceedednotification)
Posted when more data is stored in user defaults than is allowed.
[class letย completedInitialCloudSyncNotification: NSNotification.Name](https://developer.apple.com/documentation/foundation/userdefaults/1617169-completedinitialcloudsyncnotific)
Posted when ubiquitous defaults finish downloading data, either the first time a device is connected to an iCloud account or when a user switches their primary iCloud account.
[class letย didChangeCloudAccountsNotification: NSNotification.Name](https://developer.apple.com/documentation/foundation/userdefaults/1617438-didchangecloudaccountsnotificati)
Posted when the user changes the primary iCloud account.
[class letย noCloudAccountNotification: NSNotification.Name](https://developer.apple.com/documentation/foundation/userdefaults/1648504-nocloudaccountnotification)
Posted when a cloud default is set, but no iCloud user is logged in.
-
dictionary
tructure Dictionary
A collection whose elements are key-value pairs.
iOS 8.0+iPadOS 8.0+macOS 10.10+Mac Catalyst 13.0+tvOS 9.0+watchOS 2.0+
## Declaration
@frozen struct Dictionary<Key, Value> where Key : [Hashable](https://developer.apple.com/documentation/swift/hashable)
## Overview
A dictionary is a type of hash table, providing fast access to the entries it contains. Each entry in the table is identified using its key, which is a hashable type such as a string or number. You use that key to retrieve the corresponding value, which can be any object. In other languages, similar data types are known as hashes or associated arrays.
Create a new dictionary by using a dictionary literal. A dictionary literal is a comma-separated list of key-value pairs, in which a colon separates each key from its associated value, surrounded by square brackets. You can assign a dictionary literal to a variable or constant or pass it to a function that expects a dictionary.
Hereโs how you would create a dictionary of HTTP response codes and their related messages:
var responseMessages = [200: "OK", 403: "Access forbidden", 404: "File not found", 500: "Internal server error"]
Theย
responseMessages
ย variable is inferred to have typeย[Int: String]
. TheยKey
ย type of the dictionary isยInt
, and theยValue
ย type of the dictionary isยString
.To create a dictionary with no key-value pairs, use an empty dictionary literal (
[:]
).var emptyDict: [String: String] = [:]
Any type that conforms to theย
Hashable
ย protocol can be used as a dictionaryโsยKey
ย type, including all of Swiftโs basic types. You can use your own custom types as dictionary keys by making them conform to theยHashable
ย protocol.# Getting and Setting Dictionary Values
The most common way to access values in a dictionary is to use a key as a subscript. Subscripting with a key takes the following form:
print(responseMessages[200])// Prints "Optional("OK")"
Subscripting a dictionary with a key returns an optional value, because a dictionary might not hold a value for the key that you use in the subscript.
The next example uses key-based subscripting of theย
responseMessages
ย dictionary with two keys that exist in the dictionary and one that does not.let httpResponseCodes = [200, 403, 301]for code in httpResponseCodes { if let message = responseMessages[code] { print("Response \(code): \(message)") } else { print("Unknown response \(code)") }}// Prints "Response 200: OK"// Prints "Response 403: Access forbidden"// Prints "Unknown response 301"
You can also update, modify, or remove keys and values from a dictionary using the key-based subscript. To add a new key-value pair, assign a value to a key that isnโt yet a part of the dictionary.
responseMessages[301] = "Moved permanently"print(responseMessages[301])// Prints "Optional("Moved permanently")"
Update an existing value by assigning a new value to a key that already exists in the dictionary. If you assignย
nil
ย to an existing key, the key and its associated value are removed. The following example updates the value for theย404
ย code to be simply โNot foundโ and removes the key-value pair for theย500
ย code entirely.responseMessages[404] = "Not found"responseMessages[500] = nilprint(responseMessages)// Prints "[301: "Moved permanently", 200: "OK", 403: "Access forbidden", 404: "Not found"]"
In a mutableย
Dictionary
ย instance, you can modify in place a value that youโve accessed through a keyed subscript. The code sample below declares a dictionary calledยinterestingNumbers
ย with string keys and values that are integer arrays, then sorts each array in-place in descending order.var interestingNumbers = ["primes": [2, 3, 5, 7, 11, 13, 17], "triangular": [1, 3, 6, 10, 15, 21, 28], "hexagonal": [1, 6, 15, 28, 45, 66, 91]]for key in interestingNumbers.keys { interestingNumbers[key]?.sort(by: >)} print(interestingNumbers["primes"]!)// Prints "[17, 13, 11, 7, 5, 3, 2]"
# Iterating Over the Contents of a Dictionary
Every dictionary is an unordered collection of key-value pairs. You can iterate over a dictionary using aย
for
-in
ย loop, decomposing each key-value pair into the elements of a tuple.let imagePaths = ["star": "/glyphs/star.png", "portrait": "/images/content/portrait.jpg", "spacer": "/images/shared/spacer.gif"] for (name, path) in imagePaths { print("The path to '\(name)' is '\(path)'.")}// Prints "The path to 'star' is '/glyphs/star.png'."// Prints "The path to 'portrait' is '/images/content/portrait.jpg'."// Prints "The path to 'spacer' is '/images/shared/spacer.gif'."
The order of key-value pairs in a dictionary is stable between mutations but is otherwise unpredictable. If you need an ordered collection of key-value pairs and donโt need the fast key lookup thatย
Dictionary
ย provides, see theยKeyValuePairs
ย type for an alternative.You can search a dictionaryโs contents for a particular value using theย
contains(where:)
ย orยfirstIndex(where:)
ย methods supplied by default implementation. The following example checks to see ifยimagePaths
ย contains any paths in theย"/glyphs"
ย directory:let glyphIndex = imagePaths.firstIndex(where: { $0.value.hasPrefix("/glyphs") })if let index = glyphIndex { print("The '\(imagePaths[index].key)' image is a glyph.")} else { print("No glyphs found!")}// Prints "The 'star' image is a glyph.")
Note that in this example,ย
imagePaths
ย is subscripted using a dictionary index. Unlike the key-based subscript, the index-based subscript returns the corresponding key-value pair as a non-optional tuple.print(imagePaths[glyphIndex!])// Prints "(key: "star", value: "/glyphs/star.png")"
A dictionaryโs indices stay valid across additions to the dictionary as long as the dictionary has enough capacity to store the added values without allocating more buffer. When a dictionary outgrows its buffer, existing indices may be invalidated without any notification.
When you know how many new values youโre adding to a dictionary, use theย
init(minimumCapacity:)
ย initializer to allocate the correct amount of buffer.
๐ขย 7์ฃผ์ฐจ ์์ ํ๊ธฐ
- 7์ฃผ์ฐจ ์์ ์ ๋ฃ๊ณ ์๋ก ๋๋ ์ ์ ์ด์ผ๊ธฐํด์ฃผ์ธ์!
- ํต์ฌ ํค์๋์ ๋ํด ์๋ฒฝํ๊ฒ ์ดํดํ๋์ง? ํน์ ์ดํด๊ฐ ์ ๋๋ ๋ถ๋ถ์ ๋ญ์๋์ง? ์๋ก ์ด์ผ๊ธฐํด์ฃผ์ธ์!
UserDefaults๋ ์ด์ ๋ฏธ์ ์์๋ ๋ช ๋ฒ ์ฌ์ฉํ ์ ์ด ์์ด ์ฝ๊ฒ ์ดํดํ๋ค.
ํํ๊ณผ ๋์ ๋๋ฆฌ ํ์ฉ ๋ฐฉ๋ฒ์ด ์์์ด ๋ง์์ ๊ด๋ จ ๊ฒฝํ์ด ๋ง์ ์๋ก ์ข์ ๊ฒ ๊ฐ๋ค.
โ ๏ธย ์คํฐ๋๊ฐ ์ฃผ์์ฌํญ
- ๊ณผ์ ํผ๋๋ฐฑ ๊ธฐ๋ฐ ์งํ์ ๋๋ค - ํ๋ช ์ฉ ๋ณธ์ธ์ ๊ณผ์ ๋ฅผ ๋ฐํํ๋ ์๊ฐ ๊ทธ๋ฆฌ๊ณ ํด์จ ๊ณผ์ ์ ๋ํ ํผ๋๋ฐฑ์ ํ๋ ์๊ฐ (ex:์ ์ด๋ ๊ฒ ์๊ฐํด์ ์ด๋ฐ ๋ถ๋ถ ๋ค๋ฅด๊ฒ ํด์๋๋ฐ ์ ๊ฒ๋ ๊ด์ฐฎ์ ๊ฒ ๊ฐ์์!)์ด ๋ฌด์กฐ๊ฑด ๊ธฐ๋ฐ์ด ๋์ด์ผ ํฉ๋๋ค!
- ๋ถ๊ฐ์ ์ผ๋ก ์ํฌ๋ถ์์ ์ ๊ณต๋๋ ํค์๋ ํน์ ๊ฐ์์์ ๋ค์ ๋ํ ์ผ์ ์ธ ๋ถ๋ถ์์ ๋ ํ ์ํด๋ด๋ ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
โ ย ์ค์ต ์ฒดํฌ๋ฆฌ์คํธ
-
dictionary์ ์ ์์ ์คํ ์๋ฆฌ๋ฅผ ์ดํดํ๋์?
-
UserDefaults๋ฅผ ์ฌ์ฉํ์ฌ ํ์๊ฐ์ ๊ณผ ๋ก๊ทธ์ธ ๋ก์ง์ ๊ตฌํํ๋์?
-
ํ์๊ฐ์ ๊ณผ ๋ก๊ทธ์ธ ๊ธฐ๋ฅ์ด ์ ์์ ์ผ๋ก ๋์ํ๋ ๊ฒ์ ํ์ธํ๋์?
-
ํ์๊ฐ์ ๊ณผ ๋ก๊ทธ์ธ์ ๋ํ ์์ธ์ฒ๋ฆฌ ์ฝ๋ ๋ฐ ๋ก์ง์ ์ดํดํ๋์?
-
๋ฏธ์ ์ฐธ๊ณ ์์
โก ํธ๋ฌ๋ธ ์ํ
-
โก์ด์ No.1 (์์, ์์๋ง ๋ณต์ฌํ์๊ณ ์ง์์ฃผ์ธ์.)
์ด์
๐ ์ฑ ์คํ ์ค์ ๋ ธ๋ ๋ค์ ๋ฒํผ์ ๋๋ฅด๋๊น ์ฑ์ด ์ข ๋ฃ๋์๋ค.
๋ฌธ์
๐ ๋ ธ๋ํด๋์ค์ ๋ฐ์ดํฐ๋ฆฌ์คํธ์ Size๋ฅผ ๋์ด์ NullPointException์ด ๋ฐ์ํ์ฌ ์ฑ์ด ์ข ๋ฃ๋ ๊ฒ์ด์๋ค.
ํด๊ฒฐ
๐ ๋ ธ๋ ๋ค์ ๋ฒํผ์ ๋๋ ์ ๋ ๋ฐ์ดํฐ๋ฆฌ์คํธ์ Size๋ฅผ ๊ฒ์ฌํด Size๋ณด๋ค ๋์ด๊ฐ๋ ค๊ณ ํ๋ฉด ๋ค์์ผ๋ก ๋์ด๊ฐ๋ ๋ฉ์๋๋ฅผ ์คํ์ํค์ง ์๊ณ , ์ฒซ ๋ ธ๋๋ก ๋์๊ฐ๊ฒ๋ ํด๊ฒฐ
์ฐธ๊ณ ๋ ํผ๋ฐ์ค
- ๋งํฌ
๐คย ์ด๊ฒ๋ ํ ๋ฒ ์๊ฐํด๋ด์!
-
DB ํน์ฑ์ ๋ํด ์๊ฐํด๋ณด์ธ์! (ex ์์์ฑ)
-
dictionary์ ๋ฌธ๋ฒ๊ณผ ์๋ฃ๊ตฌ์กฐ์ ๋ํด ๊ณต๋ถํด๋ณด์ธ์!
-
UserDefaults์ ๋ค๋ฅธ ์ต์ ๋ ๊ณต๋ถํด๋ณด์ธ์!
-
JSON์ ๋ํด ๊ณต๋ถํด๋ณด์ธ์!
-
์๋ฒ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ios๋ ์ด๋ป๊ฒ ์ํตํ ์ง ์๊ฐํด๋ณด์ธ์!
-
UserDefaults ๋ณด๋ค ๋ ์ ์ฉํ ์์ฒด DB๋ ์์์ง ์กฐ์ฌํด๋ณด์ธ์! (ex. CoreData, Realm, FireBase)7wnck
์คํ ๋ค๋ ๋ฏธ์ ๐
์๋๋ 6์ฃผ์ฐจ ์ฑ์ผ๋ก ์ ์ฉํด๋ณด๋ ค๊ณ ํ์ง๋ง
unable to open dependencies file ์ด๋ผ๋ ์ ์ฒด๋ชจ๋ฅผ ์๋ฌ๊ฐ 7๊ฐ๋ ๋ฌ ๊ด๊ณ๋ก
(์ด๋ป๊ฒ๋ ๊ณ ์ณ๋ณด๋ ค๊ณ pod ๋ ์ ๋ฐ์ดํธ ํด๋ณด๊ณ , ๊ตฌ๊ธ๋งํ target ์ค์ ๋ ๋ฐ๊ฟ๋ณด์๋๋ฐ๋ ํด๊ฒฐ ๋ชป ํจ. ๊ฒฐ๊ตญ xcode๋ฅผ ๋ค์ ์ง์ ๋ค๊ฐ ๊น์๋ณด๋ ์ ์ ์๋, ์๋ง xcode ์ ๋ฐ์ดํธ ์์์ ๋ญ๊ฐ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๋ฏ ํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ฌ์ ํ 6์ฃผ์ฐจ ํ์ผ์ด ์๋์ ์ํ๋ค)
์์ ์ ํ ๋ฒ ๋ง๋ค์ด ๋์ ๋ฝ๋ชจ๋๋ก ์ฑ์ userDefaults๋ฅผ ์ ์ฉํด ๋ณด์๋ค.
import UIKit
import AudioToolbox
enum TimerStatus {
case start
case pause
case end
}
class ViewController: UIViewController {
@IBOutlet weak var timerLabel: UILabel!
@IBOutlet weak var progessView: UIProgressView!
@IBOutlet weak var datePicker: UIDatePicker!
@IBOutlet weak var cancelButton: UIButton!
@IBOutlet weak var toggleButton: UIButton!
@IBOutlet weak var imageView: UIImageView!
var duration = 60
var timerStatus: TimerStatus = .end
var timer: DispatchSourceTimer?
var currentSeconds = 0
var clockRecord: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
self.configureToggleButton()
}
func setTimerInfoViewVisible(isHidden: Bool){
self.timerLabel.isHidden = isHidden
self.progessView.isHidden = isHidden
}
func configureToggleButton(){
self.toggleButton.setTitle("์์", for: .normal)
self.toggleButton.setTitle("์ผ์์ ์ง", for: .selected)
}
func startTimer() {
if self.timer == nil {
self.timer = DispatchSource.makeTimerSource(flags: [], queue: .main)
self.timer?.schedule(deadline: .now(), repeating: 1)
self.timer?.setEventHandler(handler: { [weak self] in
guard let self = self else { return }
self.currentSeconds -= 1
let hour = self.currentSeconds / 3600
let minute = (self.currentSeconds % 3600) / 60
let seconds = (self.currentSeconds % 3600) % 60
self.timerLabel.text = String(format: "%02d:%02d:%02d", hour, minute, seconds)
self.progessView.progress = Float(self.currentSeconds) / Float(self.duration)
UIView.animate(withDuration: 0.5, delay: 0, animations: {
self.imageView.transform = CGAffineTransform(rotationAngle: .pi)
})
UIView.animate(withDuration: 0.5, delay: 0.5, animations: {
self.imageView.transform = CGAffineTransform(rotationAngle: .pi * 2)
})
if self.currentSeconds <= 0 {
self.stopTimer()
AudioServicesPlaySystemSound(1005)
}
})
self.timer?.resume()
}
}
func stopTimer(){
if self.timerStatus == .pause {
self.timer?.resume()
}
self.timerStatus = .end
self.cancelButton.isEnabled = false
UIView.animate(withDuration: 0.5, animations: {
self.timerLabel.alpha = 0
self.progessView.alpha = 0
self.datePicker.alpha = 1
self.imageView.transform = .identity
})
self.toggleButton.isSelected = false
self.timer?.cancel()
self.timer = nil
}
@IBAction func tapCancelButton(_ sender: UIButton) {
switch self.timerStatus {
case .start, .pause:
self.stopTimer()
default:
break
}
}
@IBAction func tapToggleButton(_ sender: UIButton) {
self.duration = Int(self.datePicker.countDownDuration)
self.clockRecord.append(String(self.duration))
UserDefaults.standard.set(self.clockRecord, forKey: "clockRecord")
switch self.timerStatus {
case .end:
self.currentSeconds = self.duration
self.timerStatus = .start
UIView.animate(withDuration: 0.5, animations: {
self.timerLabel.alpha = 1
self.progessView.alpha = 1
self.datePicker.alpha = 0
})
self.toggleButton.isSelected = true
self.cancelButton.isEnabled = true
self.startTimer()
case .start:
self.timerStatus = .pause
self.toggleButton.isSelected = false
self.timer?.suspend()
case .pause:
self.timerStatus = .start
self.toggleButton.isSelected = true
self.timer?.resume()
}
}
}
import UIKit
class recordViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
var timeRecord: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
guard let clockRecord: [String] = UserDefaults.standard.stringArray(forKey: "clockRecord") else {return}
timeRecord = clockRecord
tableView.dataSource = self
}
}
extension recordViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection: Int) -> Int {
return timeRecord.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = timeRecord[indexPath.row]
return cell
}
}
ํ ๊ธ๋ฒํผ์ ๋๋ฅผ ๋๋ง๋ค userDefaults์ ์ ์ฅํ ์ ์๋๋ก ํด์, ๊ทธ๋์ ์ค์ ํ ํ์ duration์ ๋ณผ ์ ์๋๋ก ํ๋ค.
์ค์ ๋ก 1๋ถ์ ์ ์ฉํ๋ฉด ํ ์ด๋ธ ๋ทฐ์ ์ด๋ ๊ฒ ๊ธฐ๋ก๋๋ค.
3๋ถ์ ์ ์ฉํ๋ฉด
์ด๋ ๊ฒ ๋ฐ๋๊ณ
์ฑ์ ๊ป๋ค๊ฐ ์ผ๋
์๋ฒฝํ๊ฒ ์ ์ง!
๋๊ธ๋จ๊ธฐ๊ธฐ