メインコンテンツへスキップ
見出し画像

ServiceNowの添付ファイルはDBのどこに保存される? sys_attachmentの内部構造


    「添付ファイルが消えたと言われたが、どのテーブルを見ればいいのか分からない」という相談を受けることがあります。ServiceNowでは、フォームに添付したファイルを保存しても、incidentのような業務テーブルに列は増えません。実体はsys_attachment(メタ情報)とsys_attachment_doc(本体)という2つの専用テーブルに集約されます。Zurich PDIの実レコードで、どの項目を見れば添付先やサイズ、種類が分かるかを確認しました。

    検証環境:Zurich PDI / OOTB / 2026-08-08 確認


    画像

    結論:添付は sys_attachment と sys_attachment_doc の2テーブルに集約される

    先に全体像です。

    • 添付を保存しても、incidentのような業務テーブルに列は増えません。ファイルはsys_attachment(メタ情報・1ファイル1行)とsys_attachment_doc(本体・分割チャンク)という2つの専用テーブルに集約されます。

    • 今回のPDIでは、sys_attachmentが2,999件、sys_attachment_docが20,879件でした。本体側が約7倍多いのは、1つのファイルが複数のチャンクに分かれて保存されるためです。

    • 添付先の業務レコードは、sys_attachmentが持つtable_nameとtable_sys_idのペアだけで特定されます。どのテーブルに添付しても、保存先はこの2テーブルのままです。


    画像

    図の色は役割を示します。濃紺は起点の業務レコード、緑はメタ情報を持つsys_attachment、橙は件数の多い本体側のsys_attachment_doc、水色は別記事への参照です。仕組みは単純です。覚えるべきテーブルは2つだけで、あとはこの2つのどちらを見ているかを意識すれば迷いません。


    添付はどの業務レコードのものか:table_nameとtable_sys_idで分かる

    sys_attachmentは、2つのフィールドのペアで添付先を特定します。table_nameは添付先テーブルの物理名(例 incident)、table_sys_idは添付先レコードのsys_idです。この2つが分かれば、どのレコードに何が添付されているかを逆引きできます。


    画像

    この設計のポイントは、どのテーブルのどのレコードに添付しても、保存先が常にsys_attachmentとsys_attachment_docに集約されることです。incidentに添付してもkb_knowledgeに添付しても、業務テーブル側の構造は変わりません。添付先はtable_nameとtable_sys_idのペアだけで表現されます。

    今回のPDIで業務テーブルの内訳を数えると、incidentが11件、kb_knowledgeが1件でした。件数はどちらも少なく、大半はシステムが内部で使う画像やヘルプコンテンツです。上位を見ると、sys_ux_theme_assetが111件、sys_product_helpが108件、gsw_content_informationが53件と続きます。UIのテーマ素材やヘルプ記事の挿絵など、管理者が意識して添付したわけではないファイルが上位を占めています。人が能動的に添付したファイルは、実は全体のごく一部です。

    添付の一覧は、次のURLでサイズの大きい順に確認できます(先頭の<YourInstance>は自分のインスタンスに置き換えます)。

    https://<YourInstance>/sys_attachment_list.do?sysparm_query=ORDERBYDESCsize_bytes


    画像

    添付一覧の72%はZZ_YYプレフィックスの隠し添付だった

    table_nameの内訳をすべて数えると、ZZ_YYで始まる値が2,156件あり、全体の72%を占めていました。ServiceNowがFile Attachment型フィールドの実体や、標準の添付一覧に出したくない添付を隠すために、table_nameを書き換える慣習によるものです。この慣習を知らずに一覧を眺めると、大半がZZ_YYのノイズに見えてしまい、目的の添付を探すのに時間がかかります。業務ファイルを探すときは、この2,156件を先に除外してから絞り込むと早くたどり着けます。

    添付が見当たらないときにまず見る場所

    「添付が消えた」という相談を受けたら、まずtable_sys_idを対象レコードのsys_idに絞って一覧を開きます。table_nameとtable_sys_idの両方を条件に加えると、そのレコードに紐づく添付だけに絞り込めるという仕組みです。スクリプトから同じ絞り込みをしたい場合は、はじめてのGlideRecordの要領で、sys_attachmentテーブルをtable_nameとtable_sys_idの条件でクエリします。それでも件数が多いときは、content_typeやsize_bytesを条件に加えて範囲を狭めます。


    sys_attachmentが持つ主なフィールド

    sys_attachmentは、ファイルのメタ情報を役割ごとに持ちます。大きく分けると次の5グループに整理できます。

    • 添付先 … table_name / table_sys_id

    • ファイル属性 … file_name / content_type

    • サイズと圧縮 … size_bytes / size_compressed / compressed / chunk_size_bytes

    • 画像メタ … image_width / image_height / average_image_color

    • 状態 … state / hash


    画像

    ポイントは、sys_attachmentが単独で添付に関するほぼすべての情報を持っていることです。ファイルの中身そのもの以外は、このテーブルを見るだけで把握できます。size_bytesとsize_compressedを見比べれば、圧縮でどれだけ縮んだかが分かる仕組みです。compressedがtrueの添付は、size_compressedがsize_bytesより小さくなります。すでに圧縮済みのzipのようなファイルでは、この差がほとんど出ません。hashも便利です。同じファイルが重複して添付されていないかを、hash列の値を突き合わせるだけで確認できます。

    主なフィールドは次のとおりです。ラベルは画面上の表示名で、実機どおり英語で記載します。


    画像

    固有フィールドは、次のURLで一覧できます。

    https://<YourInstance>/sys_dictionary_list.do?sysparm_query=name=sys_attachment^elementISNOTEMPTY


    画像

    公式のAdministering attachments(Zurich)に、添付のシステムプロパティやテーブル単位での添付制御の方法が説明されています。

    stateに選択肢定義はなく自由文字列だった

    sys_attachmentのstateは、選択肢(choice)の定義を持たず、自由文字列でした。200件のサンプルでは、空が181件、availableが18件、pendingが1件です。アップロード中や処理中の状態を表すと考えられますが、内部の遷移条件は今回の検証範囲外としました。


    添付の中身(バイナリ本体)はどこにあるのか

    ここまではメタ情報側の話です。ファイルの中身そのものは、sys_attachment_docにbase64のチャンクとして分割保存されます。1つの添付が複数行に分かれる仕組みと、圧縮率によってチャンク数がどう変わるかは、対になる記事「添付の実体(sys_attachment_doc)はbase64で分割保存」で詳しく確認しています。


    添付の種類はどう分布しているか(content_type)


    画像

    content_typeの分布は、画像(image/pngとimage/svg+xml)に大きく偏っていました。全2,999件のうち、image/pngが1,122件、image/svg+xmlが1,122件で、この2種類だけで全体の75%を占めます。text/csvも309件あり、これはアップグレード関連のマニフェストファイルなど、システムが内部で生成したものが中心でした。application/zipやapplication/javascriptも数十件単位で見つかり、こちらはアプリケーションのパッケージや静的ファイルの実体と考えられます。

    実務で調べ物をするときは、content_typeが手がかりになります。text/csvやapplication/zipで極端にサイズが大きい行が並んでいたら、エクスポート結果やパッケージファイルである可能性が高いという見当がつきます。image系中心の一覧なら、システム由来の素材だと考えてよいでしょう。

    一覧をcontent_typeでGROUP BYすると、種類ごとの件数を確認できます。

    https://<YourInstance>/sys_attachment_list.do?sysparm_query=GROUPBYcontent_type


    画像

    なぜ画像ファイルが大半を占めるのか

    PDIはOOTBのままなので、バナー画像・ヘルプ画像・UI素材のようなシステム由来の画像が大半です。業務ファイル(PDFやOffice文書)はほとんどありません。実環境では、ここに業務文書が加わって分布が変わります。


    添付の最大サイズはどこで決まるか

    添付の最大サイズは、システムプロパティで制御されます。公式ドキュメントによると、com.glide.attachment.max_size(MB単位)が全体の最大添付サイズを規定し、新規OOTBインスタンスの既定は1024MBです。プロパティの探し方や役割そのものは、「システムプロパティ(sys_properties)は設定値の置き場」で扱っています。

    今回のPDIでは、このプロパティの実値までは確認していません。実環境でサイズ制限を調べるときは、sys_propertiesで実値を確認します。アップロードが途中で止まる、大きなファイルだけ添付に失敗するという相談を受けたときは、まずこのプロパティが既定値のままか、環境側で引き下げられていないかを疑うのが近道です。原因の多くはここにあります。


    実機で気づいたこと

    前回確認からsys_attachmentが150件増えていた

    同じ環境を7週間後に数え直すと、2,849件だった件数が2,999件になっていました。150件の増加です。sys_attachment_docも20,455件から20,879件に増えていました。業務データを何も触っていなくても、プラットフォームの更新やヘルプコンテンツの追加だけで母数が動きます。件数を根拠にするときは、確認した時点の数字であることを前提にしたほうがよいと感じました。同じ理由で、この記事の数字も次に読んだ時点では少しずれているはずです。

    ZZ_YYだけでなくinvisible.でも隠す添付があった

    table_nameの内訳を全件見て気づいたのが、invisible.で始まる値です。invisible.sys_app_hash_inventoryが307件、invisible.sys_store_appが45件で、合わせて352件、全体の12%でした。最初はZZ_YYプレフィックスだけが隠し添付の目印だと思っていましたが、実際には別の命名規則がもう1つ存在します。ZZ_YYとinvisible.を合わせると、全体の84%が何らかの形で通常の添付一覧から外されていることになります。命名規則が1つとは限らないと分かってからは、table_nameを見るときに他のプレフィックスも探す癖がつきました。

    sys_attachment自身に添付された添付が22件あった

    table_nameの値そのものがsys_attachmentという行が22件ありました。添付レコードに対してさらに添付が付いている状態です。用途までは確認していませんが、添付先が業務テーブルとは限らないという点は、絞り込みの条件を組むときに覚えておく価値があります。同じ構造がsys_attachment_doc側にも起きているかどうかは、今回は確認していません。


    実務では何に使えるか:添付調査の順番

    「添付が見当たらない」という問い合わせを受けたときは、次の順番で確認します。

    1. table_sys_idを対象レコードのsys_idに絞り、そのレコードの添付だけを一覧する。table_nameを付け忘れると、他のテーブルの同名sys_idを拾ってしまうことがあるので両方を条件に入れる

    2. table_nameが業務テーブル名と一致しているかを見る(ZZ_YYやinvisible.始まりならシステム側の隠し添付で、ユーザーが探している業務ファイルではない可能性が高い)

    3. content_typeとsize_bytesで、探しているファイルの手がかりを絞る。相手から聞いたファイル形式やおおよそのサイズと突き合わせる

    4. それでも見当たらないなら、削除された可能性を疑う

    この4段階で見つからない添付は、そもそもアップロードが完了していなかった可能性もあります。アップロード時のエラーやサイズ超過がなかったかも、あわせて確認しておくと二度手間になりません。

    削除された記録そのものを追いたい場合は、Incidentの「誰が何を変えたか」はどこに残るか(sys_audit)で扱った仕組みが参考になります。特定のロールだけが添付を読めないという相談には、ACLの構造を扱った「ロールを付けたのに見えない理由:ACL(sys_security_acl)」が近道です。


    まとめ

    ServiceNowの添付ファイルは、業務テーブルに列を増やさず、sys_attachment(メタ情報)とsys_attachment_doc(本体)という2つの専用テーブルに集約されます。添付先はtable_nameとtable_sys_idのペアで特定され、今回のPDIではsys_attachmentが2,999件、sys_attachment_docが20,879件でした。

    table_nameの内訳を見ると、業務ファイルはごく一部で、大半はZZ_YYやinvisible.といったプレフィックスを持つシステム由来の添付です。添付を調べるときは、まずこのノイズを見分けることから始めると、目的の添付に早くたどり着けます。ファイルの中身そのものを追いたくなったら、sys_attachment_doc側の記事に進みます。

    よくある質問

    Q1. incidentに添付したファイルは、sys_attachmentのどこで見分けられますか

    table_nameがincidentで、table_sys_idが対象incidentレコードのsys_idと一致する行を探します。この2つのフィールドが添付先を特定する唯一の手がかりで、incidentテーブル側には添付を示す列はありません。他の業務テーブルでも考え方は同じです。

    Q2. ZZ_YYやinvisible.で始まる添付は削除しても問題ありませんか

    本記事ではその判断はしていません。File Attachment型フィールドの実体や、システム内部で使う画像である可能性が高く、安易に削除すると別の機能に影響することがあります。用途が分からない添付は、まずどのテーブルからどう参照されているかを確認してから扱います。判断に迷う添付は、削除ではなく調査を優先したほうが安全です。

    Q3. sys_attachmentとsys_attachment_docのどちらを先に見ればいいですか

    添付先やファイルの種類、サイズを知りたいときはsys_attachmentです。ファイルの中身そのものやチャンクの並びを追いたいときだけ、sys_attachment_docを見ます。多くの調査はsys_attachmentだけで完結します。

    Q4. table_sys_idだけで検索しても大丈夫ですか

    おすすめしません。table_sys_idはレコードのsys_idであり、テーブルをまたいで値が重複することがあります。table_nameを条件に加えないと、まったく別のテーブルの同名sys_idを持つ添付を拾ってしまう可能性があります。table_nameとtable_sys_idは、必ずセットで条件に加えるのが安全です。この2つはいつも一緒に扱う値だと覚えておきます。


    次に読むなら

    用語

    • PDI … Personal Developer Instance(無料の検証用インスタンス)

    • OOTB … Out of the Box(初期設定のまま)

    • table_name / table_sys_id … 添付先のテーブルとレコードを指すペア

    • チャンク … ファイルを分割した断片(sys_attachment_docの1行が1チャンク)

    • ZZ_YY / invisible. … 標準の添付一覧に出さない隠し添付に使われるtable_nameの慣習

    • content_type … 添付ファイルのMIMEタイプ(image/pngなど)

    • hash … 添付の中身から計算される識別値。重複確認に使える

    実機で調べるときに使ったURL

    先頭に自分のインスタンスを付けて開きます。

    添付メタ一覧(サイズ降順)  : sys_attachment_list.do?sysparm_query=ORDERBYDESCsize_bytes
    添付の種類分布            : sys_attachment_list.do?sysparm_query=GROUPBYcontent_type
    table_name別の集計        : sys_attachment_list.do?sysparm_query=GROUPBYtable_name
    sys_attachment 固有項目   : sys_dictionary_list.do?sysparm_query=name=sys_attachment^elementISNOTEMPTY
    特定レコードの添付        : sys_attachment_list.do?sysparm_query=table_name=incident^table_sys_id=<対象レコードのsys_id>

    参考リンク

    検証環境と未検証範囲

    件数はZurich PDI(OOTB)で2026-08-08に確認したものです。一覧画面の件数表示と実レコードを突き合わせて数えており、推定やサンプリングではありません。state(自由文字列)のサンプル値のみ2026-06-21確認分を継続利用しています。本番環境やカスタマイズ済みの環境では、件数・分布・プロパティ値が異なります。同じ理由で、この記事の数字をそのまま自分の環境に当てはめず、必ず自分のインスタンスで確認し直すのが安全です。

    確認した範囲は次のとおりです。

    • sys_attachment / sys_attachment_docの継承(独立テーブル)と1対多の関係

    • 全件数(sys_attachment 2,999 / sys_attachment_doc 20,879)

    • table_name(業務テーブル・ZZ_YY・invisible.)とcontent_typeの分布

    • sys_attachmentの主な固有フィールドとstateの実値

    確認していない範囲は次のとおりです(断定しません)。

    • 添付プロパティの実値(max_size等)

    • GlideSysAttachment / REST Attachment APIの挙動

    • 添付のACL詳細

    • 外部ストレージ(Attachment store)構成

    • invisible.プレフィックスの添付が使われる具体的な機能

    これらは別記事で扱います。


    このシリーズの記事一覧

    ServiceNowの機能を1テーマずつ実機で確かめた記事を、分類ごとにまとめています。読みたいテーマから辿れます。

    → ServiceNow 観察日記 - 目次 -

     
     
    ServiceNowのPDI(Personal Developer Instance)を実機で観察して、Noteに記事を書いています 実装・運用・教育の現場視点で淡々と記録中です リクエストがあればその記事も書きます 個人の観察日記です

    あなたへのおすすめ