> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.onesignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Materialize

> Materialize에서 OneSignal로 사용자 지정 이벤트를 동기화하여 실시간 사용자 행동을 기반으로 자동화된 Journey 및 개인화된 메시징 캠페인을 트리거하세요.

export const PLATFORM_0 = "Materialize"

export const DATA_TYPE_0 = "view or table columns"

export const COLUMN_HEADER_0 = "Materialize Column"

export const PROPERTIES_DESCRIPTION_0 = "JSON object with event metadata"

## 개요

OneSignal + Materialize 통합은 Materialize 스트리밍 데이터베이스에서 OneSignal로 사용자 지정 이벤트를 자동으로 동기화하여 실시간 사용자 행동을 기반으로 자동화된 메시징 캠페인 및 Journey를 트리거할 수 있습니다.

Materialize는 데이터의 점진적으로 업데이트된 뷰를 유지하여 실시간 분석 및 이벤트 처리를 가능하게 하는 PostgreSQL 호환 스트리밍 데이터베이스입니다.

***

## 요구 사항

* Access to [Event Streams](/docs/en/event-streams) for outbound message events (Plan limitations and overages apply)
* Access to [Custom Events](/docs/en/custom-events) for inbound event syncing (Plan limitations and overages apply)
* [Updated Account Plan](https://onesignal.com/pricing) (not available on free apps)

### Materialize

* 콘솔 액세스 권한이 있는 **Materialize 계정**
* 외부 도구 인증을 위한 **App Password**
* 이벤트 데이터를 포함하는 **Materialized View** 또는 테이블
* Materialize 데이터베이스에서 액세스 가능한 **이벤트 데이터**

***

## 설정

<Steps>
  <Step title="Materialize 연결 세부 정보 가져오기">
    Materialize 콘솔에 로그인하고 **Connect** 페이지로 이동하여 연결 세부 정보를 찾으세요.
  </Step>

  <Step title="App Password 만들기">
    Materialize 콘솔에서 OneSignal이 인증에 사용할 새 **App Password**를 만드세요.
  </Step>

  <Step title="OneSignal에 연결">
    OneSignal에서 **Data > Integrations**으로 이동하여 **Add Integration**을 클릭합니다.

    **Materialize**를 선택하고 다음을 제공하세요:

    * **Host:** Materialize 호스트 이름(Materialize 콘솔 Connect 페이지의 **External Tools** 아래에서 찾을 수 있음)
    * **Username:** 이메일 주소(Materialize에 로그인하는 데 사용)
    * **Password:** 2단계에서 생성한 App Password
    * **Database:** 데이터베이스 이름(선택 사항, 기본값은 `materialize`)
  </Step>

  <Step title="연결 테스트">
    **Test**를 클릭하여 연결이 올바르게 작동하는지 확인하세요.
  </Step>
</Steps>

***

### 이벤트 데이터 매핑

{PLATFORM_0} {DATA_TYPE_0}를 OneSignal의 사용자 지정 이벤트 형식에 매핑합니다:

| OneSignal 필드  | {COLUMN_HEADER_0} | 설명                         | 필수  |
| ------------- | ----------------- | -------------------------- | --- |
| `name`        | `event_name`      | 이벤트 식별자                    | Yes |
| `external_id` | `user_id`         | 사용자 식별자                    | Yes |
| `timestamp`   | `event_timestamp` | 이벤트가 발생한 시간                | No  |
| `properties`  | `event_data`      | {PROPERTIES_DESCRIPTION_0} | No  |

### 실시간 이벤트 뷰 예제

```sql theme={null}
-- Real-time materialized view for recent events
CREATE MATERIALIZED VIEW analytics.recent_user_events AS
SELECT
    event_name,
    user_id,
    event_timestamp,
    event_properties,
    session_id,
    device_type
FROM raw_events.stream
WHERE event_timestamp >= NOW() - INTERVAL '1 day';
```

***

## 처리 모드

### Materialized View(권장)

새 데이터가 도착하면 자동으로 업데이트되는 Materialized View에서 동기화하여 Materialize의 실시간 처리를 활용하세요:

```sql theme={null}
-- High-value events materialized view
CREATE MATERIALIZED VIEW analytics.high_value_events AS
SELECT
    event_name,
    user_id,
    event_timestamp,
    event_properties || jsonb_build_object(
        'source', 'materialize',
        'value_tier', 'high'
    ) as event_properties
FROM raw_events.stream
WHERE (event_properties->>'value')::numeric > 100;
```

### SQL 쿼리 모드

이벤트 데이터를 변환하기 위한 사용자 지정 PostgreSQL 호환 쿼리를 작성하세요:

```sql theme={null}
-- Real-time user activity summary
SELECT
    'activity_summary' as event_name,
    user_id,
    NOW() as event_timestamp,
    jsonb_build_object(
        'events_last_hour', COUNT(*),
        'unique_sessions', COUNT(DISTINCT session_id),
        'total_value', SUM((event_properties->>'value')::numeric),
        'last_seen', MAX(event_timestamp)
    ) as event_properties
FROM analytics.recent_user_events
WHERE event_timestamp >= NOW() - INTERVAL '1 hour'
GROUP BY user_id
HAVING COUNT(*) >= 5;
```

### 실시간 스트림 처리

```sql theme={null}
-- Progressive profiling view
CREATE MATERIALIZED VIEW analytics.user_progression AS
SELECT
    user_id,
    COUNT(*) as total_events,
    COUNT(DISTINCT event_name) as unique_event_types,
    MAX(event_timestamp) as last_activity,
    CASE
        WHEN COUNT(*) >= 50 THEN 'power_user'
        WHEN COUNT(*) >= 20 THEN 'active_user'
        WHEN COUNT(*) >= 5 THEN 'engaged_user'
        ELSE 'new_user'
    END as user_segment
FROM raw_events.stream
GROUP BY user_id;
```

***

## 제한 사항

* Materialize는 Basic Sync Engine만 지원합니다
* 실시간 쿼리는 더 많은 컴퓨팅 리소스를 소비할 수 있습니다
* 대규모 데이터세트의 복잡한 조인은 최적화되어야 합니다
* Materialized View는 지속적인 클러스터 리소스가 필요합니다

***

## FAQ

### Materialize에서 실시간 성능을 최적화하려면 어떻게 하나요?

자주 쿼리되는 열에 인덱스를 사용하고 더 나은 성능을 위해 시간 범위별로 대규모 이벤트 데이터세트를 파티셔닝하는 것을 고려하세요.

### 테이블과 Materialized View 모두에서 동기화할 수 있나요?

예, OneSignal은 Materialize의 정적 테이블과 실시간 Materialized View 모두에서 읽을 수 있습니다.

### 실시간 동기화는 어떻게 작동하나요?

Materialize는 점진적으로 업데이트된 뷰를 유지하므로 OneSignal은 추가 처리 오버헤드 없이 항상 데이터의 최신 상태를 읽습니다.

***
