인벤토리 아이템 관련 질문

고객님의 문의에 답변하는 직원은 고객 여러분의 가족 중 한 사람일 수 있습니다.
고객의 언어폭력(비하, 조롱, 욕설, 협박, 성희롱 등)으로부터 직원을 보호하기 위해
관련 법에 따라 수사기관에 필요한 조치를 요구할 수 있으며, 형법에 의해 처벌 대상이 될 수 있습니다.

커뮤니티 이용 정책에 위배되는 게시물을 작성할 경우, 별도 안내 없이 게시물 삭제 또는 커뮤니티 이용이 제한될 수 있습니다.

문의 응대 : 평일 오전 10시 ~ 오후 6시
문의를 남기실 경우 다음 항목을 작성해 주세요.
정보가 부족하거나 응대시간 외 문의하는 경우 확인 및 답변이 지연될 수 있습니다.

  • 뒤끝 SDK 버전 :
  • 프로젝트명 :
  • 스테이터스 코드 :
  • 에러 코드 :
  • 에러 메시지 :

인벤토리를 구현하려 하는데요
예를들어 슬롯이 30개인 인벤토리를 가정했을때

  1. 빈 슬롯도 중간중간 있을테고
  2. 한 슬롯에 n개의 아이템을 가졌을 수도 있을텐데

이 사앹에서 제가 궁금한건 위 데이터를 DB에 어떤식으로 음 보관? 그니까
처음에 위의 1,2번을 구현하려면 테이블에 데이터가 있어야 할텐데 어떤 형태로
존재해야하는지 감이 안 와서요

그러니까 음 예를들어 슬롯이 10개 있고 아이템이 4번 슬롯에만 존재한다고 했을 때 유저가 인벤토리 열면
아이템이 4번슬롯에만 있어야겠죠? 그럼 DB에서 하나의 칼럼으로 해야하는지 … 칼럼에 들어갈 데이터의 자료형은 머로 해야하는게 좋을지 고민입니다 ㅠㅠㅠ 슬롯이 150개일 때 칼럼을 150개 해야 하나요…? 데이터 수정도 빈번하게 일어날텐데 참 고민입니다

안녕하세요 개발자님,
말씀해주신 인벤토리 구현의 경우 json 형태로 하나의 컬럼에 저장하거나,
여러 컬럼을 생성하여 구성하는 방식 모두 이용이 가능하나,
관리의 편의성을 위해 아래와 같이 json 형식으로 저장하는 방법을 권장드립니다.

{
    "1": null,
    "2": null,
    "3": null,
    "4": {"itemId": "item_001", "quantity": 2},
    "5": null,
    "6": null,
    "7": null,
    "8": null,
    "9": null,
    "10": null
}

예시로 제공해드리는 구성인 만큼 의도에 따라 적절히 구성하여 이용해 주시기 바랍니다.

하나의 컬럼 혹은 여러 컬럼을 이용하는 방법 유사하나,
데이터의 관리에있어 json 형태로 하나의 컬럼을 사용하시는 것이 더 원활하실 것으로 예상됩니다.
단, 기획상 인벤토리 슬롯이 너무 많게 구성되는 경우라면 json 구조가 복잡해지고, 데이터가 많아지며 DB 처리량부분에서 효율적이지 못할 수 있습니다.

적절한 수의 인벤토리 슬롯을 구성하시거나,
자동정렬 되는 형태로 하여 데이터를 최적화 하시는 것을 추천드립니다.

저 혹시 “4”: {“itemId”: “item_001”, “quantity”: 2}, 이거 데이터 뒤끝 db에 삽입하는 코드좀 알려주실 수 있나요 초보라서요 ㅠ (딕셔너리로 추가하는 건가요??? json 형태로 추가한다는 개념이 이해가 잘 안 갑니다 ㅠㅠ )

데이터 삽입 예시코드를 안내드립니다.
구성하시는 데이터에 따라 적절히 수정하여 이용해 주세요. :D
(테이블 명은 Inventory, 컬럼명은 slots이라는 가정하 5개 슬롯 저장으로만 작성되었습니다.)

Dictionary<string, object> inventoryData = new Dictionary<string, object>()
{
    { "1", null },
    { "2", null },
    { "3", null },
    { "4", new Dictionary<string, object>()
        {
            { "itemId", "item_001" },
            { "quantity", 2 }
        }
    },
    { "5", null }
};

// 데이터를 Param에 추가
Param param = new Param();
param.Add("slots", inventoryData);

Backend.GameData.Insert("Inventory", param, callback =>
{
    if (callback.IsSuccess())
    {
        Debug.Log("데이터 저장 성공");
    }
    else
    {
        Debug.LogError("데이터 저장 실패 : " + callback);
    }
});

감사합니다 마지막으로 그럼 Inventory칼람의 데이터 형식은 무엇으로 설정하나요?

스키마 미정의 테이블에서는 위 코드를 그대로 사용 가능합니다.
스키마 정의 테이블이라면 map(dictionary) 형식으로 설정해야 하지만,
value의 형식을 다시 map 형식으로 지정할 수 없어 위 코드를 사용할 수 없습니다.

죄송합니다 value의 형식을 다시 map으로 형식으로 지정할수 없어 코드를 사용할 수 없다는 말이 이해가 잘 안 갑니다 ㅠ

스키마가 정의된 테이블에서는 중첩된 map(dictionary) 구조를 사용할 수 없다는 설명입니다.

아하 그러면 스키마를 정의하지 않고 이대로 insert 한다음에 게임 초기화 단계에서 데이터 불러와서 가공해서 쓰면 되나요? 수정사항 있으면 updatev2 인가 ? 이걸로 저 컬럼만 수정해서 다시 반영시키면 될까요??

네, 스키마 미정의 테이블로 이용하시면 되며,
수정을 할때는 아래와 같이 적용해주시면 됩니다.
(4번 슬롯 아이템 수량 변경, 5번 슬롯 아이템 추가 예시)

Dictionary<string, object> inventoryData = new Dictionary<string, object>()
{
    { "1", null },
    { "2", null },
    { "3", null },
    { "4", new Dictionary<string, object>()
        {
            { "itemId", "item_001" },
            { "quantity", 25 }
        }
    },
    { "5", new Dictionary<string, object>()
        {
            { "itemId", "item_005" },
            { "quantity", 70 }
        }}
};

// 데이터를 Param에 추가
Param param = new Param();
param.Add("slots", inventoryData);

Backend.GameData.UpdateV2("Inventory", row_indate, owner_indate ,param, callback =>
{
    if (callback.IsSuccess())
    {
        Debug.Log("데이터 저장 성공");
    }
    else
    {
        Debug.LogError("데이터 저장 실패 : " + callback);
    }
});

게임 정보 데이터 삽입에 실패했습니다. : StatusCode : 400
ErrorCode : BadParameterException
Message : bad 컬럼이 존재하지 않습니다., 잘못된 컬럼이 존재하지 않습니다. 입니다

Dictionary<string, object> inventorySlots = new Dictionary<string, object>()
{
    { "1", null },
    { "2", null },
    { "3", null },
    { "4", new Dictionary<string, object>()
        {
            { "itemId", "item_001" },
            { "quantity", 2 }
        }
    },
    { "5", null }
};

Debug.Log("뒤끝 업데이트 목록에 해당 데이터들을 추가합니다.");
Param param = new Param();
param.Add("Level", 1);
param.Add("Money", 10000);
param.Add("ChrType", chrIdx ?? userData.ChrType);
param.Add("LastMap", "A");
param.Add("SetPlayerItems", new List<int> { 1,4});
param.Add("Atk", 10);
param.Add("Miss", 10);
param.Add("Acc", 10);
param.Add("Lucky", 10);
param.Add("Inventory", inventorySlots); // Add inventory JSON to database

Debug.Log("게임 정보 데이터 삽입을 요청합니다.");
var bro = Backend.GameData.Insert("Character", param);
userData.EndInit();
if (bro.IsSuccess())
{
    Debug.Log("게임 정보 데이터 삽입에 성공했습니다. : " + bro);

    //삽입한 게임 정보의 고유값입니다.  
    gameDataRowInDate = bro.GetInDate();
}
else
{
    Debug.LogError("게임 정보 데이터 삽입에 실패했습니다. : " + bro);
}

}

컬럼이 존재하지 않는다는 오류가 나는 것 같아요 ㅠㅠ 정의 안 한 컬럼 맞긴한데

스키마 정의 테이블은 정의되지 않은 컬럼은 저장할 수없습니다.
스키마 미정의 테이블을 만들어 이용해 주셔야 합니다.

답변 감사합니다 이해하였습니다 혹시

  1. 스키마 정의 테이블과 미정의 테이블의 특징? 장단점을 간략하게 알 수 있을까요?

  2. 아래 string 데이터는 스키마 정의 테이블에 삽입 되던데 string 이라서 가능한 것일까요?
    /* List inventorySlots = new List();

        for (int i = 1; i <= 20; i++) // Assuming 30 slots
        {
            inventorySlots.Add(new InventorySlot(i, null, 0)); // Empty slot
        }
        string inventoryJson = JsonMapper.ToJson(new { slots = inventorySlots });
        userData.InventoryJson = inventoryJson;
    

    */

  3. 답변 주신 분께서 알려주신 방법은 뒤끝에 데이터가 어떤 식으로 저장되는 걸까요? 보니까 미사용 스키마 정의 테이블에 아래와 같이 들어가던데 json 인가요? 제가 잘 몰라서요…
    {
    “1”: null,
    “2”: null,
    “3”: null,
    “4”: {
    “itemId”: “item_001”,
    “quantity”: 2
    },
    “5”: null
    }

  1. 스키마 정의/미정의 테이블

    • 스키마 정의 테이블의 특징
      • 테이블의 구조(열 이름, 데이터 타입 등)가 미리 정의되어 있습니다.
      • 데이터 입력 시, 스키마를 따라야 하며, 구조가 고정적입니다.
      • 데이터의 일관성을 보장합니다.
    • 스키마 미정의 테이블의 특징
      • 테이블 구조를 미리 정의하지 않습니다.
      • 데이터는 키-값 형태로 저장되거나 자유로운 구조를 가질 수 있습니다.
      • JSON, BSON 등 구조화된 문서 형식으로 데이터를 저장하는 경우가 많습니다.
  2. 스키마 정의 테이블에서 string 데이터 타입으로 정의된 컬럼에 JSON 데이터가 단순 문자열로 저장되었기 때문에 삽입에 성공한 것입니다.

  3. 저장된 데이터는 콘솔에서 컬럼을 더블 클릭하여 수정을 시도하였을 때 명확히 그 타입을 확인할 수 있습니다.
    list, map 타입의 경우 첫번째 스크린샷처럼 확인되며, string, number 등의 타입은 두번째 스크린샷과 같이 확인됩니다.
    image