> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-parallel-read-in-order-multi-part.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> `user.xml` 設定ファイルの `profiles` セクションで設定に関する制約を定義すると、ユーザーが `SET` クエリで一部の設定を変更できないようにできます。

# 設定に関する制約

<h2 id="overview">
  概要
</h2>

ClickHouse では、設定に対する「制約」とは、設定に適用できる制限やルールを指します。これらの制約は、データベースの安定性、セキュリティ、そして予測可能な動作を維持するために使用できます。

<h2 id="defining-constraints">
  制約の定義
</h2>

設定に対する制約は、`user.xml` 設定ファイルの `profiles` セクションで
定義できます。これにより、ユーザーが
[`SET`](/ja/reference/statements/set)ステートメントを使用して一部の設定を変更することを
禁止できます。

制約は次のように定義します。

```xml theme={null}
<profiles>
  <user_name>
    <constraints>
      <setting_name_1>
        <min>lower_boundary</min>
      </setting_name_1>
      <setting_name_2>
        <max>upper_boundary</max>
      </setting_name_2>
      <setting_name_3>
        <min>lower_boundary</min>
        <max>upper_boundary</max>
      </setting_name_3>
      <setting_name_4>
        <readonly/>
      </setting_name_4>
      <setting_name_5>
        <min>lower_boundary</min>
        <max>upper_boundary</max>
        <changeable_in_readonly/>
      </setting_name_5>
      <setting_name_6>
        <min>lower_boundary</min>
        <max>upper_boundary</max>
        <disallowed>value1</disallowed>
        <disallowed>value2</disallowed>
        <disallowed>value3</disallowed>
        <changeable_in_readonly/>
      </setting_name_6>
    </constraints>
  </user_name>
</profiles>
```

ユーザーが制約に違反しようとすると、例外が発生し、
設定は変更されないままです。

<h2 id="types-of-constraints">
  制約の種類
</h2>

ClickHouse でサポートされている制約には、いくつかの種類があります。

* `min`
* `max`
* `disallowed`
* `readonly` (別名 `const`)
* `changeable_in_readonly`

`min` 制約と `max` 制約は、数値設定の上限値と下限値を指定するもので、組み合わせて使用できます。

`disallowed` 制約は、特定の設定に対して許可しない特定の値を指定するために使用できます。

`readonly` または `const` 制約は、ユーザーが対応する設定を一切変更できないことを示します。

`changeable_in_readonly` 制約タイプでは、`readonly` 設定が `1` に設定されている場合でも、設定を `min`/`max` の範囲内で変更できます。
それ以外の場合、`readonly=1` モードでは設定の変更は許可されません。

<Note>
  `changeable_in_readonly` がサポートされるのは、`settings_constraints_replace_previous`
  が有効になっている場合のみです。

  ```xml theme={null}
  <access_control_improvements>
    <settings_constraints_replace_previous>true</settings_constraints_replace_previous>
  </access_control_improvements>
  ```
</Note>

<h3 id="readonly-changeable-in-readonly">
  読み取り専用モードで `readonly` を変更可能にしない
</h3>

<Warning>
  誰にも割り当てていないプロファイルも含め、すべてのプロファイルで `readonly` を `changeable_in_readonly` のリストに含めないでください。プロファイル名はどのセッションからでも選択できます。
</Warning>

`readonly` 自体を `changeable_in_readonly` に指定しないでください。指定してしまうと、同じCONSTRAINTで `0` も禁止していない限り、`readonly = 1` で開始したセッションが `SET readonly = 0` を実行でき、そのセッションが既に持つ権限で許可されている書き込みクエリを再び実行できるようになります。

これは割り当て済みのプロファイルに限った話ではなく、定義したすべてのプロファイルで問題になります。

* `SET profile` はアクセスチェックの対象ではないため、どのセッションでも任意のプロファイルを名前で選択できます。誰にも割り当てていないプロファイルであっても選択可能です。ただし、そのプロファイルによって変更される内容は、そのセッションで既に有効なCONSTRAINTに照らしてチェックされます。
* HTTP 経由の場合、`GET` リクエストが `readonly = 2` に強制されるのは、実効値がそのままでは `0` になる場合のみです。そのため、`readonly = 1` を設定しつつ読み取り専用モードでの `readonly` の変更も許可しているプロファイルでは、`GET` リクエストで値を `0` に切り替えて書き込みができてしまうため、この保護が機能しなくなります。

<h2 id="multiple-constraint-profiles">
  複数の制約プロファイル
</h2>

ユーザーに対して複数のプロファイルが有効になっている場合、制約はマージされます。
マージ処理の動作は `settings_constraints_replace_previous` によって決まります。

* **true** (推奨) : 同じ設定に対する制約はマージ時に置き換えられます。
  そのため、最後の制約が使用され、それ以前の制約はすべて無視されます。
  これには、新しい制約で設定されていないフィールドも含まれます。
* **false** (デフォルト) : 同じ設定に対する制約は、次のようにマージされます。
  未設定の制約タイプはすべて前のプロファイルから引き継がれ、
  設定済みの制約タイプはすべて新しいプロファイルの値で置き換えられます。

<h2 id="read-only">
  読み取り専用モード
</h2>

読み取り専用モードは `readonly` 設定によって有効になります。これは `readonly` という CONSTRAINT の種別とは
別のものなので混同しないでください。`readonly = 1` の場合でも、`changeable_in_readonly` CONSTRAINT が
許可していれば、通常は拒否される設定であっても変更できます。この設定の各値の意味については
[設定リファレンス](/ja/reference/settings/session-settings/other#readonly)を、各値がどの種類のクエリを許可するか、
および HTTP インターフェイスがこの値をどのように設定するかについては
[クエリの権限](/ja/concepts/features/configuration/settings/permissions-for-queries#readonly)を参照してください。

<h3 id="example-read-only">
  例
</h3>

`users.xml` に次の行を記述します。

```xml theme={null}
<profiles>
  <default>
    <max_memory_usage>10000000000</max_memory_usage>
    <force_index_by_date>0</force_index_by_date>
    ...
    <constraints>
      <max_memory_usage>
        <min>5000000000</min>
        <max>20000000000</max>
      </max_memory_usage>
      <force_index_by_date>
        <readonly/>
      </force_index_by_date>
    </constraints>
  </default>
</profiles>
```

次のクエリはいずれも例外をスローします:

```sql theme={null}
SET max_memory_usage=20000000001;
SET max_memory_usage=4999999999;
SET force_index_by_date=1;
```

```text theme={null}
Code: 452, e.displayText() = DB::Exception: Setting max_memory_usage should not be greater than 20000000000.
Code: 452, e.displayText() = DB::Exception: Setting max_memory_usage should not be less than 5000000000.
Code: 452, e.displayText() = DB::Exception: Setting force_index_by_date should not be changed.
```

<Note>
  `default` プロファイルは特別な扱いになります。`default` プロファイルに定義された
  すべての制約はデフォルトの制約となるため、各ユーザーに対して明示的に上書きされない限り、
  すべてのユーザーに適用されます。
</Note>

<h2 id="constraints-on-merge-tree-settings">
  MergeTree 設定の制約
</h2>

[MergeTree 設定](/ja/reference/settings/merge-tree-settings)には制約を設定できます。
これらの制約は、MergeTree エンジンのテーブルを作成するとき、
またはそのストレージ設定を変更するときに適用されます。

`<constraints>` セクションで参照する場合、MergeTree 設定名の先頭に
`merge_tree_` プレフィックスを付ける必要があります。

<h3 id="example-mergetree">
  例
</h3>

`storage_policy` を明示的に指定した新しいテーブルの作成を禁止できます

```xml theme={null}
<profiles>
  <default>
    <constraints>
      <merge_tree_storage_policy>
        <const/>
      </merge_tree_storage_policy>
    </constraints>
  </default>
</profiles>
```
