EAV 모델의 개념

EAV 모델에서는 엔터티(Entity), 속성(Attribute), 값(Value)로 데이터를 나누어 저장합니다. 이는 여러 필드를 가질 수 있는 다양한 엔터티를 하나의 테이블에 유연하게 저장할 수 있도록 도와줍니다. 각 데이터를 세 가지 기본 요소로 나눠 관리하게 됩니다:

  1. 엔터티 (Entity): 실제 객체나 데이터 항목을 의미합니다. 예를 들어, '환자', '제품', '유저' 등이 될 수 있습니다.
  2. 속성 (Attribute): 엔터티가 가질 수 있는 특정 속성입니다. 예를 들어, 환자의 '키', '몸무게', '혈압' 등이 속성이 됩니다.
  3. 값 (Value): 속성에 해당하는 실제 값입니다. 예를 들어, '키' 속성의 값은 175cm, '몸무게' 속성의 값은 70kg와 같은 식입니다.

 

 

테이블 구조 예시

 

1. Entities 테이블

이 테이블은 각 엔터티를 저장합니다. 예를 들어, 사용자가 될 수도 있고, 제품이 될 수도 있습니다.

Entity ID Entity Type
1 Patient
2 Product

( 테이블 리스트들을 관리하는 테이블 )

 

2. Attributes 테이블

속성을 저장하는 테이블로, 속성의 이름과 타입 등을 저장합니다.

Attribute ID Attribute Name Attribute Type
1 Height Int
2 Weight Int
3 Blood Type String

( 컬럼들의 리스트들을 정의하는 테이블 )

 

3. Values 테이블

이 테이블은 엔터티와 속성의 관계를 맺고 실제 값을 저장합니다.

Entity ID Attribute ID Value
1 1 175
1 2 70
1 3 AB
2 1 180
2 3 A

( 어떤 테이블에 어떤 컬럼이 있고 그 컬럼의 데이터는 무엇인지 저장하는 테이블 )

 

 

각 테이블의 역할

  • Entities 테이블: 엔터티(환자, 제품 등)를 고유한 ID로 관리하며, 이 ID를 통해 속성과 값을 연결할 수 있습니다.
  • Attributes 테이블: 속성을 정의하고 관리합니다. 속성의 타입(예: 정수, 문자열 등)과 이름을 기록합니다.
  • Values 테이블: 특정 엔터티의 속성에 해당하는 값을 저장합니다. 이때 Entity ID와 Attribute ID로 값을 연결하고, 실제 데이터를 Value 컬럼에 저장합니다.

 

 

 

장점

  • 유연성: 속성이 사전에 정의되지 않거나 자주 변경될 때 적합합니다. 새로운 속성을 추가할 때도 스키마를 변경하지 않고 데이터를 추가할 수 있어 매우 유연합니다.
  • 다양한 데이터 관리 가능: 각 엔터티마다 속성과 값이 다를 수 있으므로 매우 다양한 데이터 형식을 처리할 수 있습니다. 예를 들어, 한 환자는 혈압 정보가 있지만 다른 환자는 혈압 정보가 없는 경우도 자연스럽게 관리 가능합니다.

 

 

 

단점

  1. 복잡한 쿼리: 데이터를 가져오려면 여러 레코드를 조회하고 병합해야 하기 때문에 복잡한 SQL 쿼리가 필요합니다. 특히 여러 속성을 동시에 조회하는 경우에는 성능 문제가 발생할 수 있습니다.
  2. 성능 문제: 대규모 데이터셋에서 EAV 모델을 사용할 경우 쿼리 성능이 저하될 수 있습니다. 인덱싱이 어렵고, 값이 여러 개의 행으로 나눠지기 때문에 조인(Join)이나 필터링에서 부담이 큽니다.
  3. 데이터 무결성 관리 어려움: 속성의 값에 대한 제약 조건이나 데이터 타입을 관리하기 어려워, 데이터 무결성을 유지하기 위해 별도의 로직이나 프로세스가 필요합니다.

 

 

쿼리 예시

만약 환자의 키(Height)를 조회하고 싶다면, 쿼리는 다음과 같이 작성됩니다:

SELECT e.EntityID, a.AttributeName, v.Value
FROM Entities e
JOIN Values v ON e.EntityID = v.EntityID
JOIN Attributes a ON v.AttributeID = a.AttributeID
WHERE a.AttributeName = 'Height';

 

 

 

결론

EAV 모델은 유연하게 데이터를 저장할 수 있는 좋은 방법이지만, 실제로는 엔터티, 속성, 값을 각각 따로 테이블로 관리하는 것이 더 일반적입니다. 이렇게 하면 속성 추가나 수정이 유연하게 가능하고 데이터베이스의 구조를 자주 변경하지 않아도 되는 장점이 있어요.

 

 

 

 

어떻게 사용하고 있는지?

위의 EAV 개념과 동일하게 관리하며 사용하고 있지는 않지만 예시로 들어보겠다. 설비의 설정되어 있는 레시피를 저장하는 내용이다.

 

1. 구조

1. 레시피 수신 데이터 : 특정 설비의 설정되어 있는 값들을 저장 함. 설비마다 Column 항목을 유동적이기 때문에 COL_1, COL_2 로 유동적 관리

2. 버전 관리 : 특정 설비는 어떤 버전들을 갖고 있는지 관리

3. 파라메터 관리 : 설비마다 유동 컬럼 (COL_1, COL_2, ..) 이 어떤 것을 뜻하는지 버전과 함께 관리. BBB 설비의 경우 COL_2의 뜻하는 내용이 바뀌었기 때문에 버전을 올려서 관리를 한다.

 

2. 수신 받은 내용

{
    "message": {
        "header": {
            "messagename": "레시피"
        },
        "body": {
            "MACHINENAME": "AAA",
            "PARAMETERREVISION": "1.0",
            "PARAMETERLIST": {
                "PARAMETER": [
                    {
                        "PARAMETERNAME": "VACCUM",
                        "PARAMETERVALUE": "0.00"
                    },
                    {
                        "PARAMETERNAME": "TEMP",
                        "PARAMETERVALUE": "5.12"
                    },
                    {
                        "PARAMETERNAME": "DOWN",
                        "PARAMETERVALUE": "462.00"
                    },   
                    {                 
                        "PARAMETERNAME": "UP",
                        "PARAMETERVALUE": "1.25"
                    }
                ]
            },
            "TRANSTIME": "2024-10-18 00:11:43:13"
        }
    }
}
{
    "message": {
        "header": {
            "messagename": "레시피"
        },
        "body": {
            "MACHINENAME": "BBB",
            "PARAMETERREVISION": "1.1",
            "PARAMETERLIST": {
                "PARAMETER": [
                    {
                        "PARAMETERNAME": "HEAD",
                        "PARAMETERVALUE": "1.1"
                    },
                    {
                        "PARAMETERNAME": "LEG",
                        "PARAMETERVALUE": "623.00"
                    }
                ]
            },
            "TRANSTIME": "2024-10-18 00:11:43:13"
        }
    }
}

 

위의 두 개의 JSON을 수신 후 param 순서와 기준정보를 통해 파싱하게 되면 아래 수신 데이터와 같이 내용이 쌓이게 된다

반응형


글이 도움이 되셨다면 공감과 광고 클릭 한번 부탁드립니다! 💕
감사합니다 ✨