# 5130 데이터베이스 구조

## 데이터베이스 정보

| 항목 | 값 |
|------|-----|
| DB명 | chandj |
| 엔진 | MySQL 8.0 |
| 문자셋 | utf8mb4 |

---

## 주요 테이블 목록

### 핵심 업무 테이블

| 테이블 | 설명 | 비고 |
|--------|------|------|
| `output` | 출고/주문 | 메인 업무 테이블 |
| `estimate` | 견적 | 스크린/스라트 견적 |
| `instock` | 수입검사 | 자재 입고/검사 |
| `lot` | LOT 관리 | 재고 LOT |

### 전자결재 테이블

| 테이블 | 설명 | 비고 |
|--------|------|------|
| `eworks` | 전자결재 통합 | 품의서, 지출결의서, 연차 등 |

### 게시판 테이블

| 테이블 | 설명 | 비고 |
|--------|------|------|
| `notice` | 공지사항 | |
| `notice_ripple` | 공지 댓글 | |
| `qna` | 자료실 | |
| `rnd` | 개발일지 | |

### 회원/조직 테이블

| 테이블 | 설명 | 비고 |
|--------|------|------|
| `member` | 회원 정보 | 로그인 계정 |

### 자산 관리 테이블

| 테이블 | 설명 | 비고 |
|--------|------|------|
| `car` | 차량 정보 | 정비이력 JSON |
| `lift` | 지게차 정보 | 정비이력 JSON |

---

## 테이블 상세

### output (출고/주문)

```sql
CREATE TABLE output (
    num INT AUTO_INCREMENT PRIMARY KEY,

    -- 기본 정보
    indate DATE,                    -- 접수일
    outdate DATE,                   -- 출고예정일
    outdonedate DATE,               -- 출고완료일

    -- 현장 정보
    outworkplace VARCHAR(200),      -- 현장명
    outarea VARCHAR(100),           -- 지역

    -- 제품 정보
    prodCode VARCHAR(50),           -- 제품코드 (KS, KW 등)

    -- 인정검사
    ACIregDate DATE,                -- 인정검사 요청일
    ACIaskDate DATE,                -- 인정검사 신청일
    ACIdoneDate DATE,               -- 인정검사 완료일

    -- 배송
    deliveryfeeList JSON,           -- 배차/운송비 목록

    -- 상태
    is_deleted TINYINT DEFAULT 0,   -- 삭제 여부
    devMode TINYINT,                -- 개발모드

    -- 메타
    created_at TIMESTAMP,
    updated_at TIMESTAMP
);
```

### estimate (견적)

```sql
CREATE TABLE estimate (
    num INT AUTO_INCREMENT PRIMARY KEY,

    -- 견적 정보
    estimate_date DATE,             -- 견적일
    customer VARCHAR(100),          -- 고객명
    project_name VARCHAR(200),      -- 프로젝트명

    -- 제품 정보
    product_type VARCHAR(50),       -- 제품유형 (screen, slat)
    specifications JSON,            -- 사양 정보

    -- 금액
    unit_price DECIMAL(15,2),       -- 단가
    total_amount DECIMAL(15,2),     -- 총금액

    -- 상태
    is_deleted TINYINT DEFAULT 0,

    -- 메타
    created_at TIMESTAMP,
    updated_at TIMESTAMP
);
```

### instock (수입검사)

```sql
CREATE TABLE instock (
    num INT AUTO_INCREMENT PRIMARY KEY,

    -- 검사 정보
    inspection_date DATE,           -- 검사일
    item_name VARCHAR(200),         -- 품명
    supplier VARCHAR(100),          -- 공급사

    -- 검사 상세
    specification TEXT,             -- 규격
    iList JSON,                     -- 검사 상세 항목

    -- 판정
    resultJudgement VARCHAR(20),    -- 합격/불합격

    -- 비고
    remarks TEXT,
    weight_kg DECIMAL(10,2),        -- 중량

    -- 상태
    is_deleted TINYINT DEFAULT NULL,

    -- 메타
    created_at TIMESTAMP,
    updated_at TIMESTAMP
);
```

### eworks (전자결재)

```sql
CREATE TABLE eworks (
    num INT AUTO_INCREMENT PRIMARY KEY,

    -- 문서 유형
    eworks_item VARCHAR(50),        -- 품의서, 지출결의서, 연차 등
    al_company VARCHAR(20),         -- 회사 (경동, 주일)

    -- 기본 정보
    indate DATE,                    -- 작성일
    outworkplace VARCHAR(200),      -- 제목/현장명

    -- 금액 (품의서/지출결의서)
    suppliercost VARCHAR(50),       -- 금액
    expense_data JSON,              -- 지출 상세 (지출결의서)

    -- 연차 정보
    al_askdatefrom DATE,            -- 연차 시작일
    al_askdateto DATE,              -- 연차 종료일

    -- 결재 정보
    status VARCHAR(20),             -- 상태 (draft, pending, end)
    e_line_id VARCHAR(200),         -- 결재라인 ID
    e_confirm TEXT,                 -- 결재 확인 정보

    -- 상태
    is_deleted TINYINT DEFAULT NULL,

    -- 메타
    created_at TIMESTAMP,
    updated_at TIMESTAMP
);
```

### member (회원)

```sql
CREATE TABLE member (
    num INT AUTO_INCREMENT PRIMARY KEY,

    -- 계정 정보
    userid VARCHAR(50) UNIQUE,
    password VARCHAR(255),
    name VARCHAR(50),

    -- 조직 정보
    company VARCHAR(50),            -- 회사
    department VARCHAR(50),         -- 부서
    position VARCHAR(50),           -- 직급

    -- 권한
    level INT,                      -- 권한 레벨
    eworks_lv INT,                  -- 결재 레벨
    eworks_level INT,               -- 결재 단계
    authority VARCHAR(50),          -- 특수 권한

    -- 연락처
    email VARCHAR(100),
    phone VARCHAR(20),

    -- 결재 설정
    first_approval_id VARCHAR(50),
    first_approval_name VARCHAR(50),

    -- 상태
    is_active TINYINT DEFAULT 1,

    -- 메타
    created_at TIMESTAMP,
    updated_at TIMESTAMP
);
```

### notice (공지사항)

```sql
CREATE TABLE notice (
    num INT AUTO_INCREMENT PRIMARY KEY,

    -- 게시글 정보
    subject VARCHAR(200),           -- 제목
    content TEXT,                   -- 내용

    -- 공지 설정
    noticecheck CHAR(1),            -- 전체공지 여부 (y/n)

    -- 작성자
    name VARCHAR(50),
    userid VARCHAR(50),

    -- 조회
    hit INT DEFAULT 0,

    -- 날짜
    regist_day DATETIME,

    -- 파일
    file_name VARCHAR(200),
    file_path VARCHAR(500),

    -- 상태
    is_deleted TINYINT DEFAULT 0
);
```

### car (차량)

```sql
CREATE TABLE car (
    num INT AUTO_INCREMENT PRIMARY KEY,

    -- 차량 정보
    vehicle_type VARCHAR(100),      -- 차종
    license_plate VARCHAR(20),      -- 차량번호
    purchase_date DATE,             -- 구매일

    -- 정비 이력 (JSON)
    engine_oil_change_data JSON,    -- 엔진오일 교환 이력
    maintenance_data JSON,          -- 정비 이력

    -- 상태
    is_deleted TINYINT DEFAULT 0,

    -- 메타
    created_at TIMESTAMP,
    updated_at TIMESTAMP
);

-- JSON 구조 예시
-- engine_oil_change_data: [
--   {"engine_oil_change_date": "2024-01-15", "mileage": "50000"}
-- ]
-- maintenance_data: [
--   {"maintenance_date": "2024-02-20", "maintenance_record": "타이어 교체"}
-- ]
```

### lift (지게차)

```sql
-- car 테이블과 동일한 구조
CREATE TABLE lift (
    num INT AUTO_INCREMENT PRIMARY KEY,
    vehicle_type VARCHAR(100),
    purchase_date DATE,
    engine_oil_change_data JSON,
    maintenance_data JSON,
    is_deleted TINYINT DEFAULT 0,
    created_at TIMESTAMP,
    updated_at TIMESTAMP
);
```

---

## 공통 컬럼 패턴

### Soft Delete

대부분의 테이블에서 `is_deleted` 컬럼으로 소프트 삭제 구현:

```sql
-- 삭제되지 않은 레코드 조회
WHERE is_deleted IS NULL OR is_deleted = '0'

-- 삭제 처리
UPDATE table SET is_deleted = '1' WHERE num = ?
```

### 타임스탬프

```sql
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
```

### JSON 컬럼

복잡한 데이터 구조는 JSON 컬럼으로 저장:

```sql
-- 예: 배차 정보
deliveryfeeList JSON
-- 값: [{"col1": "업체명", "col5": "100000"}, ...]

-- 예: 검사 항목
iList JSON
-- 값: [{"inputItems": {"resultJudgement": "합격"}}, ...]
```

---

## 인덱스 권장 사항

### output 테이블

```sql
CREATE INDEX idx_output_indate ON output(indate);
CREATE INDEX idx_output_outdate ON output(outdate);
CREATE INDEX idx_output_is_deleted ON output(is_deleted);
CREATE INDEX idx_output_prodcode ON output(prodCode);
```

### eworks 테이블

```sql
CREATE INDEX idx_eworks_company ON eworks(al_company);
CREATE INDEX idx_eworks_item ON eworks(eworks_item);
CREATE INDEX idx_eworks_status ON eworks(status);
CREATE INDEX idx_eworks_indate ON eworks(indate);
CREATE INDEX idx_eworks_leave_dates ON eworks(al_askdatefrom, al_askdateto);
```

### instock 테이블

```sql
CREATE INDEX idx_instock_date ON instock(inspection_date);
CREATE INDEX idx_instock_deleted ON instock(is_deleted);
```

---

## 연결 설정

### PDO 연결 (lib/mydb.php)

```php
function db_connect(){
    loadEnv();

    $db_host = $_ENV['DB_HOST'] ?? 'localhost';
    $db_name = $_ENV['DB_NAME'] ?? 'chandj';
    $db_user = $_ENV['DB_USER'] ?? 'chandj';
    $db_pass = $_ENV['DB_PASS'] ?? '';

    $dsn = "mysql:host=".$db_host.";dbname=".$db_name.";charset=utf8mb4";

    $options = [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES => false
    ];

    $pdo = new PDO($dsn, $db_user, $db_pass, $options);
    return $pdo;
}
```

### 환경 변수 (.env)

```env
DB_HOST=localhost
DB_NAME=chandj
DB_USER=chandj
DB_PASS=your_password
```

---

## 백업 권장

### 일일 백업

```bash
mysqldump -u chandj -p chandj > backup_$(date +%Y%m%d).sql
```

### 주요 테이블 우선 백업

```bash
mysqldump -u chandj -p chandj output estimate instock eworks member > critical_backup.sql
```

---

*문서 작성일: 2025-12-13*