ServiceNowでテーブルを拡張した際、実際のデータベース上では何が起こるのでしょうか?これは”テーブルの拡張モデル”に依存します。この記事では、”拡張モデル”とは何か、またこれと関係のあるタスクテーブル拡張時の注意について説明します。
前提知識: RDBにおけるテーブル拡張
まず、拡張モデルを理解するための前提知識として、ServiceNowでも採用されている関係データベース(RDB)におけるテーブル拡張の考え方を知っておく必要があります。”単一テーブル継承”や”クラステーブル継承”という言葉がわかる人は読み飛ばして大丈夫です。
ここではServiceNowのITサービス管理機能の代表的なテーブルであるTask(タスク)、Incident(インシデント)、Problem(問題)を例に説明します。システムで扱うデータの関係を業務レベルで抽象的に表した概念データモデルにおいて、拡張元のエンティティ=オブジェクトをスーパータイプ、そこから派生したエンティティをサブタイプと呼びます。
概念データモデルで拡張・継承関係のあるデータ構造に対して、関係データベース(RDB)にはテーブルの拡張(継承)の概念が存在しないため、RDBでこれを次のような方法で表現します。
- 単一テーブル継承
スーパータイプ、サブタイプ全ての属性を含む単一のテーブルを作成する。サブタイプの区別はどのサブタイプかを表す属性で行う。アプリ側から扱いやすいがストレージ効率が悪い(データが歯抜けになる)。 - クラステーブル継承
スーパータイプ、各サブタイプで異なるテーブルを作成する。スーパータイプのテーブルには共通属性のみを、サブタイプのテーブルには各サブタイプの固有属性及びスーパータイプのテーブルへの外部キーのみを含める。アプリ側からはjoinやunionを行う必要があり扱いが難しいがストレージ効率は良い。
他にも方法はありますが、ServiceNowではこの2つを理解しておけば十分です。
テーブル拡張モデル
ServiceNowにおけるテーブル拡張の際に、それを物理データベース上でどのように表現するかが”テーブルの拡張モデル”です。拡張モデルには次の3つがあります。
テーブル拡張モデル | RDB上での表現方法 | 説明 |
---|---|---|
Table per class(TPC) | クラステーブル継承 | 下記例外を除き基本的にこの拡張モデルが採用されている。 |
Table per hierarchy(TPH) | 単一テーブル継承 | Task(タスク)及びその拡張テーブルだけで採用されている拡張モデル。 |
Table per Partition(TPP) | 単一テーブル継承の亜種 | CMDB関連テーブルだけで採用されている拡張モデル。TPHのテーブルのカラム数、レコードサイズ制限(後述)の問題を解消したもの。 |
参照: Table extension and classes, KB1080488 テーブル構造の FAQ
TPHはタスクテーブルだけで採用されており、タスクテーブルのパフォーマンス向上のために導入されたそうです。多くの標準機能で使われているタスクテーブルはTPCの場合頻繁にテーブルのjoinやunionが発生しパフォーマンスに影響を与えるのだと思われます。
TPPはCMDBで採用されているとのことです。CMDBはかなり深い階層構造を持ち、また項目数が多いテーブルも多いです。そのため、単一テーブル継承によるパフォーマンス向上効果を得つつも、問題点であるテーブルのカラム数、レコードサイズの制約を解消した仕組みになっているようです。
TPH、TPPの場合のデータベース上の物理的なテーブルの確認方法
TPHやTPPの場合の、ServiceNowにおける論理的なテーブル(Task, Incident, Problemなど)とデータベース上の物理なテーブルの関係はStorage Column Aliases[sys_storage_alias]テーブルで確認することができます。(メニューの検索欄に”sys_storage_alias.list”と打ち込む)
例えば、Incident(インシデント)テーブルのCaller[caller_id]項目のレコードを確認すると、データベース上は”task”テーブルの”a_ref_4″カラムに対応していることがわかります。
参考: Understanding Storage Aliasing for Task
タスクテーブルはRDBMS(MySQL)のカラム数、カラムサイズの上限に注意
ServiceNowはRDBMSとして基本的にMySQLを使っているため、テーブルのカラム数とレコードサイズの上限に関してMySQLの制約に起因した下記の制約が存在します。
- カラム数: 4096個
- レコードサイズ: 65,535バイト
参考: KB0749585 Tables & Dictionary – Frequently asked Questions (FAQ)
この制約は全てのテーブルに共通ですが、特にTPHのタスクテーブルは全ての拡張テーブルのカラムがDB上では同じ物理テーブル(taskテーブル)に作成されるため、カラム数とレコードサイズの上限に注意が必要です。
実際に過去の案件でTaskテーブルを拡張したテーブルに大量のカスタムフィールドを追加した結果、この制約に抵触しカラムが追加できなくなった例がありました。
Taskテーブルのカラム数、レコードサイズの制約への対応策であるGlomming
Taskテーブルは標準の様々な機能で使われており、将来的にもどんどん拡張されていくことが予想されます。このとき、上述の制約に抵触してしまわないのでしょうか。この問題は根本的に解決はされていませんが、この影響を緩和するための仕組みが存在します。
具体例を用いて説明します。Storage Column Aliases[sys_storage_alias]で、物理テーブルのカラム名”a_str_1″に対応するIncident, Problemテーブルのフィールドを探してみると、IncidentテーブルのCategory項目と、ProblemテーブルのSubcategory項目は物理テーブル上では同じ”a_str_1″カラムに対応していることがわかります。
一方で、Taskテーブルの項目は、それぞれServiceNow上の論理テーブルの項目名と同名の物理カラムを持っていることがわかります。
つまり、下図のように、スーパータイプ=Taskテーブルの項目は論理テーブルの項目に対応したカラムを物理テーブル上にも作成するが、サブタイプ=Incident,Problemなどの項目は論理テーブルの同じデータ型の項目を物理テーブル上の1つのカラムに対応付けて保持しているのです。
ServiceNowではこの方式をGlommingと呼んでおり、これによってタスクテーブルが多くの子テーブルを持っていても、物理テーブルのカラムの上限に達するのを抑制し、またストレージ容量の節約にも寄与しているのです。
タスクテーブルをTPCで拡張する方法
タスクを拡張したテーブルや、標準のタスクの派生テーブルに対して大量のカスタムテーブルを追加することが予想される場合は、TPHではなくTPCで拡張したくなるでしょう。
このときは、まずは設計を見直し、できる限り標準通り使って、大量のカスタムフィールドを追加しないようにすべきですが、拡張モデルを変更する方法は一応存在します。
具体的な方法は公開ドキュメント等に掲載されていなかったのでこのブログでも公開するのはやめておきます。必要に応じてServiceNow社に問い合わせてみてください。
なお、タスクテーブルの拡張モデルをTPCに変更する設定は、開発時だけでなく、Application Repositoryのインストール時にインストール先の環境に対しても行っておかなければならないので注意です。
以上です。
コメント