Azure Cosmos에서 무료로 만드는 하이스코어 DB(3) : 코어(SQL)

6240 단어 포엠CosmosDB

소개



CosmosDB에 코어(SQL)로, 스코어 등록, 하이 스코어 취득까지 할 수 있었으므로 이하 기록으로서 남긴다.

이용 개시까지의 순서는 1회째 기사 참조:
Azure Cosmos에서 무료로 만드는 하이스코어 DB(1)

설명 부분 이외의 소스는 git hub 참조:
cosmos-db 샘플

등록/취득 처리를 작성할 수 있었으므로, 나머지는 AzureFunctions 로부터 호출하도록 하면 이용 개시할 수 있을 것 같지만, 사용감이 나쁘기 때문에 CosmosDB는 이번에 종료로 해 firebase로 이행하려고 한다.

NoSQL과 한마디로 말해도 ...



Wikipedia

NoSQL (일반적으로 "Not only SQL"로 해석 됨)은 관계 데이터베이스 관리 시스템 (RDBMS) 이외의 데이터베이스 관리 시스템을 가리키는 대략적인 분류 용어입니다. 관계데이터베이스를 산자자에 적용해 온 오랜 역사를 타파하고, 그 이외의 구조의 데이터베이스의 이용·발전을 촉진시키려는 운동의 표어로서의 의미를 가진다. 관계 모델이 아닌 데이터 스토어의 특징으로서 고정된 스키마에 묶이지 않는 것, 관계 모델의 결합 조작을 이용하지 않는 것 (경우에 따라서는 단순히 그러한 기능이 누락되고 있을 뿐), 수평 스케일러빌리티가 확보 하기 쉬운 일이 많은 것, 트랜잭션 처리를 이용할 수 없는 것이 많은 것 등을 들 수 있다. 학술적인 세계에서는 이런 종류의 데이터베이스를 구조형 스토리지(structured storage)라고 부르는 경우가 많다[1][2][3][4].

DynamoDB는 컴패네이션에 들어가면 [테이블 만들기] 버튼이 있고 테이블 위치는 보통 있는 것일까라고 생각했지만, CosmosDB의 코어 SQL에는 없었다.



CosmosDB는, 계정 작성시에 API와 데이터 모델 종류를 선택할 수 있어, 그 선택에 의해 할 수 있는 것이 다른 사양이 되고 있다.
이것은 인터넷상의 단편적인 정보를 모아서 작업하는 것이 매우 어려운 사양이라고 생각되었기 때문에, 이대로 계속 이용하는 것을 단념하기에 이르렀다.

API 및 데이터 모델:
Azure Cosmos에서 무료로 만드는 높은 점수 DB (2) : API, 데이터 모델 및 Azure 테이블

데이터 구조



Cosmos DB 코어 (SQL) 데이터 모델은 id 항목을 기본 키로 json을 저장하는 key-value 저장소입니다.
본 기사에서는 쇼와의 게임의 하이 스코어를 재현하기 위해, 이름과 스코어가 등록 대상이 되지만, 모두 고유의 키는 되지 않는다.
{
    "id": <一意の値>
    "name": "test",
    "score": 123
}

따라서, id 에 일의의 값을 설정하기 위해서 시리얼치등을 생성할 필요가 있지만, 시리얼치를 보존하는 테이블을 보관 유지할 수 없다.
그래서 이번에는 {テーブル名}_{id} 라는 값을 id 로 설정하기로 했다.

sequences.js
  {
    "id": "sequences_scores", // score テーブル用の sequence
    "no": 1   // 現在のシーケンス
  }

scores.js
  {
    "id": "scores_{sequenceより取得した一意の値}"
    "name": "SHEEP",
    "score": 1000
  },
  {
    "id": "scores_{sequenceより取得した一意の値}"
    "name": "SHEEP",    // 重複可
    "score": 900
  }
  ...

DB 생성



간단하고 사용하기 쉬운 명령
async function createDatabase() {
  const { database } = await client.databases.createIfNotExists({
    id: databaseId
  })
  console.log(`Created database:\n${database.id}\n`)
}

Container 작성



간단하고 사용하기 쉬운 명령. partitionKey은 조금 기분 나쁘다.
async function createContainer() {
  const { container } = await client
    .database(databaseId)
    .containers.createIfNotExists(
      { id: containerId, partitionKey },
      { offerThroughput: 400 }
    )
  console.log(`Created container:\n${config.container.id}\n`)
}

upsert(insert or update)


items.upsert 에서 고유 ID를 가진 json을 등록.
동일한 ID의 항목이 있으면 덮어 씁니다. 1건씩 밖에 등록할 수 없다.
async function upsertItems(itemBodies) {

  // 複数itemの配列を upsert して、Promise.all(ps)で完了待ち
  const items = client.database(databaseId).container(containerId).items
  const ps = itemBodies.map(body => items.upsert(body))
  await Promise.all(ps)

  console.log(`upserted items : `, itemBodies.map(o => o.id))
}

선택



SQL 쿼리에서 상위 점수를 얻습니다.
코어(SQL)에서는 SQL을 사용할 수 있지만, 테이블 API에서는 사용할 수 없다.
async function getHiScores(count) {
  console.group(`+ getHiScores(${count})`)
  const q = {
    query: `SELECT VALUE c FROM c ORDER BY c.score DESC OFFSET 0 LIMIT ${count}`,
    parameters: []
  }
  const query = client.database(databaseId).container(containerId).items.query(q)
  const { resources: rs } = await query.fetchAll()

  console.groupEnd()
  console.log(`- getHiScores(${count})`)
  return rs
}

결론



간단한 높은 점수 처리에 필요한 코드를 한 번에 썼다.
SQL보다 불편한 것은 어쩔 수 없지만, 테이블이 서포트되어 있지 않고 id 를 궁리하는 구현을 계속하는 것은 매우 스트레스에 느꼈다.
어떠한 로그를 던지는 등, 순수하게 단일의 데이터를 던지는 곳으로서는 좋은 것이라고 생각했지만, AWS보다 저렴하다고 하는 것도 없다면, 굳이 CosmosDB를 선택하는 메리트는 느껴지지 않았다.

좋은 웹페이지 즐겨찾기