File size: 3,047 Bytes
76a8b94
 
 
 
 
 
 
 
 
 
 
 
220e583
5ffbc31
76a8b94
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
-- JobSonar Database Schema
-- SQLite (๋กœ์ปฌ ๊ฐœ๋ฐœ) / PostgreSQL (ํ”„๋กœ๋•์…˜) ํ˜ธํ™˜

-- ์ฑ„์šฉ๊ณต๊ณ  ๋ฉ”์ธ ํ…Œ์ด๋ธ”
CREATE TABLE IF NOT EXISTS jobs (
    id              INTEGER PRIMARY KEY AUTOINCREMENT,
    source_site     TEXT    NOT NULL,           -- 'wanted' | 'saramin' | 'jobkorea'
    source_id       TEXT    NOT NULL,           -- ์‚ฌ์ดํŠธ๋ณ„ ๊ณ ์œ  ID (์ค‘๋ณต ๋ฐฉ์ง€)
    url             TEXT    NOT NULL,
    title           TEXT    NOT NULL,           -- ๊ณต๊ณ  ์ œ๋ชฉ
    company_name    TEXT    NOT NULL,
    job_category    TEXT,                       -- '๋ฐ์ดํ„ฐ ์—”์ง€๋‹ˆ์–ด' | '๋ฐ์ดํ„ฐ ๋ถ„์„๊ฐ€' ๋“ฑ
    industry        TEXT,                       -- ํšŒ์‚ฌ ์—…์ข… (์›ํ‹ฐ๋“œ: API, ์‚ฌ๋žŒ์ธ/์žก์ฝ”๋ฆฌ์•„: HTML)
    employment_type TEXT,                       -- '์ •๊ทœ์ง' | '๊ณ„์•ฝ์ง' | '์ธํ„ด' ๋“ฑ
    location        TEXT,                       -- '์„œ์šธ' | 'ํŒ๊ต' ๋“ฑ
    experience_min  INTEGER,                    -- ์ตœ์†Œ ๊ฒฝ๋ ฅ (๋…„)
    experience_max  INTEGER,                    -- ์ตœ๋Œ€ ๊ฒฝ๋ ฅ (๋…„), NULL = ๋ฌด๊ด€
    salary_min      INTEGER,                    -- ์—ฐ๋ด‰ ํ•˜ํ•œ (๋งŒ์›)
    salary_max      INTEGER,                    -- ์—ฐ๋ด‰ ์ƒํ•œ (๋งŒ์›)
    posted_date     DATE,                       -- ๊ณต๊ณ  ๊ฒŒ์‹œ์ผ
    deadline_date   DATE,                       -- ๋งˆ๊ฐ์ผ
    is_active       BOOLEAN NOT NULL DEFAULT 1,
    is_duplicate    BOOLEAN NOT NULL DEFAULT 0, -- ํƒ€ ์‚ฌ์ดํŠธ ๋™์ผ ๊ณต๊ณ  ์ค‘๋ณต ์—ฌ๋ถ€
    collected_at    DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at      DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,

    UNIQUE(source_site, source_id)
);

-- ๊ธฐ์ˆ  ์Šคํƒ ํ…Œ์ด๋ธ” (๊ณต๊ณ ๋ณ„ ํƒœ๊ทธ)
CREATE TABLE IF NOT EXISTS job_skills (
    id          INTEGER PRIMARY KEY AUTOINCREMENT,
    job_id      INTEGER NOT NULL REFERENCES jobs(id) ON DELETE CASCADE,
    skill_name  TEXT    NOT NULL,               -- ์ •๊ทœํ™”๋œ ์Šคํ‚ฌ๋ช… (์†Œ๋ฌธ์ž)
    UNIQUE(job_id, skill_name)
);

-- ์ˆ˜์ง‘ ์‹คํ–‰ ๋กœ๊ทธ (GitHub Actions ๋””๋ฒ„๊น…์šฉ)
CREATE TABLE IF NOT EXISTS crawl_logs (
    id              INTEGER PRIMARY KEY AUTOINCREMENT,
    source_site     TEXT    NOT NULL,
    started_at      DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    finished_at     DATETIME,
    jobs_found      INTEGER DEFAULT 0,
    jobs_inserted   INTEGER DEFAULT 0,
    jobs_updated    INTEGER DEFAULT 0,
    status          TEXT    NOT NULL DEFAULT 'running', -- 'running' | 'success' | 'failed'
    error_message   TEXT
);

-- ์ธ๋ฑ์Šค
CREATE INDEX IF NOT EXISTS idx_jobs_source      ON jobs(source_site, source_id);
CREATE INDEX IF NOT EXISTS idx_jobs_dedup       ON jobs(lower(company_name), lower(title));
CREATE INDEX IF NOT EXISTS idx_jobs_category    ON jobs(job_category);
CREATE INDEX IF NOT EXISTS idx_jobs_posted      ON jobs(posted_date);
CREATE INDEX IF NOT EXISTS idx_jobs_active      ON jobs(is_active);
CREATE INDEX IF NOT EXISTS idx_job_skills_name  ON job_skills(skill_name);
CREATE INDEX IF NOT EXISTS idx_job_skills_job   ON job_skills(job_id);