4.7 Databases#

๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ํฌ๊ฒŒ RDBMS์™€ NoSQL(Not only SQL)๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„œ๋Š” ๊ทธ ์ค‘ NoSQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ข…๋ฅ˜ ๋ฐ ํŠน์ง•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.

Key-Value Store (KVS)#

Key-Value Store (KVS) ๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ key - value ์Œ์œผ๋กœ ์ €์žฅํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ, ํ•ด์‹œ ํ•จ์ˆ˜๋‚˜ python์—์„œ์˜ dictionary ํ˜•์‹๊ณผ ์œ ์‚ฌํ•œ ํ˜•ํƒœ๋กœ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ operation#

  • PUT: ์ƒˆ๋กœ์šด key - value ์Œ์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค. (์ด๋ฏธ ํ•ด๋‹น key๊ฐ€ ์กด์žฌํ•  ๊ฒฝ์šฐ์—๋Š” value๋ฅผ ์—…๋ฐ์ดํŠธ ํ•ฉ๋‹ˆ๋‹ค.)

  • GET: ์ฃผ์–ด์ง„ key์— ๋Œ€ํ•œ value๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

  • DELETE: ํ•ด๋‹น key๊ฐ€ ์กด์žฌํ•  ๊ฒฝ์šฐ, key - value ์Œ์„ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.

์žฅ์ #

  • value์— ๋Œ€ํ•œ data type ์ œ์•ฝ์ด ์—†์Šต๋‹ˆ๋‹ค.

  • value์— ๊ฐ๊ฐ ๋‹ค๋ฅธ ์†์„ฑ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

    user:123:preferences = {"language": "ko"}
    user:123:preferences = {"language": "en", "color": "blue"}
    

๋‹จ์ #

  • key์— ์˜ํ•ด์„œ๋งŒ ๊ฐ’์„ ์ฐพ์•„์•ผ ํ•˜๋ฏ€๋กœ, key ๊ฐ’์„ ์•Œ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

  • ์ด๋ฅผ ์œ„ํ•ด value ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ฑฐ๋‚˜, ๋ณด์กฐ ์ธ๋ฑ์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ ์˜ˆ์‹œ#

  • ์œ ์ €๋ณ„ ์„ธ์…˜ ์ •๋ณด ์ €์žฅ (key : ์„ธ์…˜ ID / value : ์„ธ์…˜ ์ •๋ณด)

  • ์œ ์ €๋ณ„ ํ”„๋กœํ•„ ๋ฐ ๊ธฐ๋ณธ ์„ค์ • (key: ์œ ์ € ID / value : ์œ ์ € ์ •๋ณด)

  • ์œ ์ €๋ณ„ ์ถ”์ฒœ, ๊ด‘๊ณ  ๋“ฑ (key: ์œ ์ € ID / value : ํ•ด๋‹น ์œ ์ €์— ์ ํ•ฉํ•œ ์ถ”์ฒœ ์•„์ดํ…œ ๋ฐ ๊ด‘๊ณ  ๋“ฑ)

Top 10 Key-Value Stores#

๊ทธ๋ ‡๋‹ค๋ฉด ์–ด๋–ค Key-Value Store๊ฐ€ ๋งŽ์ด ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์„๊นŒ์š”?
https://db-engines.com๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ Top 10 Key-Value Stores๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

kvs_rank (์ถœ์ฒ˜: https://db-engines.com/en/ranking/key-value+store)

Redis#

๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” KVS๋Š” ๋ฐ”๋กœ Redis(Remote Dictionary Server) ์ž…๋‹ˆ๋‹ค.
Twitter, Pinterest, stackoverflow ๋“ฑ ๋‹ค์–‘ํ•œ ํšŒ์‚ฌ์—์„œ๋„ ์œ ์ €๋ณ„ ์„ธ์…˜ ์ •๋ณด ์ €์žฅ ์‹œ ์ด์šฉํ•˜๊ณ  ์žˆ๋Š” Redis๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํŠน์ง•์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

  • in-memory ๊ตฌ์กฐ

    • ๋ฐ์ดํ„ฐ๋ฅผ ๋””์Šคํฌ์— ์ €์žฅํ•˜์ง€ ์•Š๊ณ  ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋น ๋ฅธ ์†๋„๋ฅผ ๋ณด์žฅํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

    • ์ถ”๊ฐ€๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋””์Šคํฌ์— ์œ ์ง€ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋น„๋™๊ธฐ ๋ณต์ œ ์ œ๊ณต

    • ๋ฐ์ดํ„ฐ๊ฐ€ ๊ธฐ๋ณธ ์Šคํ† ๋ฆฌ์ง€์— ๋จผ์ € ์ €์žฅ๋œ ๋’ค, ๋ณต์ œ๋ณธ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

Oracle Berkeley DB#

(์ธ๊ธฐ ์žˆ๋Š” DB๋Š” ์•„๋‹ˆ์ง€๋งŒ) ํ˜„์—…์—์„œ ๋งŽ์ด ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” KVS ์ค‘ ํ•˜๋‚˜๋กœ Oracle Berkeley DB๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ํ˜„์—…์—์„œ ๊ฐ„๋‹จํ•œ ๋ฐ์ดํ„ฐ ์ •์ œ ์‹œ key๋ณ„ value ์ •๋ณด๊ฐ€ ํ•„์š”ํ•  ๊ฒฝ์šฐ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ž„๋ฒ ๋””๋“œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ, sqlite์™€ ๊ฐ™์ด ํŒŒ์ผ ํ˜•์‹์œผ๋กœ DB๊ฐ€ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

  • ๋‹ค๋งŒ ๋ณ‘๋ ฌ ์ ‘๊ทผ ์‹œ ์†๋„๊ฐ€ ๋งค์šฐ ๋Š๋ ค์ง„๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์œผ๋ฉฐ, ์ด๋Ÿฌํ•œ ์ ์ด ๋ณด์™„๋œ RocksDB ๋“ฑ์ด ์ œ์‹œ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


Wide-Column Store (Column-family Store)#

Google BigTable ์—์„œ ์œ ๋ž˜๋œ Wide-Column Store(Column-family Store)๋Š” row key์™€ column name์˜ ์กฐํ•ฉ์œผ๋กœ ๊ฐ’์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
wide_column
RDBMS์™€ ์œ ์‚ฌํ•œ ํ˜•ํƒœ๋กœ ๋ณผ ์ˆ˜ ์žˆ์ง€๋งŒ, column์ด ์ง€์ •๋˜์ง€ ์•Š๊ณ  ์ž์œ ๋กญ๊ฒŒ ์ž…๋ ฅ๋  ์ˆ˜ ์žˆ๋Š” ํ˜•ํƒœ๋กœ ๋˜์–ด ์žˆ๋‹ค๋Š” ์ฐจ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์žฅ์ #

  • row๋งˆ๋‹ค ๋‹ค๋ฅธ column ๊ฐœ์ˆ˜๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๊ณ , ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค ์›ํ•˜๋Š” column ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • RDBMS์—์„œ๋Š” ํŠน์ • column ๊ฐ’์ด ์—†์„ ๋•Œ default value๋ฅผ ๋„ฃ์–ด์•ผ ํ–ˆ์ง€๋งŒ,
    Wide-Column Store์—์„œ๋Š” ํŠน์ • column์— ๋Œ€ํ•ด default ๊ฐ’์œผ๋กœ ์ฑ„์šฐ์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค.

  • ํ•„์š”ํ•œ column ์ •๋ณด๋งŒ ์“ฐ๋ฉด ๋˜๊ณ  ํŠน์ • column์— ํ•ด๋‹นํ•˜๋Š” ๋ฐ์ดํ„ฐ๋งŒ ์ฝ์œผ๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ฒ˜๋ฆฌ ์†๋„๊ฐ€ ๋น ๋ฆ…๋‹ˆ๋‹ค.

๋‹จ์ #

  • multi-row ํŠธ๋žœ์žญ์…˜์„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • join, subquery ๋“ฑ ๋˜ํ•œ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ ์˜ˆ์‹œ#

  • event logging: ์ด๋ฒคํŠธ๋ณ„ ์‚ฌ์šฉ์ž ๋กœ๊ทธ ๋‚ด์—ญ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์˜ค๋ฅ˜ ๋‚ด์—ญ ๋“ฑ์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

  • ์ปจํ…์ธ  ๊ด€๋ฆฌ ์‹œ์Šคํ…œ: ์ปจํ…์ธ ๋ณ„ ๋Œ“๊ธ€, ๋งํฌ, ํƒœ๊ทธ ๋“ฑ์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

Top 10 Wide-Column Stores#

๊ทธ๋ ‡๋‹ค๋ฉด ์–ด๋–ค Wide-Column Store๊ฐ€ ๋งŽ์ด ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์„๊นŒ์š”?
Key-Value Store์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ https://db-engines.com์—์„œ Top 10 Wide-Column Stores๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

wide_column_rank (์ถœ์ฒ˜: https://db-engines.com/en/ranking/wide+column+store)

Cassandra#

  • ํŽ˜์ด์Šค๋ถ์—์„œ ๊ฐœ๋ฐœ๋˜๊ณ  ์• ํ”Œ, ๋„ทํ”Œ๋ฆญ์Šค, ์šฐ๋ฒ„ ๋“ฑ์—์„œ ์ด์šฉ์ค‘์ธ Cassandra๋Š” ์•„ํŒŒ์น˜ ์žฌ๋‹จ์—์„œ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๋Š” ์˜คํ”ˆ์†Œ์Šค์ž…๋‹ˆ๋‹ค.

  • ๋ฐ์ดํ„ฐ๊ฐ€ ๋…ธ๋“œ์— ๋ถ„์‚ฐ๋˜์–ด ์ €์žฅ๋˜๋ฏ€๋กœ ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์ˆ˜ํ‰์ ์œผ๋กœ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Cassandra ์ „์šฉ ์ฟผ๋ฆฌ ์–ธ์–ด์ธ CQL(Cassandra Query Language)์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
    ์ด๋Š” SQL๊ณผ ๋น„์Šทํ•˜์ง€๋งŒ join ๋ฐ subquery๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š๊ณ  ์™ธ๋ž˜ ํ‚ค๊ฐ€ ์—†๋‹ค๋Š” ํŠน์ง•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

    // ํ…Œ์ด๋ธ” ์ƒ์„ฑ
    CREATE TABLE users (
        user_id uuid PRIMARY KEY,
        first_name text,
        last_name text,
        email text,
        password text,
        created_at timestamp
    );
    
    // ๋ฐ์ดํ„ฐ ์‚ฝ์ž…
    INSERT INTO users (user_id, first_name, last_name, email, password, created_at) VALUES 
        (uuid(), 'John', 'Doe', 'john.doe@example.com', 'password123', toTimestamp(now()));
    
    // ๋ฐ์ดํ„ฐ ์กฐํšŒ
    SELECT * FROM users WHERE user_id = f3f9e3e3-301b-4c8a-ae0a-ccbae7b477a2;
    
    // ๋ฐ์ดํ„ฐ ์—…๋ฐ์ดํŠธ
    UPDATE users SET password = 'newpassword123' WHERE user_id = f3f9e3e3-301b-4c8a-ae0a-ccbae7b477a2;
    
    // ๋ฐ์ดํ„ฐ ์‚ญ์ œ
    DELETE FROM users WHERE user_id = f3f9e3e3-301b-4c8a-ae0a-ccbae7b477a2;
    

Document Store#

Document Store๋Š” ํ”ํžˆ ์•Œ๊ณ  ์žˆ๋Š” JSON ํ˜•์‹์œผ๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ž…๋‹ˆ๋‹ค.
document_db
Document Store์—๋Š” ํ…Œ์ด๋ธ”์„ ๋‚˜ํƒ€๋‚ด๋Š” collection๊ณผ ํ…Œ์ด๋ธ” ๋‚ด row๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” document๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
(๊ฐ document๊ฐ€ collection์— ์ €์žฅ๋œ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.)

์žฅ์ #

  • collection ๋‚ด document๋“ค๋ผ๋ฆฌ ๋™์ผํ•œ ๊ตฌ์กฐ์ด์ง€ ์•Š์•„๋„ ๋˜๊ธฐ ๋•Œ๋ฌธ์—
    ์Šคํ‚ค๋งˆ๋ฅผ ์ •ํ•˜์ง€ ์•Š๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์Šคํ‚ค๋งˆ๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด๋„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณ„์† ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋ฐ์ดํ„ฐ๊ฐ€ ์ง๊ด€์ ์ด๊ณ , ๊ฐœ๋ฐœ ์‹œ ๊ฐ์ฒด๋กœ ๋ฐ”๋กœ ์ ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ํ…Œ์ด๋ธ” ๊ฐ„ join ๋˜ํ•œ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‹จ์ #

  • ์ค‘๋ณต ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ๊ด€๋ฆฌ๊ฐ€ ์–ด๋ ต๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋งŒ์•ฝ ํŠน์ • ๊ฐ’์„ ๋‹ค๋ฅธ ๋ฌธ์„œ๋กœ ๋ณต์‚ฌํ•œ ๋‹ค์Œ ๊ทธ ๊ฐ’์ด ๋ณ€๊ฒฝ๋œ๋‹ค๋ฉด,
    ๋‹ค๋ฅธ ๋ฌธ์„œ ๋‚ด์šฉ๋„ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•ด ๋ณต์‚ฌ๋ฅผ ํ•ด์™”๋˜ ๋ฌธ์„œ๋ฅผ ๊ธฐ์–ตํ•ด์•ผ ํ•˜๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ ์˜ˆ์‹œ#

  • ์ƒํ’ˆ ์นดํƒˆ๋กœ๊ทธ

    {
        "product_id": 123,
        "name": "Macbook M2 Pro",
        "category": {
            "category_id": "345",
            "name": "laptop"
        }
    }
    
  • Event logging : ์œ ์ € ๋กœ๊ทธ, ์ œํ’ˆ ๊ตฌ๋งค ๋‚ด์—ญ, ์˜ค๋ฅ˜ ๋กœ๊ทธ ๋“ฑ

Top 10 Document Stores#

Document Store์—์„œ๋Š” ์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ๋งŽ์ด ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์„๊นŒ์š”?
์•ž์—์„œ์™€ ๊ฐ™์ด https://db-engines.com๋ฅผ ํ†ตํ•ด Top 10 Document Stores๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

document_db_rank (์ถœ์ฒ˜: https://db-engines.com/en/ranking/document+store)

MongoDB#

  • ๋žญํ‚น์—์„œ ์••๋„์ ์ธ score๋ฅผ ๋ณด์ด๋Š” ๋งŒํผ Document Store๋ฅผ ๋Œ€ํ‘œํ•œ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋Š” MongoDB๋Š” BSON(Binary JSON) ํ˜•์‹์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

  • Cassandra๊ฐ€ CQL์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ์ž์ฒด ์ฟผ๋ฆฌ ์–ธ์–ด์ธ MQL(MongoDB Query Language)์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

    // ๋ฐ์ดํ„ฐ ์‚ฝ์ž…
    db.users.insertOne({
        "first_name": "John",
        "last_name": "Doe",
        "email": "john.doe@example.com",
        "password": "password123",
        "created_at": new Date()
    })
    
    // ๋ฐ์ดํ„ฐ ์กฐํšŒ
    db.users.find({
        "email": "john.doe@example.com"
    })
    
    // ๋ฐ์ดํ„ฐ ์—…๋ฐ์ดํŠธ
    db.users.updateOne(
        {"email": "john.doe@example.com"},
        {$set: {"password": "newpassword123"}}
    )
    
    // ๋ฐ์ดํ„ฐ ์‚ญ์ œ
    db.users.deleteOne({
        "email": "john.doe@example.com"
    })
    
  • ๋˜ํ•œ sharding ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์—ฌ ์—ฌ๋Ÿฌ ์„œ๋ฒ„์— ๋ถ„์‚ฐ ์ €์žฅ์„ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. sharding


Graph Store#

Graph Store๋Š” ๋ง ๊ทธ๋Œ€๋กœ ๊ทธ๋ž˜ํ”„ ๊ตฌ์กฐ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋ฉฐ, node ๋ฐ edge ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
graph_structure

Graph Store์˜ ์ฃผ์š” ํŠน์ง•์œผ๋กœ๋Š” ์ฟผ๋ฆฌ ํ˜•ํƒœ๊ฐ€ ๊ทธ๋ž˜ํ”„๋ฅผ traversing ํ•˜๋Š” ์‹์œผ๋กœ ์ง„ํ–‰๋œ๋‹ค๋Š” ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด A๊ฐ€ ํŒ”๋กœ์šฐํ•˜๊ณ  ์žˆ๋Š” ๋ชจ๋“  user ์ฐพ์œผ๋ ค๊ณ  ํ•  ๋•Œ, user A์— ๋Œ€ํ•œ node์—์„œ ํŒ”๋กœ์šฐ์™€ ๊ด€๋ จ๋œ edge๋ฅผ ํ†ตํ•ด ๋‹ค๋ฅธ user node ์ •๋ณด๋ฅผ ์–ป๋Š” ๋“ฑ๊ณผ ๊ฐ™์ด ๊ทธ๋ž˜ํ”„์˜ node์™€ edge๋ฅผ ๋”ฐ๋ผ๊ฐ€๋ฉด ์›ํ•˜๋Š” ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์žฅ์ #

  • ์ตœ์ข… ๊ตฌ์กฐ๋ฅผ ๋ฏธ๋ฆฌ ์ •์˜ํ•  ํ•„์š” ์—†์ด node, edge ๋ฐ ํ•ด๋‹น ์†์„ฑ์„ ๊ธฐ์กด ๊ทธ๋ž˜ํ”„์— ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ด๋ฏธ ๋ฐ์ดํ„ฐ๊ฐ€ ์„œ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— join์„ ์ˆ˜ํ–‰ํ•  ํ•„์š” ์—†์ด ํŠน์ • node์—์„œ๋ถ€ํ„ฐ ๋‹ค๋ฅธ node๊นŒ์ง€ edge๋ฅผ ๋”ฐ๋ผ๊ฐ€๋ฉด ์›ํ•˜๋Š” ๊ฐ’์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋ฐ์ดํ„ฐ ํ˜•์‹์ด ์ง๊ด€์ ์ด๊ณ  ์‹œ๊ฐํ™”ํ•˜๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.

๋‹จ์ #

  • ๊ทธ๋ž˜ํ”„ ํ˜•์‹์œผ๋กœ ํ‘œํ˜„ ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ์—๋งŒ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

  • ์ƒˆ๋กœ์šด ์ฟผ๋ฆฌ ์–ธ์–ด(Cypher, SPARQL ๋“ฑ)๋ฅผ ์ด์šฉํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋Ÿฌ๋‹์ปค๋ธŒ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ ์˜ˆ์‹œ#

  • ์†Œ์…œ ๋„คํŠธ์›Œํฌ ๋ฐ์ดํ„ฐ (์‚ฌ๋žŒ๋“ค ๊ฐ„ ํŒ”๋กœ์šฐ ์ •๋ณด, ๊ฒŒ์‹œ๋ฌผ ๋ฐ ์ข‹์•„์š” ์ •๋ณด ๋“ฑ)

  • ์ „์—ผ๋ณ‘ ๋ฐ์ดํ„ฐ (์‚ฌ๋žŒ๋“ค ๊ฐ„ ์ ‘์ด‰ ์ •๋ณด, ๊ฐ์—ผ ์—ฌ๋ถ€ ๋“ฑ)

  • ๊ฒฝ๋กœ ์•ˆ๋‚ด ์„œ๋น„์Šค (์žฅ์†Œ ๊ฐ„ ๊ฑฐ๋ฆฌ ์ •๋ณด๋กœ ์ตœ์  ๊ฒฝ๋กœ ์ œ๊ณต)

  • ์ถ”์ฒœ์‹œ์Šคํ…œ (์œ ์‚ฌํ•œ ์‚ฌ์šฉ์ž๊ฐ€ ์‹œ์ฒญํ•œ ๋‹ค๋ฅธ ์˜ํ™”๋ฅผ ๊ทธ๋ž˜ํ”„ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฒ€์ƒ‰)

Top 10 Graph Stores#

๋งˆ์ง€๋ง‰์œผ๋กœ Graph Store์—์„œ๋Š” ์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ๋งŽ์ด ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์„๊นŒ์š”?
Graph Store ๋˜ํ•œ https://db-engines.com๋ฅผ ํ†ตํ•ด Top 10 Graph Stores๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

graph_rank (์ถœ์ฒ˜: https://db-engines.com/en/ranking/graph+dbms)

Neo4j#

  • ๋Œ€ํ‘œ์ ์ธ Graph Store์ธ Neo4j๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ์•„ํ‚คํ…์ณ๋ฅผ ์ง€๋‹ˆ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. neo4j

  • ์ž์ฒด์ ์œผ๋กœ Neo4j graph ํ”Œ๋žซํผ์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ์–ด์„œ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๊ธฐ์— ์šฉ์ดํ•ฉ๋‹ˆ๋‹ค. neo4j_example

  • ๊ทธ๋ž˜ํ”„์™€ ๊ด€๋ จ๋œ ๋‹ค์–‘ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ธฐ๋Šฅ ๋˜ํ•œ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

    • path finding

    • centrality

    • community detection

    • similarity

    • link prediction

    • node embeddings

    • node classification

    • โ€ฆ

  • ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ์‹œ์—๋Š” Cypher ์ฟผ๋ฆฌ ์–ธ์–ด๋ฅผ ํ†ตํ•ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    // node ์ƒ์„ฑ
    CREATE (n:Person { name: 'John Doe', age: 30 })
    
    // node ๊ฒ€์ƒ‰
    MATCH (n:Person { name: 'John Doe' }) RETURN n
    
    // node ๊ฐ„ edge ์ƒ์„ฑ
    MATCH (p1:Person { name: 'John Doe' }), (p2:Person { name: 'Jane Smith' })
    CREATE (p1)-[:FRIENDS_WITH]->(p2)
    
    // node ๋ฐ edge ๊ฒ€์ƒ‰
    MATCH (p1:Person)-[:FRIENDS_WITH]->(p2:Person)
    WHERE p1.name = 'John Doe'
    RETURN p1, p2
    
    // edge ์ˆ˜์ •
    MATCH (p1:Person)-[r:FRIENDS_WITH]->(p2:Person)
    WHERE p1.name = 'John Doe' AND p2.name = 'Jane Smith'
    SET r.since = '2022-01-01'
    
    // edge ์ œ๊ฑฐ
    MATCH (p1:Person)-[r:FRIENDS_WITH]->(p2:Person)
    WHERE p1.name = 'John Doe' AND p2.name = 'Jane Smith'
    DELETE r