You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by mo...@apache.org on 2026/10/19 15:58:41 UTC
(doris-website) branch master updated: [i18n](ko) Translate 100 documentation pages (T09 20261019T075224Z-019) (#4387)
This is an automated email from the ASF dual-hosted git repository.
morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris-website.git
The following commit(s) were added to refs/heads/master by this push:
new e10ff44b63a [i18n](ko) Translate 100 documentation pages (T09 20261019T075224Z-019) (#4387)
e10ff44b63a is described below
commit e10ff44b63ad325daf69b63e43ee4511ad9c4a33
Author: Mingyu Chen (Rayner) <mo...@gmail.com>
AuthorDate: Mon Oct 19 16:58:34 2026 +0100
[i18n](ko) Translate 100 documentation pages (T09 20261019T075224Z-019) (#4387)
Translate 100 English documentation pages into Korean with local Codex.
Source: `f1464d3fb0dd6007d36104a970c3bc7db282d822`. Model:
`gpt-6.1-sol`; reasoning effort: `xhigh`.
These are machine translations requiring Korean proofreading. Each
document has its own state shard.
Retry summary: 65/75 generated pages passed on the first attempt; 25
pages copied across versions; 86 total model calls. Prompt rules used:
comments, inline-code, code-blocks, numbers, metadata, headings,
glossary.
| Source | Operation | Model calls | Result |
| --- | --- | ---: | --- |
|
`docs/sql-manual/sql-statements/table-and-view/table/SHOW-PARTITION-ID.md`
| Translate | 1 | Local gates passed |
|
`docs/sql-manual/sql-statements/table-and-view/table/SHOW-PARTITION.md`
| Translate | 1 | Local gates passed |
|
`docs/sql-manual/sql-statements/table-and-view/table/SHOW-PARTITIONS.md`
| Translate | 1 | Local gates passed |
| `docs/sql-manual/sql-statements/table-and-view/table/SHOW-TABLE-ID.md`
| Translate | 1 | Local gates passed |
|
`docs/sql-manual/sql-statements/table-and-view/table/SHOW-TABLE-STATUS.md`
| Translate | 1 | Local gates passed |
| `docs/sql-manual/sql-statements/table-and-view/table/SHOW-TABLES.md` |
Translate | 1 | Local gates passed |
|
`docs/sql-manual/sql-statements/table-and-view/table/TRUNCATE-TABLE.md`
| Translate | 1 | Local gates passed |
| `docs/sql-manual/sql-statements/table-and-view/view/ALTER-VIEW.md` |
Translate | 1 | Local gates passed |
| `docs/sql-manual/sql-statements/table-and-view/view/CREATE-VIEW.md` |
Translate | 1 | Local gates passed |
| `docs/sql-manual/sql-statements/table-and-view/view/DROP-VIEW.md` |
Translate | 1 | Local gates passed |
|
`docs/sql-manual/sql-statements/table-and-view/view/SHOW-CREATE-VIEW.md`
| Translate | 1 | Local gates passed |
| `docs/sql-manual/sql-statements/table-and-view/view/SHOW-VIEW.md` |
Translate | 1 | Local gates passed |
| `docs/sql-manual/sql-statements/transaction/BEGIN.md` | Translate | 1
| Local gates passed |
| `docs/sql-manual/sql-statements/transaction/COMMIT.md` | Translate | 1
| Local gates passed |
| `docs/sql-manual/sql-statements/transaction/ROLLBACK.md` | Translate |
1 | Local gates passed |
| `docs/sql-manual/sql-statements/transaction/SHOW-TRANSACTION.md` |
Translate | 1 | Local gates passed |
| `docs/sql-manual/sql-statements/types/SHOW-DATA-TYPES.md` | Translate
| 2 | Local gates passed |
| `docs/sql-manual/sql-statements/types/SHOW-TYPECAST.md` | Translate |
1 | Local gates passed |
| `docs/table-design/auto-increment.md` | Translate | 2 | Local gates
passed |
| `docs/table-design/column-compression.md` | Translate | 1 | Local
gates passed |
| `docs/table-design/data-model/aggregate.md` | Translate | 1 | Local
gates passed |
| `docs/table-design/data-model/duplicate.md` | Translate | 1 | Local
gates passed |
| `docs/table-design/data-model/intro.mdx` | Translate | 1 | Local gates
passed |
| `docs/table-design/data-model/merge-on-write.md` | Translate | 1 |
Local gates passed |
| `docs/table-design/data-model/tips.md` | Translate | 1 | Local gates
passed |
| `docs/table-design/data-model/unique.md` | Translate | 1 | Local gates
passed |
| `docs/table-design/data-partitioning/auto-partitioning.md` | Translate
| 2 | Local gates passed |
| `docs/table-design/data-partitioning/basic-concepts.mdx` | Translate |
1 | Local gates passed |
| `docs/table-design/data-partitioning/common-issues.md` | Translate | 1
| Local gates passed |
| `docs/table-design/data-partitioning/data-bucketing.md` | Translate |
1 | Local gates passed |
| `docs/table-design/data-partitioning/dynamic-partitioning.md` |
Translate | 1 | Local gates passed |
| `docs/table-design/data-partitioning/manual-partitioning.md` |
Translate | 1 | Local gates passed |
| `docs/table-design/data-partitioning/overview.md` | Translate | 1 |
Local gates passed |
| `docs/table-design/data-type.md` | Translate | 1 | Local gates passed
|
| `docs/table-design/index/bloomfilter.md` | Translate | 1 | Local gates
passed |
| `docs/table-design/index/index-overview.md` | Translate | 1 | Local
gates passed |
| `docs/table-design/index/inverted-index/custom-analyzer.md` |
Translate | 2 | Local gates passed |
| `docs/table-design/index/inverted-index/custom-normalizer.md` |
Translate | 1 | Local gates passed |
| `docs/table-design/index/inverted-index/overview.md` | Translate | 1 |
Local gates passed |
| `docs/table-design/index/inverted-index/scoring.md` | Translate | 1 |
Local gates passed |
| `docs/table-design/index/inverted-index/search-function.md` |
Translate | 1 | Local gates passed |
| `docs/table-design/index/inverted-index/search-operators.md` |
Translate | 1 | Local gates passed |
| `docs/table-design/index/ngram-bloomfilter-index.md` | Translate | 1 |
Local gates passed |
| `docs/table-design/index/prefix-index.md` | Translate | 1 | Local
gates passed |
| `docs/table-design/index/vector-index/behind-index.md` | Translate | 1
| Local gates passed |
| `docs/table-design/index/vector-index/hnsw.md` | Translate | 1 | Local
gates passed |
| `docs/table-design/index/vector-index/index-management.md` | Translate
| 1 | Local gates passed |
| `docs/table-design/index/vector-index/ivf-on-disk.md` | Translate | 1
| Local gates passed |
| `docs/table-design/index/vector-index/ivf.md` | Translate | 1 | Local
gates passed |
| `docs/table-design/index/vector-index/overview.md` | Translate | 1 |
Local gates passed |
| `docs/table-design/index/vector-index/performance-large-scale.md` |
Translate | 1 | Local gates passed |
| `docs/table-design/index/vector-index/performance.md` | Translate | 1
| Local gates passed |
| `docs/table-design/index/vector-index/practical-guide.md` | Translate
| 1 | Local gates passed |
| `docs/table-design/index/vector-index/quantization-survey.md` |
Translate | 1 | Local gates passed |
| `docs/table-design/index/vector-index/resource-estimation.md` |
Translate | 1 | Local gates passed |
| `docs/table-design/overview.mdx` | Translate | 1 | Local gates passed
|
| `docs/table-design/row-store.md` | Translate | 1 | Local gates passed
|
| `docs/table-design/schema-change.md` | Translate | 1 | Local gates
passed |
| `docs/table-design/storage-format.md` | Translate | 2 | Local gates
passed |
| `docs/table-design/storage-layout-overview.mdx` | Translate | 1 |
Local gates passed |
| `docs/table-design/tiered-storage/overview.md` | Translate | 1 | Local
gates passed |
| `docs/table-design/tiered-storage/remote-storage.md` | Translate | 1 |
Local gates passed |
| `docs/table-design/tiered-storage/tiered-ssd-hdd.md` | Translate | 1 |
Local gates passed |
| `versioned_docs/version-4.x/admin-manual/audit-plugin.md` | Copy from
current | 0 | Local gates passed |
|
`versioned_docs/version-4.x/admin-manual/auth/authentication-and-authorization.md`
| Translate | 1 | Local gates passed |
|
`versioned_docs/version-4.x/admin-manual/auth/authentication/internal.md`
| Copy from current | 0 | Local gates passed |
| `versioned_docs/version-4.x/admin-manual/auth/authentication/ldap.md`
| Translate | 1 | Local gates passed |
| `versioned_docs/version-4.x/admin-manual/auth/authorization/custom.md`
| Translate | 2 | Local gates passed |
| `versioned_docs/version-4.x/admin-manual/auth/authorization/data.md` |
Translate | 1 | Local gates passed |
|
`versioned_docs/version-4.x/admin-manual/auth/authorization/internal.md`
| Copy from current | 0 | Local gates passed |
|
`versioned_docs/version-4.x/admin-manual/auth/authorization/ranger-hive.md`
| Translate | 3 | Retained with warnings |
| `versioned_docs/version-4.x/admin-manual/auth/authorization/ranger.md`
| Copy from current | 0 | Local gates passed |
| `versioned_docs/version-4.x/admin-manual/auth/certificate.md` | Copy
from current | 0 | Local gates passed |
| `versioned_docs/version-4.x/admin-manual/auth/encryption-function.md`
| Copy from current | 0 | Local gates passed |
| `versioned_docs/version-4.x/admin-manual/auth/fe-certificate.md` |
Copy from current | 0 | Local gates passed |
|
`versioned_docs/version-4.x/admin-manual/auth/integrations/aws-authentication-and-authorization.md`
| Translate | 1 | Local gates passed |
|
`versioned_docs/version-4.x/admin-manual/auth/integrations/aws-iam-role.md`
| Copy from current | 0 | Local gates passed |
| `versioned_docs/version-4.x/admin-manual/auth/security-overview.md` |
Copy from current | 0 | Local gates passed |
| `versioned_docs/version-4.x/admin-manual/auth/tls-framework.md` | Copy
from current | 0 | Local gates passed |
|
`versioned_docs/version-4.x/admin-manual/cluster-management/elastic-expansion.md`
| Copy from current | 0 | Local gates passed |
| `versioned_docs/version-4.x/admin-manual/cluster-management/fqdn.md` |
Copy from current | 0 | Local gates passed |
| `versioned_docs/version-4.x/admin-manual/cluster-management/intro.mdx`
| Copy from current | 0 | Local gates passed |
|
`versioned_docs/version-4.x/admin-manual/cluster-management/load-balancing.md`
| Copy from current | 0 | Local gates passed |
|
`versioned_docs/version-4.x/admin-manual/cluster-management/time-zone.md`
| Translate | 1 | Local gates passed |
|
`versioned_docs/version-4.x/admin-manual/cluster-management/upgrade.md`
| Translate | 2 | Local gates passed |
| `versioned_docs/version-4.x/admin-manual/config/be-config.md` |
Translate | 2 | Local gates passed |
| `versioned_docs/version-4.x/admin-manual/config/config-dir.md` | Copy
from current | 0 | Local gates passed |
| `versioned_docs/version-4.x/admin-manual/config/fe-config.md` |
Translate | 1 | Local gates passed |
| `versioned_docs/version-4.x/admin-manual/config/ms-config.md` | Copy
from current | 0 | Local gates passed |
| `versioned_docs/version-4.x/admin-manual/config/user-property.md` |
Copy from current | 0 | Local gates passed |
|
`versioned_docs/version-4.x/admin-manual/data-admin/backup-restore/backup.md`
| Copy from current | 0 | Local gates passed |
|
`versioned_docs/version-4.x/admin-manual/data-admin/backup-restore/overview.md`
| Copy from current | 0 | Local gates passed |
|
`versioned_docs/version-4.x/admin-manual/data-admin/backup-restore/restore.md`
| Copy from current | 0 | Local gates passed |
| `versioned_docs/version-4.x/admin-manual/data-admin/overview.md` |
Copy from current | 0 | Local gates passed |
| `versioned_docs/version-4.x/admin-manual/data-admin/recyclebin.md` |
Copy from current | 0 | Local gates passed |
| `versioned_docs/version-4.x/admin-manual/log-management/be-log.md` |
Copy from current | 0 | Local gates passed |
| `versioned_docs/version-4.x/admin-manual/log-management/fe-log.md` |
Translate | 2 | Local gates passed |
| `versioned_docs/version-4.x/admin-manual/log-management/intro.mdx` |
Copy from current | 0 | Local gates passed |
|
`versioned_docs/version-4.x/admin-manual/maint-monitor/automatic-service-start.md`
| Translate | 1 | Local gates passed |
|
`versioned_docs/version-4.x/admin-manual/maint-monitor/disk-capacity.md`
| Copy from current | 0 | Local gates passed |
Validation:
- scope-ko: passed
- configuration-ko: passed
- state-protection-ko: passed
- syntax-ko: passed
- internal-links-ko: passed
Local checks reuse translation state, protection, Markdown/MDX syntax
and internal-link functions for Korean files.
Local validation does not build the website or run the CI test suites.
GitHub CI runs independently.
Failures are fed into the next translation prompt, with at most three
total model attempts per page.
The third translation is retained when local checks still fail, as
requested; this does not waive GitHub CI.
Retained warnings:
-
`versioned_docs/version-4.x/admin-manual/auth/authorization/ranger-hive.md`
/ protected-content: Restore protected source content: protected node
205: expected ["inlineCode",null,null,"core-site.xml"]; received
["inlineCode",null,null,"fe/conf/"] protected node 206: expected
["inlineCode",null,null,"fe/conf/"]; received
["inlineCode",null,null,"core-site.xml"] protected node 214: expected
["inlineCode",null,null,"domain_realm"]; received
["inlineCode",null,null,"/etc/krb5.conf"]
Remaining blocking local checks: none.
This batch is independent of other translation PRs. The runner continues
without waiting for merge.
<!-- korean-local-t09 source=f1464d3fb0dd6007d36104a970c3bc7db282d822
-->
Co-authored-by: morningman <mo...@apache.org>
---
.../table-and-view/table/SHOW-PARTITION-ID.md | 39 +
.../table-and-view/table/SHOW-PARTITION.md | 45 +
.../table-and-view/table/SHOW-PARTITIONS.md | 139 +
.../table-and-view/table/SHOW-TABLE-ID.md | 54 +
.../table-and-view/table/SHOW-TABLE-STATUS.md | 91 +
.../table-and-view/table/SHOW-TABLES.md | 99 +
.../table-and-view/table/TRUNCATE-TABLE.md | 79 +
.../table-and-view/view/ALTER-VIEW.md | 68 +
.../table-and-view/view/CREATE-VIEW.md | 88 +
.../table-and-view/view/DROP-VIEW.md | 45 +
.../table-and-view/view/SHOW-CREATE-VIEW.md | 55 +
.../table-and-view/view/SHOW-VIEW.md | 29 +
.../sql-manual/sql-statements/transaction/BEGIN.md | 43 +
.../sql-statements/transaction/COMMIT.md | 44 +
.../sql-statements/transaction/ROLLBACK.md | 44 +
.../sql-statements/transaction/SHOW-TRANSACTION.md | 83 +
.../sql-statements/types/SHOW-DATA-TYPES.md | 71 +
.../sql-statements/types/SHOW-TYPECAST.md | 81 +
.../current/table-design/auto-increment.md | 525 ++++
.../current/table-design/column-compression.md | 125 +
.../current/table-design/data-model/aggregate.md | 187 ++
.../current/table-design/data-model/duplicate.md | 87 +
.../current/table-design/data-model/intro.mdx | 134 +
.../table-design/data-model/merge-on-write.md | 99 +
.../current/table-design/data-model/tips.md | 201 ++
.../current/table-design/data-model/unique.md | 93 +
.../data-partitioning/auto-partitioning.md | 345 +++
.../data-partitioning/basic-concepts.mdx | 304 ++
.../data-partitioning/common-issues.md | 100 +
.../data-partitioning/data-bucketing.md | 283 ++
.../data-partitioning/dynamic-partitioning.md | 231 ++
.../data-partitioning/manual-partitioning.md | 256 ++
.../table-design/data-partitioning/overview.md | 95 +
.../current/table-design/data-type.md | 72 +
.../current/table-design/index/bloomfilter.md | 135 +
.../current/table-design/index/index-overview.md | 141 +
.../index/inverted-index/custom-analyzer.md | 637 ++++
.../index/inverted-index/custom-normalizer.md | 146 +
.../table-design/index/inverted-index/overview.md | 251 ++
.../table-design/index/inverted-index/scoring.md | 156 +
.../index/inverted-index/search-function.md | 497 ++++
.../index/inverted-index/search-operators.md | 187 ++
.../table-design/index/ngram-bloomfilter-index.md | 307 ++
.../current/table-design/index/prefix-index.md | 151 +
.../index/vector-index/behind-index.md | 398 +++
.../table-design/index/vector-index/hnsw.md | 461 +++
.../index/vector-index/index-management.md | 330 +++
.../table-design/index/vector-index/ivf-on-disk.md | 222 ++
.../current/table-design/index/vector-index/ivf.md | 459 +++
.../table-design/index/vector-index/overview.md | 610 ++++
.../index/vector-index/performance-large-scale.md | 246 ++
.../table-design/index/vector-index/performance.md | 172 ++
.../index/vector-index/practical-guide.md | 392 +++
.../index/vector-index/quantization-survey.md | 299 ++
.../index/vector-index/resource-estimation.md | 242 ++
.../current/table-design/overview.mdx | 251 ++
.../current/table-design/row-store.md | 153 +
.../current/table-design/schema-change.md | 361 +++
.../current/table-design/storage-format.md | 105 +
.../table-design/storage-layout-overview.mdx | 31 +
.../table-design/tiered-storage/overview.md | 128 +
.../table-design/tiered-storage/remote-storage.md | 298 ++
.../table-design/tiered-storage/tiered-ssd-hdd.md | 190 ++
.../version-4.x/admin-manual/audit-plugin.md | 89 +
.../auth/authentication-and-authorization.md | 392 +++
.../admin-manual/auth/authentication/internal.md | 223 ++
.../admin-manual/auth/authentication/ldap.md | 534 ++++
.../admin-manual/auth/authorization/custom.md | 241 ++
.../admin-manual/auth/authorization/data.md | 118 +
.../admin-manual/auth/authorization/internal.md | 185 ++
.../admin-manual/auth/authorization/ranger-hive.md | 878 ++++++
.../admin-manual/auth/authorization/ranger.md | 476 +++
.../version-4.x/admin-manual/auth/certificate.md | 235 ++
.../admin-manual/auth/encryption-function.md | 59 +
.../admin-manual/auth/fe-certificate.md | 110 +
.../aws-authentication-and-authorization.md | 685 +++++
.../admin-manual/auth/integrations/aws-iam-role.md | 159 +
.../admin-manual/auth/security-overview.md | 116 +
.../version-4.x/admin-manual/auth/tls-framework.md | 72 +
.../cluster-management/elastic-expansion.md | 193 ++
.../admin-manual/cluster-management/fqdn.md | 167 ++
.../admin-manual/cluster-management/intro.mdx | 61 +
.../cluster-management/load-balancing.md | 909 ++++++
.../admin-manual/cluster-management/time-zone.md | 320 ++
.../admin-manual/cluster-management/upgrade.md | 538 ++++
.../version-4.x/admin-manual/config/be-config.md | 1663 +++++++++++
.../version-4.x/admin-manual/config/config-dir.md | 29 +
.../version-4.x/admin-manual/config/fe-config.md | 3135 ++++++++++++++++++++
.../version-4.x/admin-manual/config/ms-config.md | 28 +
.../admin-manual/config/user-property.md | 55 +
.../data-admin/backup-restore/backup.md | 450 +++
.../data-admin/backup-restore/overview.md | 65 +
.../data-admin/backup-restore/restore.md | 199 ++
.../admin-manual/data-admin/overview.md | 99 +
.../admin-manual/data-admin/recyclebin.md | 125 +
.../admin-manual/log-management/be-log.md | 200 ++
.../admin-manual/log-management/fe-log.md | 251 ++
.../admin-manual/log-management/intro.mdx | 29 +
.../maint-monitor/automatic-service-start.md | 437 +++
.../admin-manual/maint-monitor/disk-capacity.md | 260 ++
.../default/4.x/admin-manual/audit-plugin.json | 49 +
.../auth/authentication-and-authorization.json | 37 +
.../admin-manual/auth/authentication/internal.json | 49 +
.../4.x/admin-manual/auth/authentication/ldap.json | 37 +
.../admin-manual/auth/authorization/custom.json | 46 +
.../4.x/admin-manual/auth/authorization/data.json | 37 +
.../admin-manual/auth/authorization/internal.json | 49 +
.../auth/authorization/ranger-hive.json | 65 +
.../admin-manual/auth/authorization/ranger.json | 49 +
.../default/4.x/admin-manual/auth/certificate.json | 49 +
.../4.x/admin-manual/auth/encryption-function.json | 49 +
.../4.x/admin-manual/auth/fe-certificate.json | 49 +
.../aws-authentication-and-authorization.json | 37 +
.../auth/integrations/aws-iam-role.json | 49 +
.../4.x/admin-manual/auth/security-overview.json | 49 +
.../4.x/admin-manual/auth/tls-framework.json | 49 +
.../cluster-management/elastic-expansion.json | 49 +
.../4.x/admin-manual/cluster-management/fqdn.json | 49 +
.../4.x/admin-manual/cluster-management/intro.json | 49 +
.../cluster-management/load-balancing.json | 49 +
.../admin-manual/cluster-management/time-zone.json | 37 +
.../admin-manual/cluster-management/upgrade.json | 46 +
.../default/4.x/admin-manual/config/be-config.json | 46 +
.../4.x/admin-manual/config/config-dir.json | 49 +
.../default/4.x/admin-manual/config/fe-config.json | 37 +
.../default/4.x/admin-manual/config/ms-config.json | 49 +
.../4.x/admin-manual/config/user-property.json | 49 +
.../data-admin/backup-restore/backup.json | 49 +
.../data-admin/backup-restore/overview.json | 49 +
.../data-admin/backup-restore/restore.json | 49 +
.../4.x/admin-manual/data-admin/overview.json | 49 +
.../4.x/admin-manual/data-admin/recyclebin.json | 49 +
.../4.x/admin-manual/log-management/be-log.json | 49 +
.../4.x/admin-manual/log-management/fe-log.json | 46 +
.../4.x/admin-manual/log-management/intro.json | 49 +
.../maint-monitor/automatic-service-start.json | 37 +
.../admin-manual/maint-monitor/disk-capacity.json | 49 +
.../table-and-view/table/SHOW-PARTITION-ID.json | 37 +
.../table-and-view/table/SHOW-PARTITION.json | 37 +
.../table-and-view/table/SHOW-PARTITIONS.json | 37 +
.../table-and-view/table/SHOW-TABLE-ID.json | 37 +
.../table-and-view/table/SHOW-TABLE-STATUS.json | 37 +
.../table-and-view/table/SHOW-TABLES.json | 37 +
.../table-and-view/table/TRUNCATE-TABLE.json | 37 +
.../table-and-view/view/ALTER-VIEW.json | 37 +
.../table-and-view/view/CREATE-VIEW.json | 37 +
.../table-and-view/view/DROP-VIEW.json | 37 +
.../table-and-view/view/SHOW-CREATE-VIEW.json | 37 +
.../table-and-view/view/SHOW-VIEW.json | 37 +
.../sql-statements/transaction/BEGIN.json | 37 +
.../sql-statements/transaction/COMMIT.json | 37 +
.../sql-statements/transaction/ROLLBACK.json | 37 +
.../transaction/SHOW-TRANSACTION.json | 37 +
.../sql-statements/types/SHOW-DATA-TYPES.json | 46 +
.../sql-statements/types/SHOW-TYPECAST.json | 37 +
.../current/table-design/auto-increment.json | 46 +
.../current/table-design/column-compression.json | 37 +
.../current/table-design/data-model/aggregate.json | 37 +
.../current/table-design/data-model/duplicate.json | 37 +
.../current/table-design/data-model/intro.json | 37 +
.../table-design/data-model/merge-on-write.json | 37 +
.../current/table-design/data-model/tips.json | 37 +
.../current/table-design/data-model/unique.json | 37 +
.../data-partitioning/auto-partitioning.json | 46 +
.../data-partitioning/basic-concepts.json | 37 +
.../data-partitioning/common-issues.json | 37 +
.../data-partitioning/data-bucketing.json | 37 +
.../data-partitioning/dynamic-partitioning.json | 37 +
.../data-partitioning/manual-partitioning.json | 37 +
.../table-design/data-partitioning/overview.json | 37 +
.../default/current/table-design/data-type.json | 37 +
.../current/table-design/index/bloomfilter.json | 37 +
.../current/table-design/index/index-overview.json | 37 +
.../index/inverted-index/custom-analyzer.json | 46 +
.../index/inverted-index/custom-normalizer.json | 37 +
.../index/inverted-index/overview.json | 37 +
.../table-design/index/inverted-index/scoring.json | 37 +
.../index/inverted-index/search-function.json | 37 +
.../index/inverted-index/search-operators.json | 37 +
.../index/ngram-bloomfilter-index.json | 37 +
.../current/table-design/index/prefix-index.json | 37 +
.../index/vector-index/behind-index.json | 37 +
.../table-design/index/vector-index/hnsw.json | 37 +
.../index/vector-index/index-management.json | 37 +
.../index/vector-index/ivf-on-disk.json | 37 +
.../table-design/index/vector-index/ivf.json | 37 +
.../table-design/index/vector-index/overview.json | 37 +
.../vector-index/performance-large-scale.json | 37 +
.../index/vector-index/performance.json | 37 +
.../index/vector-index/practical-guide.json | 37 +
.../index/vector-index/quantization-survey.json | 37 +
.../index/vector-index/resource-estimation.json | 37 +
.../default/current/table-design/overview.json | 37 +
.../default/current/table-design/row-store.json | 37 +
.../current/table-design/schema-change.json | 37 +
.../current/table-design/storage-format.json | 46 +
.../table-design/storage-layout-overview.json | 37 +
.../table-design/tiered-storage/overview.json | 37 +
.../tiered-storage/remote-storage.json | 37 +
.../tiered-storage/tiered-ssd-hdd.json | 37 +
200 files changed, 30184 insertions(+)
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/table/SHOW-PARTITION-ID.md b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/table/SHOW-PARTITION-ID.md
new file mode 100644
index 00000000000..36312f98770
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/table/SHOW-PARTITION-ID.md
@@ -0,0 +1,39 @@
+---
+{
+ "title": "SHOW PARTITION ID",
+ "language": "ko",
+ "description": "이 구문은 파티션 ID를 기준으로 해당 데이터베이스 이름, 테이블 이름, 파티션 이름을 찾는 데 사용합니다."
+}
+---
+
+## 설명 {#description}
+
+이 구문은 파티션 ID를 기준으로 해당 데이터베이스 이름, 테이블 이름, 파티션 이름을 찾는 데 사용합니다.
+
+## 구문 {#syntax}
+
+```sql
+SHOW PARTITION <partition_id>
+```
+
+## 필수 매개변수 {#required-parameters}
+
+**1. `<partition_id>`**
+
+> 파티션 ID
+
+## 접근 제어 요구 사항 {#access-control-requirements}
+
+이 SQL을 실행하는 사용자는 최소한 다음 권한을 가지고 있어야 합니다.
+
+| 권한 | 객체 | 비고 |
+|---------------------|----|----|
+| ADMIN_PRIV | | |
+
+## 예제 {#examples}
+
+1. 파티션 ID를 기준으로 해당 데이터베이스 이름, 테이블 이름, 파티션 이름을 찾습니다.
+
+ ```sql
+ SHOW PARTITION 10002;
+ ```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/table/SHOW-PARTITION.md b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/table/SHOW-PARTITION.md
new file mode 100644
index 00000000000..9a1229fcd0d
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/table/SHOW-PARTITION.md
@@ -0,0 +1,45 @@
+---
+{
+ "title": "SHOW PARTITION",
+ "language": "ko",
+ "description": "SHOW PARTITION은 지정된 파티션의 상세 정보를 표시하는 데 사용됩니다. 여기에는 연결된 데이터베이스의 이름과 ID가 포함됩니다."
+}
+---
+
+## 설명 {#description}
+
+SHOW PARTITION은 지정된 파티션의 상세 정보를 표시하는 데 사용됩니다. 여기에는 연결된 데이터베이스의 이름과 ID, 연결된 테이블의 이름과 ID, 파티션 이름이 포함됩니다.
+
+## 구문 {#syntax}
+
+```sql
+SHOW PARTITION <partition_id>
+```
+
+## 필수 매개변수 {#required-parameters}
+
+**<partition_id>**
+
+> 파티션의 ID입니다. 파티션 ID는 SHOW PARTITIONS 등의 방법으로 확인할 수 있습니다. 자세한 내용은 "SHOW PARTITIONS" 섹션을 참조하세요.
+
+## 접근 제어 요구 사항 {#access-control-requirements}
+
+이 SQL 명령을 실행하는 사용자는 최소한 `ADMIN_PRIV` 권한을 보유해야 합니다.
+
+## 예제 {#examples}
+
+파티션 ID가 13004인 파티션의 정보를 쿼리합니다:
+
+```sql
+SHOW PARTITION 13004;
+```
+
+결과:
+
+```text
++--------+-----------+---------------+-------+---------+
+| DbName | TableName | PartitionName | DbId | TableId |
++--------+-----------+---------------+-------+---------+
+| ods | sales | sales | 13003 | 13005 |
++--------+-----------+---------------+-------+---------+
+```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/table/SHOW-PARTITIONS.md b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/table/SHOW-PARTITIONS.md
new file mode 100644
index 00000000000..37efd9f29b1
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/table/SHOW-PARTITIONS.md
@@ -0,0 +1,139 @@
+---
+{
+ "title": "SHOW PARTITIONS",
+ "language": "ko",
+ "description": "이 문은 파티션 정보를 표시하는 데 사용됩니다. Internal catalog와 Hive Catalog를 모두 지원합니다."
+}
+---
+
+## 설명 {#descriptions}
+
+이 문은 파티션 정보를 표시하는 데 사용됩니다. Internal catalog와 Hive Catalog를 모두 지원합니다.
+
+`Hive Catalog`의 경우:
+
+다단계 파티션을 포함한 모든 파티션을 반환할 수 있습니다.
+## 구문 {#syntax}
+
+```sql
+SHOW [ TEMPORARY ] PARTITIONS
+ FROM [ <db_name>. ] <table_name>
+ [ <where_clause> ]
+ [ ORDER BY <order_by_key> ]
+ [ LIMIT <limit_rows> ];
+```
+
+## 필수 매개변수 {#required-parameters}
+**1. `<table_name>`**
+
+파티션 정보를 조회할 테이블의 이름을 지정해야 합니다.
+
+
+## 선택적 매개변수 {#optional-parameters}
+**1. `TEMPORARY`**
+
+임시 파티션 정보를 쿼리할지 여부입니다.
+
+**2. `<db_name>`**
+
+파티션 정보를 조회할 데이터베이스의 이름을 지정해야 합니다.
+
+**3. `<where_clause>`**
+
+필터 조건입니다. PartitionId, PartitionName, State, Buckets, ReplicationNum, LastConsistencyCheckTime 등의 열을 기준으로 필터링할 수 있습니다.
+
+다음 사항에 유의하세요.
+1. 현재 WHERE 절은 문자열 타입인 PartitionName과 State에 대해 `=`, `!=`, `like` 연산자만 지원합니다. 다른 열에는 `=`, `!=`, `>`, `<`, `>=`, `<=` 등의 연산자만 지원합니다.
+2. WHERE 절에서 위 연산자를 사용할 때는 열 이름을 왼쪽에 배치해야 합니다.
+3. WHERE 절에는 `AND`를 사용할 수 있습니다.
+
+**4. `<order_by_key>`**
+
+정렬 조건입니다. PartitionId, PartitionName, State, Buckets, ReplicationNum, LastConsistencyCheckTime 등의 열을 기준으로 정렬할 수 있습니다.
+
+**5. `<limit_rows>`**
+
+반환할 최대 행 수입니다.
+
+## 반환 값 {#return-value}
+| 열 | 데이터 타입 | 설명 |
+|--------------------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| PartitionId | bigint | 파티션 ID |
+| PartitionName | varchar | 파티션 이름 |
+| VisibleVersion | int | 이 파티션에 속한 태블릿의 최대 VisibleVersion. |
+| VisibleVersionTime | datetime | 이 파티션의 가장 최근 VisibleVersion 시간. |
+| State | varchar | 이 파티션의 상태 |
+| PartitionKey | datetime | 이 파티션의 파티션 키 |
+| Range | datetime | 이 파티션의 범위 |
+| DistributionKey | varchar | 이 파티션의 분산 키 |
+| Buckets | int | 이 파티션의 버킷 수 |
+| ReplicationNum | int | 이 파티션의 복제본 수 |
+| StorageMedium | varchar | 이 파티션의 스토리지 매체 |
+| CooldownTime | datetime | 이 파티션의 쿨다운 시간. 핫/콜드 분리를 사용하지 않는 경우 이 필드의 값은 [9999-12-31 23:59:59]이며, 항상 핫 데이터임을 의미합니다. |
+| RemoteStoragePolicy | varchar | 이 파티션의 원격 스토리지 정책. |
+| LastConsistencyCheckTime | datetime | 이 파티션의 마지막 파티션 일관성 검사 시간. |
+| DataSize | int | 이 파티션의 데이터 크기. |
+| IsInMemory | boolean | 인메모리 파티션인지 여부. 기본값은 false입니다. |
+| ReplicaAllocation | varchar | 이 파티션의 복제본 배치 전략. |
+| IsMutable | boolean | 파티션의 변경 가능 여부. 기본값은 true입니다. |
+| SyncWithBaseTables | boolean | 파티션이 기본 테이블의 데이터와 동기화되어 있는지 여부. |
+| UnsyncTables | varchar | 해당 파티션이 동기화되지 않은 테이블의 파티션인지 여부. |
+
+
+## 접근 제어 요구 사항 {#access-control-requirements}
+조회할 테이블에 대한 SHOW 권한이 필요합니다.
+
+
+
+## 예제 {#examples}
+
+1. 지정한 데이터베이스의 지정한 테이블에서 임시 파티션을 제외한 모든 파티션 정보를 표시합니다.
+
+```sql
+SHOW PARTITIONS FROM t_agg;
+```
+```text
++-------------+---------------+----------------+---------------------+--------+--------------+-------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+-----------+------------+-------------------------+-----------+--------------------+--------------+
+| PartitionId | PartitionName | VisibleVersion | VisibleVersionTime | State | PartitionKey | Range | DistributionKey | Buckets | ReplicationNum | StorageMedium | CooldownTime | RemoteStoragePolicy | LastConsistencyCheckTime | DataSize | IsInMemory | ReplicaAllocation | IsMutable | SyncWithBaseTables | UnsyncTables |
++-------------+---------------+----------------+---------------------+--------+--------------+-------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+-----------+------------+-------------------------+-----------+--------------------+--------------+
+| 170307 | t_agg | 4 | 2024-11-05 16:13:40 | NORMAL | | | k1 | 1 | 1 | HDD | 9999-12-31 23:59:59 | | NULL | 806.000 B | false | tag.location.default: 1 | true | true | NULL |
++-------------+---------------+----------------+---------------------+--------+--------------+-------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+-----------+------------+-------------------------+-----------+--------------------+--------------+
+```
+2. 지정한 데이터베이스의 지정한 테이블에서 모든 임시 파티션 정보를 표시합니다.
+
+```sql
+SHOW TEMPORARY PARTITIONS FROM t_temp;
+```
+```text
++-------------+---------------+----------------+---------------------+--------+--------------+----------------------------------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+----------+------------+-------------------------+-----------+--------------------+--------------+
+| PartitionId | PartitionName | VisibleVersion | VisibleVersionTime | State | PartitionKey | Range | DistributionKey | Buckets | ReplicationNum | StorageMedium | CooldownTime | RemoteStoragePolicy | LastConsistencyCheckTime | DataSize | IsInMemory | ReplicaAllocation | IsMutable | SyncWithBaseTables | UnsyncTables |
++-------------+---------------+----------------+---------------------+--------+--------------+----------------------------------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+----------+------------+-------------------------+-----------+--------------------+--------------+
+| 828863 | tp2020 | 1 | 2025-01-22 16:19:50 | NORMAL | create_time | [types: [DATETIMEV2]; keys: [2020-01-01 00:00:00]; ..types: [DATETIMEV2]; keys: [2021-01-01 00:00:00]; ) | reference_no | 1 | 1 | SSD | 9999-12-31 23:59:59 | | NULL | 0.000 | false | tag.location.default: 1 | true | true | NULL |
++-------------+---------------+----------------+---------------------+--------+--------------+----------------------------------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+----------+------------+-------------------------+-----------+--------------------+--------------+
+```
+
+3. 지정한 데이터베이스의 지정한 테이블에서 임시 파티션이 아닌 특정 파티션의 정보를 표시하고 결과를 필터링합니다.
+
+```sql
+SHOW PARTITIONS FROM t_agg WHERE PartitionName = "p2024";
+```
+```text
++-------------+---------------+----------------+---------------------+--------+-----------------+----------------------------------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+-----------+------------+-------------------------+-----------+--------------------+--------------+
+| PartitionId | PartitionName | VisibleVersion | VisibleVersionTime | State | PartitionKey | Range | DistributionKey | Buckets | ReplicationNum | StorageMedium | CooldownTime | RemoteStoragePolicy | LastConsistencyCheckTime | DataSize | IsInMemory | ReplicaAllocation | IsMutable | SyncWithBaseTables | UnsyncTables |
++-------------+---------------+----------------+---------------------+--------+-----------------+----------------------------------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+-----------+------------+-------------------------+-----------+--------------------+--------------+
+| 169851 | p2024 | 2 | 2024-11-05 14:14:29 | NORMAL | idp_create_time | [types: [DATETIMEV2]; keys: [2024-01-01 00:00:00]; ..types: [DATETIMEV2]; keys: [2025-01-01 00:00:00]; ) | idp_es_id | 3 | 1 | HDD | 9999-12-31 23:59:59 | | NULL | 27.396 KB | false | tag.location.default: 1 | true | true | NULL |
++-------------+---------------+----------------+---------------------+--------+-----------------+----------------------------------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+-----------+------------+-------------------------+-----------+--------------------+--------------+
+```
+
+4. 지정한 데이터베이스의 지정한 테이블에서 임시 파티션을 제외한 가장 최근 파티션의 정보를 표시합니다.
+
+```sql
+SHOW PARTITIONS FROM t_agg ORDER BY PartitionId DESC LIMIT 1;
+```
+```text
++-------------+---------------+----------------+---------------------+--------+-----------------+----------------------------------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+----------+------------+-------------------------+-----------+--------------------+--------------+
+| PartitionId | PartitionName | VisibleVersion | VisibleVersionTime | State | PartitionKey | Range | DistributionKey | Buckets | ReplicationNum | StorageMedium | CooldownTime | RemoteStoragePolicy | LastConsistencyCheckTime | DataSize | IsInMemory | ReplicaAllocation | IsMutable | SyncWithBaseTables | UnsyncTables |
++-------------+---------------+----------------+---------------------+--------+-----------------+----------------------------------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+----------+------------+-------------------------+-----------+--------------------+--------------+
+| 169866 | p2025 | 1 | 2024-11-05 14:13:56 | NORMAL | idp_create_time | [types: [DATETIMEV2]; keys: [2025-01-01 00:00:00]; ..types: [DATETIMEV2]; keys: [2026-01-01 00:00:00]; ) | idp_es_id | 3 | 1 | HDD | 9999-12-31 23:59:59 | | NULL | 0.000 | false | tag.location.default: 1 | true | true | NULL |
++-------------+---------------+----------------+---------------------+--------+-----------------+----------------------------------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+----------+------------+-------------------------+-----------+--------------------+--------------+
+```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/table/SHOW-TABLE-ID.md b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/table/SHOW-TABLE-ID.md
new file mode 100644
index 00000000000..31e48be52a4
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/table/SHOW-TABLE-ID.md
@@ -0,0 +1,54 @@
+---
+{
+ "title": "SHOW TABLE ID",
+ "language": "ko",
+ "description": "테이블 ID를 기준으로 해당 데이터베이스 이름과 테이블 이름을 조회하는 문입니다."
+}
+---
+
+## 설명 {#description}
+
+테이블 ID를 기준으로 해당 데이터베이스 이름과 테이블 이름을 조회하는 문입니다.
+
+## 구문 {#syntax}
+
+```sql
+SHOW TABLE <table_id>
+```
+
+## 필수 매개변수 {#required-parameters}
+
+**1. `<table_id>`**
+> 데이터베이스 이름과 테이블 이름을 조회할 테이블의 `<table_id>`입니다.
+
+## 반환값 {#return-value}
+
+| 열 이름 (열) | 유형 (데이터 유형) | 비고 (비고) |
+|:--------------------|:-------------|:----------|
+| DbName | String | 데이터베이스 이름 |
+| TableName | String | 테이블 이름 |
+| DbId | String | 데이터베이스 ID |
+
+## 접근 제어 요구 사항 {#access-control-requirements}
+
+이 SQL 명령을 실행하는 사용자는 최소한 다음 권한이 있어야 합니다:
+
+| 권한 (권한) | 객체 (객체) | 비고 (비고) |
+|:--------------|:-----------|:------------------------|
+| ADMIN_PRIV | 테이블 (테이블) | 현재 이 작업은 **ADMIN** 권한이 있는 경우에만 수행할 수 있습니다 |
+
+## 예제 {#examples}
+
+- 테이블 ID를 기준으로 해당 데이터베이스 이름과 테이블 이름 조회
+
+ ```sql
+ SHOW TABLE 2261121
+ ```
+
+ ```text
+ +--------+------------+---------+
+ | DbName | TableName | DbId |
+ +--------+------------+---------+
+ | demo | test_table | 2261034 |
+ +--------+------------+---------+
+ ```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/table/SHOW-TABLE-STATUS.md b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/table/SHOW-TABLE-STATUS.md
new file mode 100644
index 00000000000..7ab05c9ad3f
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/table/SHOW-TABLE-STATUS.md
@@ -0,0 +1,91 @@
+---
+{
+ "title": "SHOW TABLE STATUS",
+ "language": "ko",
+ "description": "이 문은 테이블이나 뷰의 일부 정보를 표시하는 데 사용됩니다."
+}
+---
+
+## 설명 {#description}
+
+이 문은 테이블이나 뷰의 일부 정보를 표시하는 데 사용됩니다.
+
+## 구문 {#syntax}
+
+```sql
+SHOW TABLE STATUS [ FROM [ <catalog_name>.]<db_name> ] [ LIKE <like_condition> ]
+```
+## 선택적 매개변수 {#optional-parameters}
+
+**1. ` FROM [ <catalog_name>.]<db_name>`**
+> 조회할 Catalog 이름과 데이터베이스 이름은 FROM 절에서 지정할 수 있습니다.
+
+**2. `LIKE <like_condition>`**
+> LIKE 절을 사용하면 테이블 이름을 기준으로 유사 일치 쿼리를 수행할 수 있습니다.
+
+## 반환 값 {#return-value}
+
+| 열 | 데이터 타입 | 설명 |
+|:--------------------|:---------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| Name | String | 테이블 이름 |
+| Engine | String | 테이블의 스토리지 엔진 |
+| Version | String | 버전 |
+| Row_format | String | 행 형식입니다. MyISAM 엔진에서는 Dynamic, Fixed 또는 Compressed일 수 있습니다. Dynamic 행은 Varchar나 Blob 타입 필드처럼 길이가 가변적입니다. Fixed 행은 Char나 Integer 타입 필드처럼 길이가 고정되어 있습니다. |
+| Rows | String | 테이블의 행 수입니다. 비트랜잭션 테이블에서는 정확한 값이며, 트랜잭션 엔진에서는 일반적으로 추정값입니다. |
+| Avg_row_length | Integer | 행당 평균 바이트 수 |
+| Data_length | Integer | 전체 테이블의 데이터 크기(바이트 단위) |
+| Max_data_length | Integer | 테이블에 저장할 수 있는 최대 데이터 크기 |
+| Index_length | Integer | 인덱스가 차지하는 디스크 공간 |
+| Data_free | Integer | MyISAM 엔진에서 할당되었지만 현재 사용하지 않는 공간을 나타내며, 삭제된 행의 공간도 포함합니다. |
+| Auto_increment | Integer | 다음 Auto_increment 값 |
+| Create_time | Datetime | 테이블 생성 시간 |
+| Update_time | Datetime | 테이블의 마지막 업데이트 시간 |
+| Check_time | Datetime | check table 또는 myisamchk 도구로 테이블을 마지막으로 검사한 시간 |
+| Collation | String | 테이블의 기본 문자 집합이며, 현재는 utf-8만 지원합니다. |
+| Checksum | String | 활성화된 경우, 전체 테이블 내용에 대해 계산된 체크섬 |
+| Create_options | String | 테이블 생성 시 지정한 기타 모든 옵션 |
+| Comment | String | 테이블 주석 |
+
+## 접근 제어 요구 사항 {#access-control-requirements}
+
+이 SQL 명령을 실행하는 사용자는 최소한 다음 권한을 보유해야 합니다:
+
+| 권한 | 객체 | 설명 |
+|:--------------|:-----------|:------------------------|
+| ADMIN_PRIV | 테이블, 뷰 | 현재는 **ADMIN** 권한이 있어야 이 작업을 수행할 수 있습니다. |
+
+## 사용 시 참고 사항 {#usage-notes}
+
+- 이 문은 주로 MySQL 구문과의 호환성을 위해 사용됩니다. 현재는 Comment 등의 일부 정보만 표시됩니다.
+
+## 예제 {#examples}
+
+- 현재 데이터베이스의 모든 테이블 정보 조회
+
+ ```sql
+ SHOW TABLE STATUS
+ ```
+
+ ```text
+ +------------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-----------+----------+----------------+---------+
+ | Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+ +------------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-----------+----------+----------------+---------+
+ | test_table | Doris | NULL | NULL | 0 | 0 | 0 | NULL | NULL | NULL | NULL | 2025-01-22 11:45:36 | 2025-01-22 11:45:36 | NULL | utf-8 | NULL | NULL | |
+ | test_view | View | NULL | NULL | 0 | 0 | 0 | NULL | NULL | NULL | NULL | 2025-01-22 11:46:32 | NULL | NULL | utf-8 | NULL | NULL | |
+ +------------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-----------+----------+----------------+---------+
+ ```
+
+- 지정된 데이터베이스에서 이름에 example이 포함된 테이블의 정보 조회
+
+ ```sql
+ SHOW TABLE STATUS FROM db LIKE "%test%"
+ ```
+
+ ```text
+ +------------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-----------+----------+----------------+---------+
+ | Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+ +------------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-----------+----------+----------------+---------+
+ | test_table | Doris | NULL | NULL | 0 | 0 | 0 | NULL | NULL | NULL | NULL | 2025-01-22 11:45:36 | 2025-01-22 11:45:36 | NULL | utf-8 | NULL | NULL | |
+ | test_view | View | NULL | NULL | 0 | 0 | 0 | NULL | NULL | NULL | NULL | 2025-01-22 11:46:32 | NULL | NULL | utf-8 | NULL | NULL | |
+ +------------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+-----------+----------+----------------+---------+
+ ```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/table/SHOW-TABLES.md b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/table/SHOW-TABLES.md
new file mode 100644
index 00000000000..fde77f04e8f
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/table/SHOW-TABLES.md
@@ -0,0 +1,99 @@
+---
+{
+ "title": "SHOW TABLES",
+ "language": "ko",
+ "description": "현재 데이터베이스에 속한 모든 테이블과 뷰를 표시하는 문입니다."
+}
+---
+
+## 설명 {#description}
+
+현재 데이터베이스에 속한 모든 테이블과 뷰를 표시하는 문입니다.
+
+## 구문 {#syntax}
+
+```sql
+SHOW [ FULL ] TABLES [ FROM [ <catalog_name>.]<db_name> ][ LIKE <like_condition> ]
+```
+
+## 선택적 매개변수 {#optional-parameters}
+
+**1. `FULL`**
+> 이 매개변수를 문에 추가하면 반환 결과에 Table_type(테이블 유형), Storage_format(저장 형식), Inverted_index_storage_format(역색인 저장 형식)이라는 세 개의 열이 추가됩니다.
+
+**2. `FROM [ <catalog_name>.]<db_name>`**
+> FROM 절에서 쿼리할 Catalog 이름과 데이터베이스 이름을 지정할 수 있습니다.
+
+**2. `LIKE <like_condition>`**
+> LIKE 절에서 테이블 이름을 기준으로 패턴 일치 쿼리를 수행할 수 있습니다.
+
+## 반환 값 {#return-value}
+
+| 열 이름(열) | 유형(데이터 유형) | 설명(설명) |
+|:--------------------|:-------------|:----------------------------|
+| Tables_in_<db_name> | String | `<db_name>`에 해당하는 데이터베이스에 속한 모든 테이블과 뷰입니다. |
+| Table_type | String | 테이블과 뷰의 유형입니다. |
+| Storage_format | String | 테이블과 뷰의 저장 형식입니다. |
+| Inverted_index_storage_format | String | 테이블과 뷰의 역색인 저장 형식입니다. |
+
+## 접근 제어 요구 사항 {#access-control-requirements}
+
+이 SQL 명령을 실행하는 사용자는 최소한 다음 권한을 보유해야 합니다.
+
+| 권한(권한) | 객체(객체) | 설명(설명) |
+|:--------------|:-----------|:------------------|
+| SELECT_PRIV | 테이블(테이블), 뷰(뷰) | 쿼리 권한이 있는 테이블과 뷰만 표시할 수 있습니다. |
+
+## 사용 시 참고 사항 {#usage-notes}
+
+- 문에 FROM 절을 지정하지 않은 경우, 해당 데이터베이스를 선택한 상태에서 실행해야 합니다.
+
+## 예제 {#examples}
+
+- DB에 속한 모든 테이블 조회
+
+ ```sql
+ SHOW TABLES;
+ ```
+
+ ```text
+ +---------------------------------+
+ | Tables_in_demo |
+ +---------------------------------+
+ | ads_client_biz_aggr_di_20220419 |
+ | cmy1 |
+ | cmy2 |
+ | intern_theme |
+ | left_table |
+ +---------------------------------+
+ ```
+
+- 테이블 이름을 기준으로 패턴 일치 쿼리 수행
+
+ ```sql
+ SHOW TABLES LIKE '%cm%'
+ ```
+
+ ```text
+ +----------------+
+ | Tables_in_demo |
+ +----------------+
+ | cmy1 |
+ | cmy2 |
+ +----------------+
+ ```
+
+- FULL을 사용하여 데이터베이스에 속한 테이블과 뷰 조회
+
+ ```sql
+ SHOW FULL TABLES
+ ```
+
+ ```text
+ +----------------+------------+----------------+-------------------------------+
+ | Tables_in_demo | Table_type | Storage_format | Inverted_index_storage_format |
+ +----------------+------------+----------------+-------------------------------+
+ | test_table | BASE TABLE | V2 | V1 |
+ | test_view | VIEW | NONE | NONE |
+ +----------------+------------+----------------+-------------------------------+
+ ```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/table/TRUNCATE-TABLE.md b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/table/TRUNCATE-TABLE.md
new file mode 100644
index 00000000000..7b2aa82378a
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/table/TRUNCATE-TABLE.md
@@ -0,0 +1,79 @@
+---
+{
+ "title": "TRUNCATE-TABLE",
+ "language": "ko",
+ "description": "이 문은 지정된 테이블과 파티션의 데이터를 비우는 데 사용됩니다."
+}
+---
+
+## 설명 {#description}
+
+이 문은 지정된 테이블과 파티션의 데이터를 비우는 데 사용됩니다.
+
+## 구문 {#syntax}
+
+```sql
+TRUNCATE TABLE [<db_name>.]<table_name>[ PARTITION ( <partition_name1> [, <partition_name2> ... ] ) ];
+```
+## 필수 매개변수 {#required-parameters}
+
+**1.`<db_name>`**
+> 데이터베이스의 식별자(이름)를 지정합니다.
+>
+> 식별자는 알파벳 문자로 시작해야 하며(unicode 이름 지원이 활성화된 경우 해당 언어의 문자로 시작할 수 있음), 식별자 문자열 전체를 백틱으로 감싸지 않는 한 공백이나 특수 문자를 포함할 수 없습니다(예: `My Database`).
+>
+> 식별자에는 예약 키워드를 사용할 수 없습니다.
+>
+> 자세한 내용은 식별자 요구 사항 및 예약 키워드를 참조하세요.
+
+**2.`<table_name>`**
+> 테이블의 식별자(이름)를 지정합니다. 이 식별자는 해당 테이블이 속한 데이터베이스 내에서 고유해야 합니다.
+>
+> 식별자는 알파벳 문자로 시작해야 하며(unicode 이름 지원이 활성화된 경우 해당 언어의 문자로 시작할 수 있음), 식별자 문자열 전체를 백틱으로 감싸지 않는 한 공백이나 특수 문자를 포함할 수 없습니다(예: `My Object`).
+>
+> 식별자에는 예약 키워드를 사용할 수 없습니다.
+>
+> 자세한 내용은 식별자 요구 사항 및 예약 키워드를 참조하세요.
+
+## 선택적 매개변수 {#optional-parameters}
+**1.`<partition_name>`**
+> 파티션의 식별자(이름)를 지정합니다.
+>
+> 식별자는 알파벳 문자로 시작해야 하며(unicode 이름 지원이 활성화된 경우 해당 문자 체계의 문자로 시작할 수 있음), 식별자 문자열 전체를 백틱으로 감싸지 않는 한 공백이나 특수 문자를 포함할 수 없습니다(예: `My Object`).
+>
+> 식별자에는 예약 키워드를 사용할 수 없습니다.
+>
+> 자세한 내용은 식별자 요구 사항 및 예약 키워드를 참조하세요.
+
+
+## 접근 제어 요구 사항 {#access-control-requirements}
+
+이 SQL 명령을 실행하는 사용자는 최소한 다음 권한을 보유해야 합니다.
+
+
+| 권한 | 객체 | 참고 사항 |
+|:----------------|:----------|:---------------------------|
+| Drop_priv | 테이블 | TRUNCATE TABLE은 테이블 DROP 작업에 해당합니다 |
+
+## 사용 시 참고 사항 {#usage-notes}
+
+- 이 문은 데이터를 비우지만 테이블이나 파티션은 유지합니다.
+- DELETE와 달리, 이 문은 지정된 테이블이나 파티션의 데이터 전체를 비우는 작업만 지원하며 필터 조건을 추가할 수 없습니다.
+- DELETE와 달리, 이 방식으로 데이터를 비워도 쿼리 성능에 영향을 주지 않습니다.
+- 이 작업으로 삭제된 데이터는 복구할 수 없습니다.
+- 이 명령을 사용할 때는 테이블 상태가 NORMAL이어야 합니다. 즉, SCHEMA CHANGE 등의 작업이 진행 중이어서는 안 됩니다.
+- 이 명령으로 인해 진행 중인 데이터 적재가 실패할 수 있습니다.
+
+## 예제 {#examples}
+
+1. example_db의 테이블 tbl 데이터 비우기
+
+ ```sql
+ TRUNCATE TABLE example_db.tbl;
+ ```
+
+2. 테이블 tbl의 p1 및 p2 파티션 데이터 비우기
+
+ ```sql
+ TRUNCATE TABLE tbl PARTITION(p1, p2);
+ ```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/view/ALTER-VIEW.md b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/view/ALTER-VIEW.md
new file mode 100644
index 00000000000..483da9c30ea
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/view/ALTER-VIEW.md
@@ -0,0 +1,68 @@
+---
+{
+ "title": "ALTER VIEW",
+ "language": "ko",
+ "description": "이 문은 논리 뷰의 정의를 수정하는 데 사용됩니다."
+}
+---
+
+## 설명 {#description}
+
+이 문은 논리 뷰의 정의를 수정하는 데 사용됩니다.
+
+## 구문 {#syntax}
+
+```sql
+ALTER VIEW [<db_name>.]<view_name>
+ [(<column_definition>)]
+AS <query_stmt>
+```
+
+여기서:
+```sql
+column_definition:
+ <column_name> [COMMENT '<comment>'] [,...]
+```
+
+## 필수 매개변수 {#required-parameters}
+
+**1. `<view_name>`**
+> 수정할 뷰의 식별자(즉, 이름)입니다.
+
+**2. `<query_stmt>`**
+> 뷰를 정의하는 SELECT 쿼리 문입니다.
+
+## 선택적 매개변수 {#optional-parameters}
+
+**1. `<db_name>`**
+> 뷰가 속한 데이터베이스의 이름입니다. 지정하지 않으면 기본적으로 현재 데이터베이스를 사용합니다.
+
+**2. `<column_definition>`**
+> 뷰의 컬럼 정의입니다.
+> 각 항목은 다음과 같습니다.
+> **1. `<column_name>`**
+> 컬럼 이름입니다.
+> **2. `<comment>`**
+> 컬럼 주석입니다.
+
+## 액세스 제어 요구 사항 {#access-control-requirements}
+
+| 권한 | 객체 | 참고 사항 |
+|---------------|----------|-----------------------------------------------------------------------|
+| ALTER_PRIV | 뷰 | 수정할 뷰에 대한 ALTER_PRIV 권한이 필요합니다. |
+| SELECT_PRIV | 테이블, 뷰 | 쿼리 대상 테이블, 뷰 또는 구체화된 뷰에 대한 SELECT_PRIV 권한이 필요합니다. |
+
+## 예제 {#example}
+
+1. 뷰 `example_view`를 `example_db`에서 수정합니다.
+
+ ```sql
+ ALTER VIEW example_db.example_view
+ (
+ c1 COMMENT "column 1",
+ c2 COMMENT "column 2",
+ c3 COMMENT "column 3"
+ )
+ AS SELECT k1, k2, SUM(v1) FROM example_table
+ GROUP BY k1, k2
+ ```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/view/CREATE-VIEW.md b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/view/CREATE-VIEW.md
new file mode 100644
index 00000000000..18b3c97c492
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/view/CREATE-VIEW.md
@@ -0,0 +1,88 @@
+---
+{
+ "title": "CREATE VIEW",
+ "language": "ko",
+ "description": "지정된 쿼리 문을 사용하여 논리적 뷰를 생성하는 구문입니다."
+}
+---
+
+## 설명 {#description}
+
+지정된 쿼리 문을 사용하여 논리적 뷰를 생성하는 구문입니다.
+
+## 구문 {#syntax}
+
+```sql
+CREATE VIEW [IF NOT EXISTS] [<db_name>.]<view_name>
+ [(<column_definition>)]
+[AS] <query_stmt>
+```
+
+각 항목의 정의는 다음과 같습니다.
+```sql
+column_definition:
+ <column_name> [COMMENT '<comment>'] [,...]
+```
+
+## 필수 매개변수 {#required-parameters}
+
+**1. `<view_name>`**
+> 뷰의 식별자(이름)입니다. 뷰가 생성되는 데이터베이스 내에서 고유해야 합니다.
+> 식별자는 문자로 시작해야 하며(유니코드 이름 지원이 활성화된 경우 모든 언어의 문자를 사용할 수 있음), 식별자 문자열 전체를 백틱으로 감싸지 않으면 공백이나 특수 문자를 포함할 수 없습니다(예: `My View`).
+> 식별자에는 예약 키워드를 사용할 수 없습니다.
+> 자세한 내용은 식별자 요구 사항과 예약 키워드를 참조하세요.
+
+**2. `<query_stmt>`**
+> 뷰를 정의하는 SELECT 쿼리 문입니다.
+
+## 선택적 매개변수 {#optional-parameters}
+
+**1. `<db_name>`**
+> 뷰가 속한 데이터베이스의 이름입니다. 지정하지 않으면 기본적으로 현재 데이터베이스를 사용합니다.
+
+**2. `<column_definition>`**
+> 뷰의 컬럼 정의입니다.
+> 각 항목의 의미는 다음과 같습니다.
+> **1. `<column_name>`**
+> 컬럼 이름입니다.
+> **2. `<comment>`**
+> 컬럼에 대한 설명입니다.
+
+## 접근 제어 요구 사항 {#access-control-requirements}
+
+| 권한 | 객체 | 설명 |
+|-------------|----------|----------------------------------------------------------------------|
+| CREATE_PRIV | 데이터베이스 | 데이터베이스에 대한 CREATE_PRIV 권한이 필요합니다. |
+| SELECT_PRIV | 테이블, 뷰 | 쿼리 대상 테이블, 뷰 또는 구체화된 뷰에 대한 SELECT_PRIV 권한이 필요합니다. |
+
+## 참고 사항 {#notes}
+
+- 뷰는 논리적 객체이며 물리적 저장 공간이 없습니다. 뷰에 대한 모든 쿼리는 해당 서브쿼리에 대한 쿼리와 동일합니다.
+- 뷰를 생성하거나 삭제해도 기반 테이블의 데이터에는 영향을 주지 않습니다.
+
+## 예제 {#examples}
+
+1. `example_view` 뷰를 `example_db`에 생성합니다.
+
+ ```sql
+ CREATE VIEW example_db.example_view (k1, k2, k3, v1)
+ AS
+ SELECT c1 as k1, k2, k3, SUM(v1) FROM example_table
+ WHERE k1 = 20160112 GROUP BY k1,k2,k3;
+ ```
+
+2. 컬럼 정의를 포함하여 뷰를 생성합니다.
+
+ ```sql
+ CREATE VIEW example_db.example_view
+ (
+ k1 COMMENT "first key",
+ k2 COMMENT "second key",
+ k3 COMMENT "third key",
+ v1 COMMENT "first value"
+ )
+ COMMENT "my first view"
+ AS
+ SELECT c1 as k1, k2, k3, SUM(v1) FROM example_table
+ WHERE k1 = 20160112 GROUP BY k1,k2,k3;
+ ```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/view/DROP-VIEW.md b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/view/DROP-VIEW.md
new file mode 100644
index 00000000000..c88af9891db
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/view/DROP-VIEW.md
@@ -0,0 +1,45 @@
+---
+{
+ "title": "DROP VIEW",
+ "language": "ko",
+ "description": "현재 데이터베이스 또는 지정한 데이터베이스에서 뷰를 삭제합니다."
+}
+---
+
+## 설명 {#description}
+
+현재 데이터베이스 또는 지정한 데이터베이스에서 뷰를 삭제합니다.
+
+## 구문 {#syntax}
+
+```sql
+DROP VIEW [ IF EXISTS ] <name>
+```
+## 필수 매개변수 {#required-parameters}
+
+삭제할 뷰의 이름입니다.
+
+## 선택적 매개변수 {#optional-parameters}
+
+**[ IF EXISTS ]**
+
+이 매개변수를 지정하면 뷰가 존재하지 않아도 오류가 발생하지 않으며, 삭제 작업을 바로 건너뜁니다.
+
+## 접근 제어 요구 사항 {#access-control-requirements}
+
+이 SQL 명령을 실행하는 사용자는 최소한 다음 권한을 보유해야 합니다.
+
+| 권한 | 객체 | 비고 |
+| :-------- | :----- | :---- |
+| DROP_PRIV | 테이블 | |
+
+## 사용 시 참고 사항 {#usage-notes}
+
+삭제한 뷰는 복원할 수 없으며 다시 생성해야 합니다.
+
+## 예제 {#examples}
+
+```sql
+CREATE VIEW vtest AS SELECT 1, 'test';
+DROP VIEW IF EXISTS vtest;
+```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/view/SHOW-CREATE-VIEW.md b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/view/SHOW-CREATE-VIEW.md
new file mode 100644
index 00000000000..af77354cb4b
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/view/SHOW-CREATE-VIEW.md
@@ -0,0 +1,55 @@
+---
+{
+ "title": "SHOW CREATE VIEW",
+ "language": "ko",
+ "description": "지정된 뷰를 생성할 때 사용한 CREATE VIEW 문을 표시합니다."
+}
+---
+
+## 설명 {#description}
+
+지정된 뷰를 생성할 때 사용한 CREATE VIEW 문을 표시합니다.
+
+## 구문 {#syntax}
+
+```sql
+SHOW CREATE VIEW <name>
+```
+
+## 필수 매개변수 {#required-parameters}
+
+`**<name>**` 조회할 뷰의 이름입니다.
+
+## 결과 설명 {#result-description}
+
+- View: 쿼리한 뷰의 이름입니다.
+- Create View: 데이터베이스에 저장된 SQL 문입니다.
+- character_set_client: 뷰 생성 시 세션의 character_set_client 시스템 변수 값입니다.
+- collation_connection: 뷰 생성 시 세션의 collation_connection 시스템 변수 값입니다.
+
+## 접근 제어 요구 사항 {#access-control-requirements}
+
+이 SQL 명령을 실행하는 사용자는 최소한 다음 권한을 보유해야 합니다:
+
+| 권한 | 객체 | 비고 |
+| ---------------- | ------ | ----- |
+| SHOW_VIEW_PRIV | 테이블 | |
+
+뷰 정보는 INFORMATION_SCHEMA.VIEWS 테이블을 쿼리하여 확인할 수도 있습니다.
+
+## 예제 {#examples}
+
+```sql
+CREATE VIEW vtest AS SELECT 1, 'test';
+SHOW CREATE VIEW vtest;
+```
+
+쿼리 결과:
+
+```sql
++-------+------------------------------------------+----------------------+----------------------+
+| View | Create View | character_set_client | collation_connection |
++-------+------------------------------------------+----------------------+----------------------+
+| vtest | CREATE VIEW `vtest` AS SELECT 1, 'test'; | utf8mb4 | utf8mb4_0900_bin |
++-------+------------------------------------------+----------------------+----------------------+
+```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/view/SHOW-VIEW.md b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/view/SHOW-VIEW.md
new file mode 100644
index 00000000000..e4bbdb05599
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/table-and-view/view/SHOW-VIEW.md
@@ -0,0 +1,29 @@
+---
+{
+ "title": "SHOW VIEW",
+ "language": "ko",
+ "description": "이 문은 지정된 테이블을 기반으로 생성된 모든 뷰를 표시하는 데 사용됩니다"
+}
+---
+
+## 설명 {#description}
+
+이 문은 지정된 테이블을 기반으로 생성된 모든 뷰를 표시하는 데 사용됩니다
+
+## 구문 {#syntax}
+
+```sql
+ SHOW VIEW { FROM | IN } table [ FROM db ]
+```
+
+## 예제 {#example}
+
+1. testTbl 테이블을 기반으로 생성된 모든 뷰 표시
+
+ ```sql
+ SHOW VIEW FROM testTbl;
+ ```
+
+## 키워드 {#keywords}
+
+ SHOW, VIEW
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/transaction/BEGIN.md b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/transaction/BEGIN.md
new file mode 100644
index 00000000000..8680306230c
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/transaction/BEGIN.md
@@ -0,0 +1,43 @@
+---
+{
+ "title": "BEGIN",
+ "language": "ko",
+ "description": "사용자는 Label을 지정할 수 있습니다. 지정하지 않으면 시스템이 Label을 자동으로 생성합니다."
+}
+---
+
+## 설명 {#description}
+
+사용자는 Label을 지정할 수 있습니다. 지정하지 않으면 시스템이 Label을 자동으로 생성합니다.
+
+## 구문 {#syntax}
+
+```sql
+BEGIN [ WITH LABEL <label> ]
+```
+
+## 선택적 매개변수 {#optional-parameter}
+
+`[ WITH LABEL <label> ]`
+
+> 트랜잭션에 연결된 Label을 명시적으로 지정합니다. 지정하지 않으면 시스템이 [label](../../../data-operate/transaction)을 자동으로 생성합니다.
+
+## 참고 사항 {#notes}
+
+- 명시적 트랜잭션을 시작한 후 커밋하거나 롤백하지 않은 상태에서 BEGIN 명령을 다시 실행해도 효과가 없습니다.
+
+## 예제 {#examples}
+
+시스템이 생성한 Label로 명시적 트랜잭션 시작
+
+```sql
+mysql> BEGIN;
+{'label':'txn_insert_624a0e16ef4c43d4-9814c7fa3e83a705', 'status':'PREPARE', 'txnId':''}
+```
+
+지정한 Label로 명시적 트랜잭션 시작
+
+```sql
+mysql> BEGIN WITH LABEL load_1;
+{'label':'load_1', 'status':'PREPARE', 'txnId':''}
+```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/transaction/COMMIT.md b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/transaction/COMMIT.md
new file mode 100644
index 00000000000..0d22644b28e
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/transaction/COMMIT.md
@@ -0,0 +1,44 @@
+---
+{
+ "title": "COMMIT",
+ "language": "ko",
+ "description": "명시적 트랜잭션을 커밋하며, BEGIN과 쌍으로 사용합니다."
+}
+---
+
+## 설명 {#description}
+
+명시적 트랜잭션을 커밋하며, [BEGIN](./BEGIN)과 쌍으로 사용합니다.
+
+## 구문 {#syntax}
+
+```sql
+COMMIT
+```
+
+## 참고 사항 {#notes}
+
+- 명시적 트랜잭션이 활성화되어 있지 않으면 이 명령을 실행해도 아무런 효과가 없습니다.
+
+## 예제 {#example}
+
+다음 예제에서는 `test`라는 테이블을 생성하고, 트랜잭션을 시작한 다음 두 행의 데이터를 삽입하고 트랜잭션을 커밋한 후 쿼리를 실행합니다.
+
+```sql
+CREATE TABLE `test` (
+ `ID` int NOT NULL,
+ `NAME` varchar(100) NULL,
+ `SCORE` int NULL
+) ENGINE=OLAP
+DUPLICATE KEY(`ID`)
+DISTRIBUTED BY HASH(`ID`) BUCKETS 1
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 3"
+);
+
+BEGIN;
+INSERT INTO test VALUES(1, 'Alice', 100);
+INSERT INTO test VALUES(2, 'Bob', 100);
+COMMIT;
+SELECT * FROM test;
+```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/transaction/ROLLBACK.md b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/transaction/ROLLBACK.md
new file mode 100644
index 00000000000..495a136a267
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/transaction/ROLLBACK.md
@@ -0,0 +1,44 @@
+---
+{
+ "title": "ROLLBACK",
+ "language": "ko",
+ "description": "명시적 트랜잭션을 롤백합니다. BEGIN과 함께 사용합니다."
+}
+---
+
+## 설명 {#description}
+
+명시적 트랜잭션을 롤백합니다. [BEGIN](./BEGIN)과 함께 사용합니다.
+
+## 구문 {#syntax}
+
+```sql
+ROLLBACK
+```
+
+## 사용 시 주의 사항 {#usage-notes}
+
+- 명시적 트랜잭션을 시작하지 않은 경우, 이 명령을 실행해도 아무런 효과가 없습니다.
+
+## 예제 {#examples}
+
+다음 예제에서는 `test`라는 테이블을 생성하고 트랜잭션을 시작한 다음, 두 행의 데이터를 삽입하고 트랜잭션을 롤백한 후 쿼리를 실행합니다.
+
+```sql
+CREATE TABLE `test` (
+ `ID` int NOT NULL,
+ `NAME` varchar(100) NULL,
+ `SCORE` int NULL
+) ENGINE=OLAP
+DUPLICATE KEY(`ID`)
+DISTRIBUTED BY HASH(`ID`) BUCKETS 1
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 3"
+);
+
+BEGIN;
+INSERT INTO test VALUES(1, 'Bob', 100);
+INSERT INTO test VALUES(2, 'Bob', 100);
+ROLLBACK;
+SELECT * FROM test;
+```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/transaction/SHOW-TRANSACTION.md b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/transaction/SHOW-TRANSACTION.md
new file mode 100644
index 00000000000..0dc66dc584f
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/transaction/SHOW-TRANSACTION.md
@@ -0,0 +1,83 @@
+---
+{
+ "title": "SHOW TRANSACTION",
+ "language": "ko",
+ "description": "지정된 트랜잭션 ID 또는 레이블에 해당하는 트랜잭션의 세부 정보를 조회하는 구문입니다."
+}
+---
+
+## 설명 {#description}
+
+지정된 트랜잭션 ID 또는 레이블에 해당하는 트랜잭션의 세부 정보를 조회하는 구문입니다.
+
+## 구문 {#syntax}
+
+```sql
+SHOW TRANSACTION
+[FROM <db_name>]
+WHERE
+[id = <transaction_id> | label = <label_name>];
+```
+
+## 필수 매개변수 {#required-parameters}
+
+**1. `<transaction_id>`**
+
+세부 정보를 조회할 트랜잭션의 ID입니다.
+
+**2. `<label_name>`**
+
+트랜잭션 세부 정보를 조회할 레이블입니다.
+
+## 선택적 매개변수 {#optional-parameters}
+
+**1. `<db_name>`**
+
+트랜잭션 세부 정보를 조회할 데이터베이스입니다.
+
+## 반환 값 {#return-value}
+
+| 열 이름 | 설명 |
+|---|---|
+| TransactionId | 트랜잭션 ID |
+| Label | 데이터 적재 작업과 연결된 레이블 |
+| Coordinator | 트랜잭션 조정을 담당하는 노드 |
+| TransactionStatus | 트랜잭션 상태 |
+| PREPARE | 준비 단계 |
+| COMMITTED | 트랜잭션이 성공했지만 아직 데이터를 조회할 수 없음 |
+| VISIBLE | 트랜잭션이 성공했으며 데이터를 조회할 수 있음 |
+| ABORTED | 트랜잭션 실패 |
+| LoadJobSourceType | 데이터 적재 작업의 유형 |
+| PrepareTime | 트랜잭션 시작 시각 |
+| CommitTime | 트랜잭션이 성공적으로 커밋된 시각 |
+| FinishTime | 데이터를 조회할 수 있게 된 시각 |
+| Reason | 오류 메시지 |
+| ErrorReplicasCount | 오류가 있는 복제본 수 |
+| ListenerId | 관련 데이터 적재 작업의 ID |
+| TimeoutMs | 트랜잭션 제한 시간(밀리초) |
+
+## 접근 제어 요구 사항 {#access-control-requirements}
+
+| 권한 | 객체 | 비고 |
+|:----------| :----------- | :------------------------ |
+| LOAD_PRIV | 데이터베이스 | |
+
+## 예제 {#examples}
+
+1. id가 4005인 트랜잭션을 조회합니다:
+
+ ```sql
+ SHOW TRANSACTION WHERE ID=4005;
+ ```
+
+2. 지정된 db에서 id가 4005인 트랜잭션을 조회합니다:
+
+ ```sql
+ SHOW TRANSACTION FROM db WHERE ID=4005;
+ ```
+
+3. 레이블이 label_name인 트랜잭션을 조회합니다:
+
+ ```sql
+ SHOW TRANSACTION WHERE LABEL = 'label_name';
+ ```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/types/SHOW-DATA-TYPES.md b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/types/SHOW-DATA-TYPES.md
new file mode 100644
index 00000000000..8c8142a95b5
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/types/SHOW-DATA-TYPES.md
@@ -0,0 +1,71 @@
+---
+{
+ "title": "SHOW DATA TYPES",
+ "language": "ko",
+ "description": "이 문은 지원되는 모든 데이터 타입을 확인하는 데 사용됩니다."
+}
+---
+
+## 설명 {#description}
+
+ This statement is used to view all supported data types.
+
+## 구문 {#syntax}
+
+```sql
+SHOW DATA TYPES;
+```
+
+## 반환 값 {#return-value}
+
+| 열 이름 | 설명 |
+|-------------|------------------|
+| TypeName | 타입 이름 |
+| Size | 바이트 단위 크기 |
+
+## 접근 제어 요구 사항 {#access-control-requirements}
+
+이 SQL 명령을 실행하는 사용자에게는 별도의 권한이 필요하지 않습니다.
+
+## 예제 {#example}
+
+- 지원되는 모든 데이터 타입 표시
+
+ ```sql
+ SHOW DATA TYPES;
+ ```
+ ```text
+ +----------------+------+
+ | TypeName | Size |
+ +----------------+------+
+ | AGG_STATE | 16 |
+ | ARRAY | 32 |
+ | BIGINT | 8 |
+ | BITMAP | 16 |
+ | BOOLEAN | 1 |
+ | CHAR | 16 |
+ | DATE | 16 |
+ | DATETIME | 16 |
+ | DATETIMEV2 | 8 |
+ | DATEV2 | 4 |
+ | DECIMAL128 | 16 |
+ | DECIMAL32 | 4 |
+ | DECIMAL64 | 8 |
+ | DECIMALV2 | 16 |
+ | DOUBLE | 8 |
+ | FLOAT | 4 |
+ | HLL | 16 |
+ | INT | 4 |
+ | IPV4 | 4 |
+ | IPV6 | 16 |
+ | JSON | 16 |
+ | LARGEINT | 16 |
+ | MAP | 24 |
+ | QUANTILE_STATE | 16 |
+ | SMALLINT | 2 |
+ | STRING | 16 |
+ | TIMESTAMP_NS | 8 |
+ | TINYINT | 1 |
+ | VARCHAR | 16 |
+ +----------------+------+
+ ```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/types/SHOW-TYPECAST.md b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/types/SHOW-TYPECAST.md
new file mode 100644
index 00000000000..5f631ec6aa1
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/types/SHOW-TYPECAST.md
@@ -0,0 +1,81 @@
+---
+{
+ "title": "SHOW TYPECAST",
+ "language": "ko",
+ "description": "데이터베이스 내의 모든 타입 변환을 조회합니다. 사용자가 데이터베이스를 지정하면 해당 데이터베이스를 조회하고, 그렇지 않으면 현재 세션이 연결된 데이터베이스를 직접 쿼리합니다."
+}
+---
+
+## 설명 {#description}
+
+데이터베이스 내의 모든 타입 변환을 조회합니다. 사용자가 데이터베이스를 지정하면 해당 데이터베이스를 조회하고, 그렇지 않으면
+현재 세션이 연결된 데이터베이스를 직접 쿼리합니다.
+
+## 구문 {#syntax}
+
+```sql
+SHOW TYPE_CAST [ { IN | FROM } <db>]
+```
+
+## 필수 매개변수 {#required-parameters}
+
+**1. `<db>`**
+
+쿼리할 데이터베이스의 이름입니다.
+
+## 반환 값 {#return-value}
+
+| 열 이름 | 설명 |
+|-------------|-----------------|
+| 원본 타입 | 원래 타입 |
+| 변환 타입 | 변환 후 타입 |
+
+## 접근 제어 요구 사항 {#access-control-requirements}
+
+이 SQL 명령을 실행하는 사용자는 최소한 다음 권한을 보유해야 합니다.
+
+| 권한 | 객체 | 참고 사항 |
+|-------------|---------------|--------------------------------------------------------------------------------------------------|
+| `Select_priv` | 데이터베이스(DB) | 데이터베이스 내의 모든 타입 변환을 조회하려면 사용자 또는 역할에 해당 DB의 `Select_priv` 권한이 있어야 합니다. |
+
+## 사용 시 참고 사항 {#usage-notes}
+
+사용자가 데이터베이스를 지정하면 시스템은 지정된 데이터베이스를 쿼리합니다. 그렇지 않으면 기본적으로
+현재 세션이 연결된 데이터베이스를 쿼리합니다.
+
+## 예제 {#example}
+
+- TESTDB 데이터베이스의 모든 타입 변환 조회
+
+ ```sql
+ SHOW TYPE_CAST IN TESTDB;
+ ```
+ ```text
+ +----------------+----------------+
+ | Origin Type | Cast Type |
+ +----------------+----------------+
+ | DATETIMEV2 | BOOLEAN |
+ | DATETIMEV2 | TINYINT |
+ | DATETIMEV2 | SMALLINT |
+ | DATETIMEV2 | INT |
+ | DATETIMEV2 | BIGINT |
+ | DATETIMEV2 | LARGEINT |
+ | DATETIMEV2 | FLOAT |
+ | DATETIMEV2 | DOUBLE |
+ | DATETIMEV2 | DATE |
+ | DATETIMEV2 | DATETIME |
+ | DATETIMEV2 | DATEV2 |
+ | DATETIMEV2 | DATETIMEV2 |
+ | DATETIMEV2 | DECIMALV2 |
+ | DATETIMEV2 | DECIMAL32 |
+ | DATETIMEV2 | DECIMAL64 |
+ | DATETIMEV2 | DECIMAL128 |
+ | DATETIMEV2 | DECIMAL256 |
+ | DATETIMEV2 | VARCHAR |
+ | DATETIMEV2 | STRING |
+ | DECIMAL256 | DECIMAL128 |
+ | DECIMAL256 | DECIMAL256 |
+ | DECIMAL256 | VARCHAR |
+ | DECIMAL256 | STRING |
+ +----------------+----------------+
+ ```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/auto-increment.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/auto-increment.md
new file mode 100644
index 00000000000..9af78979c55
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/auto-increment.md
@@ -0,0 +1,525 @@
+---
+{
+ "title": "자동 증가 열",
+ "language": "ko",
+ "description": "Doris의 자동 증가 열(AUTO_INCREMENT)은 각 행에 고유한 BIGINT 값을 자동으로 생성하여 기본 키 생성, 사전 인코딩, 효율적인 페이지네이션 등의 시나리오에서 데이터 적재를 간소화합니다."
+}
+---
+
+<!-- Knowledge type: Feature concept + procedure + use cases -->
+
+Doris의 자동 증가 열(Auto Increment Column)은 고유한 숫자 값을 자동으로 생성하는 기능입니다. 일반적으로 기본 키처럼 각 행을 고유하게 식별하는 값을 만드는 데 사용합니다. 새 레코드를 삽입할 때마다 자동 증가 열에 증가하는 값이 자동으로 할당되므로 번호를 일일이 지정할 필요가 없습니다. Doris의 자동 증가 열을 사용하면 데이터의 고유성과 일관성을 보장하고, 데이터 삽입 과정을 간소화하며, 수동 작업으로 인한 오류를 줄이고 데이터 관리 효율을 높일 수 있습니다. 따라서 사용자 ID처럼 고유 식별자가 필요한 시나리오에 적합합니다.
+
+## 핵심 기능 {#core-features}
+
+### 쓰기 동작 {#write-behavior}
+
+자동 증가 열이 있는 테이블에서 Doris는 데이터 쓰기를 다음과 같이 처리합니다.
+
+| 쓰기 시나리오 | 처리 방식 |
+| ----------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
+| 쓰는 데이터에 자동 증가 열이 **포함되지 않음** | Doris가 고유한 값을 자동으로 생성하여 해당 열에 채웁니다 |
+| 쓰는 데이터에 자동 증가 열이 **포함되어 있고** 값이 NULL임 | Doris가 NULL 값을 시스템에서 생성한 고유한 값으로 대체합니다 |
+| 쓰는 데이터에 자동 증가 열이 **포함되어 있고** 값이 NULL이 아님 | 사용자가 제공한 값을 그대로 유지합니다 |
+
+:::caution 중요
+사용자가 제공한 NULL이 아닌 값으로 인해 자동 증가 열의 고유성이 깨질 수 있습니다.
+:::
+
+### 고유성 {#uniqueness}
+
+Doris는 자동 증가 열에서 생성한 값이 **테이블 수준에서 고유함**을 보장합니다. 단, 다음 사항에 유의해야 합니다.
+
+- **고유성 보장**: 시스템에서 생성한 값에만 적용됩니다.
+- **사용자가 제공한 값**: Doris는 사용자가 자동 증가 열에 지정한 값의 고유성을 검증하거나 강제하지 않으므로 중복 항목이 생길 수 있습니다.
+
+### 조밀도 {#density}
+
+Doris가 생성하는 자동 증가 값은 일반적으로 **조밀**하지만, 다음 사항을 고려해야 합니다.
+
+- **값 사이에 공백이 생길 수 있음**: 성능 최적화로 인해 값 사이에 공백이 생길 수 있습니다. 각 백엔드 노드(BE)는 효율성을 위해 고유한 값의 블록을 미리 할당하며, 노드 간에 할당된 블록은 서로 겹치지 않습니다.
+- **시간 순서와 일치하지 않는 값**: Doris는 나중에 쓰는 작업에서 생성한 값이 이전에 쓰는 작업에서 생성한 값보다 크다고 보장하지 않습니다.
+
+:::info 참고
+자동 증가 값으로 쓰기 작업의 시간 순서를 추론할 수 없습니다.
+:::
+
+## 자동 증가 열 생성 {#creating-an-auto-increment-column}
+
+<!-- Knowledge type: Syntax + constraints -->
+
+### 구문 {#syntax}
+
+자동 증가 열을 사용하려면 해당 열에 `AUTO_INCREMENT` 속성을 지정하여 [CREATE-TABLE](../sql-manual/sql-statements/table-and-view/table/CREATE-TABLE)을 실행합니다.
+
+- 시작 값을 지정하지 않으면 기본 시작 값은 `1`입니다.
+- 테이블을 생성할 때 `AUTO_INCREMENT(start_value)`로 자동 증가 열의 시작 값을 직접 지정할 수 있습니다.
+
+### 제약 조건 및 제한 사항 {#constraints-and-limitations}
+
+1. Duplicate 모델 테이블과 Unique 모델 테이블에만 자동 증가 열을 사용할 수 있습니다.
+2. 테이블에는 자동 증가 열을 최대 하나만 사용할 수 있습니다.
+3. 자동 증가 열은 `BIGINT` 타입이어야 하며 `NOT NULL`이어야 합니다.
+4. 자동 증가 열의 시작 값을 직접 지정할 경우 0 이상이어야 합니다.
+
+### 테이블 생성 예제 {#table-creation-examples}
+
+**예제 1: 키 열이 자동 증가 열인 Duplicate 모델 테이블**
+
+```sql
+CREATE TABLE `demo`.`tbl` (
+ `id` BIGINT NOT NULL AUTO_INCREMENT,
+ `value` BIGINT NOT NULL
+) ENGINE=OLAP
+DUPLICATE KEY(`id`)
+DISTRIBUTED BY HASH(`id`) BUCKETS 10
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 3"
+);
+```
+
+**예제 2: 키 열이 시작 값 100의 자동 증가 열인 Duplicate 모델 테이블**
+
+```sql
+CREATE TABLE `demo`.`tbl` (
+ `id` BIGINT NOT NULL AUTO_INCREMENT(100),
+ `value` BIGINT NOT NULL
+) ENGINE=OLAP
+DUPLICATE KEY(`id`)
+DISTRIBUTED BY HASH(`id`) BUCKETS 10
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 3"
+);
+```
+
+**예제 3: 값 열이 자동 증가 열인 Duplicate 모델 테이블**
+
+```sql
+CREATE TABLE `demo`.`tbl` (
+ `uid` BIGINT NOT NULL,
+ `name` BIGINT NOT NULL,
+ `id` BIGINT NOT NULL AUTO_INCREMENT,
+ `value` BIGINT NOT NULL
+) ENGINE=OLAP
+DUPLICATE KEY(`uid`, `name`)
+DISTRIBUTED BY HASH(`uid`) BUCKETS 10
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 3"
+);
+```
+
+**예제 4: 키 열이 자동 증가 열인 Unique 모델 테이블**
+
+```sql
+CREATE TABLE `demo`.`tbl` (
+ `id` BIGINT NOT NULL AUTO_INCREMENT,
+ `name` varchar(65533) NOT NULL,
+ `value` int(11) NOT NULL
+) ENGINE=OLAP
+UNIQUE KEY(`id`)
+DISTRIBUTED BY HASH(`id`) BUCKETS 10
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 3"
+);
+```
+
+**예제 5: 값 열이 자동 증가 열인 Unique 모델 테이블**
+
+```sql
+CREATE TABLE `demo`.`tbl` (
+ `text` varchar(65533) NOT NULL,
+ `id` BIGINT NOT NULL AUTO_INCREMENT
+) ENGINE=OLAP
+UNIQUE KEY(`text`)
+DISTRIBUTED BY HASH(`text`) BUCKETS 10
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 3"
+);
+```
+
+## 데이터 적재 {#data-ingestion}
+
+<!-- Use cases: regular ingestion / partial column update -->
+
+### 일반 데이터 적재 {#regular-ingestion}
+
+다음 테이블을 예로 살펴보겠습니다.
+
+```sql
+CREATE TABLE `demo`.`tbl` (
+ `id` BIGINT NOT NULL AUTO_INCREMENT,
+ `name` varchar(65533) NOT NULL,
+ `value` int(11) NOT NULL
+) ENGINE=OLAP
+UNIQUE KEY(`id`)
+DISTRIBUTED BY HASH(`id`) BUCKETS 10
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 3"
+);
+```
+
+#### 시나리오 1: 자동 증가 열을 지정하지 않는 INSERT INTO {#scenario-1-insert-into-without-specifying-the-auto-increment-column}
+
+`insert into` 문으로 데이터를 적재할 때 자동 증가 열인 `id`를 지정하지 않으면 Doris가 생성한 값을 `id` 열에 자동으로 채웁니다.
+
+```sql
+insert into tbl(name, value) values("Bob", 10), ("Alice", 20), ("Jack", 30);
+
+select * from tbl order by id;
++------+-------+-------+
+| id | name | value |
++------+-------+-------+
+| 1 | Bob | 10 |
+| 2 | Alice | 20 |
+| 3 | Jack | 30 |
++------+-------+-------+
+```
+
+#### 시나리오 2: 자동 증가 열을 지정하지 않는 Stream Load {#scenario-2-stream-load-without-specifying-the-auto-increment-column}
+
+마찬가지로 Stream Load를 사용해 `test.csv` 파일을 가져올 때 자동 증가 열인 `id`를 지정하지 않으면 Doris가 생성한 값을 `id` 열에 자동으로 채웁니다.
+
+`test.csv`의 내용:
+
+```text
+Tom,40
+John,50
+```
+
+데이터 적재 명령을 실행합니다.
+
+```shell
+curl --location-trusted -u user:passwd \
+ -H "columns:name,value" \
+ -H "column_separator:," \
+ -T ./test.csv \
+ http://{host}:{port}/api/{db}/tbl/_stream_load
+```
+
+결과를 쿼리합니다.
+
+```sql
+select * from tbl order by id;
++------+-------+-------+
+| id | name | value |
++------+-------+-------+
+| 1 | Bob | 10 |
+| 2 | Alice | 20 |
+| 3 | Jack | 30 |
+| 4 | Tom | 40 |
+| 5 | John | 50 |
++------+-------+-------+
+```
+
+#### 시나리오 3: 자동 증가 열에 NULL 값을 지정하는 INSERT INTO {#scenario-3-insert-into-specifying-the-auto-increment-column-with-null-values}
+
+자동 증가 열인 `id`를 지정하여 `insert into`를 실행하면 해당 열의 `null` 값은 생성된 값으로 대체됩니다.
+
+```sql
+insert into tbl(id, name, value) values(null, "Doris", 60), (null, "Nereids", 70);
+
+select * from tbl order by id;
++------+---------+-------+
+| id | name | value |
++------+---------+-------+
+| 1 | Bob | 10 |
+| 2 | Alice | 20 |
+| 3 | Jack | 30 |
+| 4 | Tom | 40 |
+| 5 | John | 50 |
+| 6 | Doris | 60 |
+| 7 | Nereids | 70 |
++------+---------+-------+
+```
+
+### 부분 열 업데이트 {#partial-column-update}
+
+자동 증가 열이 있는 merge-on-write Unique 테이블에서 부분 열 업데이트를 수행할 때의 동작은 자동 증가 열이 키 열인지에 따라 달라집니다.
+
+| 자동 증가 열의 위치 | 업데이트 동작 |
+| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| **키 열** | 사용자가 키 열을 명시적으로 지정해야 하며, 부분 업데이트 대상 열에 자동 증가 열을 포함해야 합니다. 데이터 적재 동작은 일반적인 부분 열 업데이트와 같습니다. |
+| **키가 아닌 열** | 자동 증가 열을 지정하지 않으면 테이블의 기존 행에서 해당 값을 가져와 채웁니다. 지정한 경우에는 `null` 값을 생성된 값으로 대체하고, `null`이 아닌 값은 그대로 유지한 뒤 부분 열 업데이트 방식으로 데이터를 삽입합니다. |
+
+#### 예제 1: 자동 증가 열이 키 열인 경우 {#example-1-auto-increment-column-as-a-key-column}
+
+```sql
+CREATE TABLE `demo`.`tbl2` (
+ `id` BIGINT NOT NULL AUTO_INCREMENT,
+ `name` varchar(65533) NOT NULL,
+ `value` int(11) NOT NULL DEFAULT "0"
+) ENGINE=OLAP
+UNIQUE KEY(`id`)
+DISTRIBUTED BY HASH(`id`) BUCKETS 10
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 3",
+ "enable_unique_key_merge_on_write" = "true"
+);
+
+insert into tbl2(id, name, value) values(1, "Bob", 10), (2, "Alice", 20), (3, "Jack", 30);
+
+select * from tbl2 order by id;
++------+-------+-------+
+| id | name | value |
++------+-------+-------+
+| 1 | Bob | 10 |
+| 2 | Alice | 20 |
+| 3 | Jack | 30 |
++------+-------+-------+
+
+set enable_unique_key_partial_update=true;
+set enable_insert_strict=false;
+insert into tbl2(id, name) values(1, "modified"), (4, "added");
+
+select * from tbl2 order by id;
++------+----------+-------+
+| id | name | value |
++------+----------+-------+
+| 1 | modified | 10 |
+| 2 | Alice | 20 |
+| 3 | Jack | 30 |
+| 4 | added | 0 |
++------+----------+-------+
+```
+
+#### 예제 2: 자동 증가 열이 키가 아닌 열인 경우 {#example-2-auto-increment-column-as-a-non-key-column}
+
+```sql
+CREATE TABLE `demo`.`tbl3` (
+ `id` BIGINT NOT NULL,
+ `name` varchar(100) NOT NULL,
+ `score` BIGINT NOT NULL,
+ `aid` BIGINT NOT NULL AUTO_INCREMENT
+) ENGINE=OLAP
+UNIQUE KEY(`id`)
+DISTRIBUTED BY HASH(`id`) BUCKETS 1
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 3",
+ "enable_unique_key_merge_on_write" = "true"
+);
+
+insert into tbl3(id, name, score) values(1, "Doris", 100), (2, "Nereids", 200), (3, "Bob", 300);
+
+select * from tbl3 order by id;
++------+---------+-------+------+
+| id | name | score | aid |
++------+---------+-------+------+
+| 1 | Doris | 100 | 0 |
+| 2 | Nereids | 200 | 1 |
+| 3 | Bob | 300 | 2 |
++------+---------+-------+------+
+
+set enable_unique_key_partial_update=true;
+set enable_insert_strict=false;
+insert into tbl3(id, score) values(1, 999), (2, 888);
+
+select * from tbl3 order by id;
++------+---------+-------+------+
+| id | name | score | aid |
++------+---------+-------+------+
+| 1 | Doris | 999 | 0 |
+| 2 | Nereids | 888 | 1 |
+| 3 | Bob | 300 | 2 |
++------+---------+-------+------+
+
+insert into tbl3(id, aid) values(1, 1000), (3, 500);
+
+select * from tbl3 order by id;
++------+---------+-------+------+
+| id | name | score | aid |
++------+---------+-------+------+
+| 1 | Doris | 999 | 1000 |
+| 2 | Nereids | 888 | 1 |
+| 3 | Bob | 300 | 500 |
++------+---------+-------+------+
+```
+
+## 대표적인 사용 사례 {#typical-use-cases}
+
+<!-- Use cases: dictionary encoding / efficient pagination -->
+
+### 사용 사례 1: 사전 인코딩 {#use-case-1-dictionary-encoding}
+
+**적용 업무**: 비트맵으로 코호트 분석을 수행하는 사용자 프로파일링 시나리오에서는 각 사용자를 고유한 정수 사전 값에 매핑하는 사용자 사전이 필요합니다. 사전 값이 조밀할수록 비트맵 성능이 향상됩니다.
+
+다음은 오프라인 UV/PV 분석 시나리오를 통해 절차를 설명합니다.
+
+#### 1단계: 사용자 행동 상세 테이블 생성 {#step-1-create-the-user-behavior-detail-table}
+
+다음 사용자 행동 테이블에 상세 데이터가 저장되어 있다고 가정합니다.
+
+```sql
+CREATE TABLE `demo`.`dwd_dup_tbl` (
+ `user_id` varchar(50) NOT NULL,
+ `dim1` varchar(50) NOT NULL,
+ `dim2` varchar(50) NOT NULL,
+ `dim3` varchar(50) NOT NULL,
+ `dim4` varchar(50) NOT NULL,
+ `dim5` varchar(50) NOT NULL,
+ `visit_time` DATE NOT NULL
+) ENGINE=OLAP
+DUPLICATE KEY(`user_id`)
+DISTRIBUTED BY HASH(`user_id`) BUCKETS 32
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 3"
+);
+```
+
+#### 2단계: 자동 증가 열을 사용하여 사전 테이블 생성 {#step-2-create-the-dictionary-table-using-an-auto-increment-column}
+
+```sql
+CREATE TABLE `demo`.`dictionary_tbl` (
+ `user_id` varchar(50) NOT NULL,
+ `aid` BIGINT NOT NULL AUTO_INCREMENT
+) ENGINE=OLAP
+UNIQUE KEY(`user_id`)
+DISTRIBUTED BY HASH(`user_id`) BUCKETS 32
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 3",
+ "enable_unique_key_merge_on_write" = "true"
+);
+```
+
+#### 3단계: 데이터를 적재하여 인코딩 매핑 구성 {#step-3-load-data-to-build-the-encoding-mapping}
+
+기존 데이터의 `user_id` 값을 사전 테이블에 적재하여 `user_id`를 정수 값에 매핑합니다.
+
+```sql
+insert into dictionary_tbl(user_id)
+select user_id from dwd_dup_tbl group by user_id;
+```
+
+또는 다음 방법으로 증분 데이터의 `user_id` 값만 사전 테이블에 적재할 수 있습니다.
+
+```sql
+insert into dictionary_tbl(user_id)
+select dwd_dup_tbl.user_id from dwd_dup_tbl left join dictionary_tbl
+on dwd_dup_tbl.user_id = dictionary_tbl.user_id
+where dwd_dup_tbl.visit_time > '2023-12-10' and dictionary_tbl.user_id is NULL;
+```
+
+:::tip
+실제 환경에서는 Flink Connector를 사용하여 Doris에 데이터를 쓸 수도 있습니다.
+:::
+
+#### 4단계: 집계 결과 테이블 생성 {#step-4-create-the-aggregate-result-table}
+
+`dim1`, `dim3`, `dim5`가 분석하려는 통계 차원이라고 가정합니다. 집계 결과를 저장할 다음 집계 테이블을 생성합니다.
+
+```sql
+CREATE TABLE `demo`.`dws_agg_tbl` (
+ `dim1` varchar(50) NOT NULL,
+ `dim3` varchar(50) NOT NULL,
+ `dim5` varchar(50) NOT NULL,
+ `user_id_bitmap` BITMAP BITMAP_UNION NOT NULL,
+ `pv` BIGINT SUM NOT NULL
+) ENGINE=OLAP
+AGGREGATE KEY(`dim1`,`dim3`,`dim5`)
+DISTRIBUTED BY HASH(`dim1`) BUCKETS 32
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 3"
+);
+```
+
+#### 5단계: 데이터 집계 및 쿼리 실행 {#step-5-aggregate-the-data-and-run-queries}
+
+데이터를 집계하고 결과를 집계 결과 테이블에 저장합니다.
+
+```sql
+insert into dws_agg_tbl
+select dwd_dup_tbl.dim1, dwd_dup_tbl.dim3, dwd_dup_tbl.dim5, BITMAP_UNION(TO_BITMAP(dictionary_tbl.aid)), COUNT(1)
+from dwd_dup_tbl INNER JOIN dictionary_tbl on dwd_dup_tbl.user_id = dictionary_tbl.user_id
+group by dwd_dup_tbl.dim1, dwd_dup_tbl.dim3, dwd_dup_tbl.dim5;
+```
+
+UV 및 PV 쿼리를 실행합니다.
+
+```sql
+select dim1, dim3, dim5, bitmap_count(user_id_bitmap) as uv, pv from dws_agg_tbl;
+```
+
+### 사용 사례 2: 효율적인 페이지네이션 {#use-case-2-efficient-pagination}
+
+**배경**: 페이지에 데이터를 표시할 때는 페이지네이션이 필요한 경우가 많습니다. 기존의 페이지네이션은 일반적으로 SQL의 `limit`, `offset`, `order by`를 사용합니다. 하지만 페이지를 깊이 탐색할 때, 즉 offset이 매우 클 때는 실제로 필요한 행이 적더라도 모든 데이터를 메모리로 읽어 들여 전체 정렬을 수행한 후 처리를 계속하므로 비효율적입니다.
+
+**최적화 방안**: 자동 증가 열을 통해 각 행에 고유한 값을 부여할 수 있습니다. 쿼리할 때 이전 페이지의 최댓값 `max_value`를 기록합니다. 이 값은 `unique_value` 열의 최댓값이며, 이후 `where unique_value > max_value limit rows_per_page`를 사용하면 조건자 푸시다운으로 많은 데이터를 초기에 걸러내어 페이지네이션 효율을 높일 수 있습니다.
+
+#### 기존 페이지네이션 방식(비효율적) {#traditional-pagination-inefficient}
+
+다음 업무 테이블에 페이지네이션을 적용한다고 가정합니다.
+
+```sql
+CREATE TABLE `demo`.`records_tbl` (
+ `user_id` int(11) NOT NULL COMMENT "",
+ `name` varchar(26) NOT NULL COMMENT "",
+ `address` varchar(41) NOT NULL COMMENT "",
+ `city` varchar(11) NOT NULL COMMENT "",
+ `nation` varchar(16) NOT NULL COMMENT "",
+ `region` varchar(13) NOT NULL COMMENT "",
+ `phone` varchar(16) NOT NULL COMMENT "",
+ `mktsegment` varchar(11) NOT NULL COMMENT ""
+) DUPLICATE KEY (`user_id`, `name`)
+DISTRIBUTED BY HASH(`user_id`) BUCKETS 10
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 3"
+);
+```
+
+페이지마다 100개의 행을 표시한다고 가정합니다.
+
+- 1페이지 조회:
+
+ ```sql
+ select * from records_tbl order by user_id, name limit 100;
+ ```
+
+- 2페이지 조회:
+
+ ```sql
+ select * from records_tbl order by user_id, name limit 100 offset 100;
+ ```
+
+#### 자동 증가 열을 활용한 페이지네이션(효율적) {#auto-increment-column-pagination-efficient}
+
+테이블에 자동 증가 열을 추가하여 각 행에 고유 식별자를 부여합니다.
+
+```sql
+CREATE TABLE `demo`.`records_tbl2` (
+ `user_id` int(11) NOT NULL COMMENT "",
+ `name` varchar(26) NOT NULL COMMENT "",
+ `address` varchar(41) NOT NULL COMMENT "",
+ `city` varchar(11) NOT NULL COMMENT "",
+ `nation` varchar(16) NOT NULL COMMENT "",
+ `region` varchar(13) NOT NULL COMMENT "",
+ `phone` varchar(16) NOT NULL COMMENT "",
+ `mktsegment` varchar(11) NOT NULL COMMENT "",
+ `unique_value` BIGINT NOT NULL AUTO_INCREMENT
+) DUPLICATE KEY (`user_id`, `name`)
+DISTRIBUTED BY HASH(`user_id`) BUCKETS 10
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 3"
+);
+```
+
+페이지마다 100개의 행을 표시합니다.
+
+- **1페이지 쿼리**:
+
+ ```sql
+ select * from records_tbl2 order by unique_value limit 100;
+ ```
+
+- **2페이지 쿼리**: 프로그램에서 이전 쿼리가 반환한 `unique_value`의 최댓값을 기록한 다음(99라고 가정), 다음 쿼리를 실행합니다.
+
+ ```sql
+ select * from records_tbl2 where unique_value > 99 order by unique_value limit 100;
+ ```
+
+- **뒤쪽 페이지로 바로 이동**: 뒤쪽 페이지를 바로 쿼리하려는 경우에는 이전 페이지의 `unique_value` 최댓값을 얻기가 어렵습니다. 예를 들어 101페이지를 바로 조회하려면 다음 쿼리를 실행합니다.
+
+ ```sql
+ select user_id, name, address, city, nation, region, phone, mktsegment
+ from records_tbl2, (select unique_value as max_value from records_tbl2 order by unique_value limit 1 offset 9999) as previous_data
+ where records_tbl2.unique_value > previous_data.max_value
+ order by unique_value limit 100;
+ ```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/column-compression.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/column-compression.md
new file mode 100644
index 00000000000..90208abc71d
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/column-compression.md
@@ -0,0 +1,125 @@
+---
+{
+ "title": "데이터 압축",
+ "language": "ko",
+ "description": "Doris는 LZ4, ZSTD, Snappy, Zlib 등의 컬럼형 스토리지 압축 알고리즘을 지원하므로 워크로드에 따라 스토리지 비용과 쿼리 성능 사이의 균형을 유연하게 조정할 수 있습니다.",
+ "keywords": [
+ "Doris 데이터 압축",
+ "컬럼형 스토리지 압축",
+ "LZ4",
+ "ZSTD",
+ "Snappy",
+ "Zlib",
+ "압축 알고리즘 선택",
+ "스토리지 효율 최적화"
+ ]
+}
+---
+
+<!-- Knowledge type: Capability definition + Configuration parameters + Selection decision -->
+<!-- Applicable scenarios: Compression selection during table creation / Storage cost optimization / Query performance tuning -->
+
+Doris는 분석 워크로드에 특히 적합한 **컬럼형 스토리지** 모델로 데이터를 구성하고 저장합니다. 같은 컬럼의 데이터는 대체로 분포 특성이 비슷하므로 컬럼형 스토리지는 압축에 유리합니다. Doris는 여러 압축 알고리즘을 기본으로 제공하며, 테이블을 생성할 때 워크로드에 가장 적합한 알고리즘을 선택하여 스토리지 비용과 쿼리 성능 사이의 균형을 맞출 수 있습니다.
+
+## 빠른 선택 가이드 {#quick-selection-guide}
+
+워크로드마다 압축 요구 사항이 다릅니다. 다음 표는 일반적인 시나리오별 권장 알고리즘을 정리한 것입니다.
+
+| 사용 시나리오 | 권장 알고리즘 | 이유 |
+| -------------------------------------------------------- | --------------------- | ------------------------------------------------------------------- |
+| 고성능 실시간 분석, 동시성이 높은 쿼리 | **LZ4**, Snappy | 압축 해제 속도가 매우 빠르고 CPU 오버헤드가 낮음 |
+| 스토리지 비용과 쿼리 성능의 균형 | **ZSTD**, LZ4F | 높은 압축률과 빠른 압축 해제 속도를 함께 제공 |
+| 스토리지 효율이 최우선이며 쿼리 지연 시간에 민감하지 않은 경우 | **ZSTD**, Zlib | 가장 높은 압축률로 디스크 공간 절약 |
+| 아카이빙 및 콜드 데이터 저장 | **Zlib**, LZ4HC | 압축률을 극대화하여 접근 빈도가 낮은 데이터에 적합 |
+
+> 기본 권장 알고리즘은 **ZSTD**입니다. 대부분의 시나리오에서 우수한 압축률과 빠른 압축 해제 속도를 함께 제공합니다.
+
+## 압축이 필요한 이유 {#why-compression-is-needed}
+
+Doris에서 데이터 압축의 주요 목적은 다음 두 가지입니다.
+
+1. **스토리지 비용 절감**: 데이터 저장에 필요한 디스크 공간을 줄여 동일한 물리적 리소스에 더 많은 데이터를 저장할 수 있습니다.
+2. **쿼리 성능 향상**: 압축된 데이터는 공간을 덜 차지하므로 쿼리 실행 시 I/O 작업이 줄어듭니다. 최신 압축 알고리즘은 압축 해제 속도가 매우 빠르므로 스토리지를 절약하면서 쿼리 응답 속도도 높일 수 있습니다.
+
+## 지원하는 압축 알고리즘 {#supported-compression-algorithms}
+
+Doris는 다음 압축 알고리즘을 지원합니다. 각 알고리즘은 압축률과 압축 해제 속도 사이에서 서로 다른 특성을 보입니다.
+
+| 압축 유형 | 특징 | 적용 시나리오 |
+| -------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
+| **압축 없음** | 데이터를 압축하지 않습니다. | 데이터가 이미 압축되어 있거나 스토리지 공간이 병목이 아닌 경우. |
+| **LZ4** | 압축 및 압축 해제 속도가 매우 빠르며 압축률은 보통입니다. | 실시간 쿼리, 동시성이 높은 워크로드 등 빠른 압축 해제가 필요한 경우. |
+| **LZ4F** | 더 유연한 압축 설정을 지원하는 LZ4 확장 버전으로, 속도가 빠르고 압축률은 보통입니다. | 빠른 압축과 세밀한 설정 제어가 필요한 경우. |
+| **LZ4HC** | LZ4보다 압축률이 높지만 압축 속도는 느립니다. 압축 해제 속도는 LZ4와 비슷합니다. | 압축 해제 속도가 중요하면서 더 높은 압축률도 필요한 경우. |
+| **ZSTD** (Zstandard) | 압축률이 높고 압축 수준을 유연하게 조정할 수 있으며, 압축률이 높아도 압축 해제 속도가 빠릅니다. | 높은 스토리지 효율과 우수한 쿼리 성능이 모두 필요한 경우. |
+| **Snappy** | 주로 빠른 압축 해제를 위해 설계되었으며 압축률은 보통입니다. | 빠른 압축 해제가 필요하고 CPU 리소스가 제한적인 경우. |
+| **Zlib** | 압축률과 속도 사이의 균형이 좋습니다. 압축 및 압축 해제 속도는 느리지만 압축률은 더 높습니다. | 아카이빙, 콜드 데이터 저장 등 압축 해제 속도에 민감하지 않은 경우. |
+
+## 압축의 동작 방식 {#how-compression-works}
+
+Doris의 압축은 여러 계층이 함께 작동하여 구현됩니다.
+
+### 컬럼별 압축 {#per-column-compression}
+
+Doris는 컬럼형 스토리지를 사용하므로 테이블의 각 컬럼을 독립적으로 압축합니다. 같은 컬럼의 데이터는 대체로 분포 특성이 비슷하므로 컬럼별 압축은 행별 압축보다 압축 효율이 높습니다.
+
+### 압축 전 인코딩 {#encoding-before-compression}
+
+Doris는 압축을 수행하기 전에 먼저 컬럼 데이터를 인코딩합니다. 데이터를 압축에 더 적합한 형태로 변환하여 압축률을 더욱 높입니다. 일반적인 인코딩 방식은 다음과 같습니다.
+
+- **사전 인코딩**: 반복되는 문자열을 더 짧은 사전 ID로 대체합니다.
+- **런 길이 인코딩(RLE)**: 연속으로 반복되는 값을 "값 + 반복 횟수"로 표현합니다.
+
+### 페이지별 압축 {#per-page-compression}
+
+Doris는 **페이지 단위** 압축 전략을 사용합니다.
+
+1. 각 컬럼의 데이터를 여러 페이지로 나눕니다.
+2. 각 페이지의 데이터를 독립적으로 압축합니다.
+3. 쿼리 실행 시 필요한 페이지만 압축을 해제하여 컬럼 전체를 스캔하지 않도록 합니다.
+
+페이지별 압축은 압축률과 압축 해제 성능 사이의 균형을 유지하면서 대규모 데이터셋을 효율적으로 처리할 수 있습니다.
+
+### 스토리지 포맷 V3 최적화 {#storage-format-v3-optimization}
+
+Doris 스토리지 포맷 V3부터 숫자형 데이터의 인코딩 전략이 더욱 최적화되었습니다.
+
+- 정수형은 기본적으로 `PLAIN_ENCODING`을 사용합니다.
+- LZ4 또는 ZSTD 압축과 함께 사용하면 읽기 처리량이 높아지고 CPU 오버헤드가 줄어듭니다.
+
+자세한 내용은 [스토리지 포맷 V3](./storage-format)를 참조하세요.
+
+### 설정 가능한 압축 전략 {#configurable-compression-strategy}
+
+테이블을 생성할 때 압축 알고리즘을 지정하여 실제 워크로드에 맞게 압축 효율과 쿼리 성능 사이의 균형을 최적으로 조정할 수 있습니다.
+
+## 압축에 영향을 주는 요인 {#factors-that-affect-compression}
+
+압축 효과는 선택한 알고리즘뿐 아니라 데이터 자체의 특성에도 영향을 받습니다.
+
+| 요인 | 설명 |
+| ----------------------- | -------------------------------------------------------------------------------------------------------------------- |
+| **데이터의 순차성** | 타임스탬프나 연속된 숫자 값처럼 데이터 순서가 규칙적일수록 압축 알고리즘이 반복 패턴을 더 쉽게 식별할 수 있어 압축률이 높아집니다. |
+| **데이터 중복도** | 컬럼에 반복되는 값이 많을수록 압축 효과가 좋습니다. 사전 인코딩은 중복도가 높은 데이터에 특히 효과적입니다. |
+| **데이터 타입** | 숫자형(정수, 부동 소수점 수)은 일반적으로 문자열형보다 압축하기 쉽습니다. 값의 범위가 넓을수록 압축에 미치는 영향도 커집니다. |
+| **컬럼 길이** | 짧은 컬럼은 일반적으로 긴 컬럼보다 압축하기 쉽습니다. 압축 알고리즘이 짧은 데이터 블록에서 반복 패턴을 더 효율적으로 찾을 수 있기 때문입니다. |
+| **NULL 값 비율** | NULL 값의 비율이 높으면 압축 알고리즘이 이를 특수 패턴으로 인코딩하여 스토리지 공간을 더 줄일 수 있습니다. |
+
+## Doris에서 압축 설정하기 {#configuring-compression-in-doris}
+
+테이블을 생성할 때 `compression` 매개변수를 `PROPERTIES`에 설정하여 압축 알고리즘을 지정합니다.
+
+```sql
+CREATE TABLE example_table (
+ id INT,
+ name STRING,
+ age INT
+)
+DUPLICATE KEY(id)
+DISTRIBUTED BY HASH(id) BUCKETS 10
+PROPERTIES (
+ "compression" = "zstd"
+);
+```
+
+`compression`에 지정할 수 있는 값은 `none`, `lz4`, `lz4f`, `lz4hc`, `zstd`, `snappy`, `zlib`입니다. 명시적으로 지정하지 않으면 Doris는 기본 압축 알고리즘인 `ZSTD`를 사용합니다(FE 설정 `default_compression_type`으로 제어).
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-model/aggregate.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-model/aggregate.md
new file mode 100644
index 00000000000..e2266321767
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-model/aggregate.md
@@ -0,0 +1,187 @@
+---
+{
+ "title": "집계 모델",
+ "language": "ko",
+ "description": "Doris 집계 모델은 사전 집계를 통해 중복 계산을 줄이고, 대규모 집계 쿼리의 성능을 높이며, 저장 공간을 절약합니다. 다차원 요약 및 보고서 분석 시나리오에 적합합니다."
+}
+---
+
+<!-- Knowledge type: Table model selection / Table creation syntax -->
+<!-- Applicable scenarios: Multidimensional summary analysis / Reporting / Pre-aggregation -->
+
+Doris 집계 키 모델은 대규모 데이터 쿼리에서 집계 연산을 효율적으로 처리하도록 설계되었습니다. 데이터 적재 과정과 백그라운드 병합 단계에서 사전 집계를 수행하여 중복 계산을 줄이고 집계 결과만 저장하므로, 저장 공간을 절약하고 쿼리 속도를 높입니다.
+
+## 적용 시나리오 {#applicable-scenarios}
+
+집계 모델은 다음 두 가지 유형의 비즈니스 시나리오에 적합합니다.
+
+- **상세 데이터 요약**: 전자상거래 플랫폼의 월별 매출 실적, 금융 리스크 관리의 고객별 총 거래 금액, 광고 클릭 수 등의 다차원 요약 분석.
+- **원시 상세 데이터에 의존하지 않는 쿼리**: 경영 대시보드 보고서, 사용자 거래 행동 분석 등. 원시 상세 데이터는 데이터 레이크에 보관하고, 데이터 웨어하우스에는 요약 결과만 저장하면 됩니다.
+
+## 작동 방식 {#how-it-works}
+
+집계 모델에서는 데이터를 적재할 때마다 새 버전이 생성됩니다. 버전은 백그라운드 Compaction 단계에서 병합되며, 쿼리 시점에 기본 키를 기준으로 데이터가 다시 집계됩니다. 전체 처리 흐름은 세 단계로 나뉩니다.
+
+1. **데이터 적재 단계**: 데이터를 배치 단위로 적재합니다. 각 배치마다 버전이 생성되며, 집계 키가 같은 행에 대해 사전 집계(예: 합계 또는 개수 계산)를 수행합니다.
+2. **백그라운드 병합 단계(Compaction)**: 여러 버전 파일을 주기적으로 병합하여 중복을 줄이고 저장 공간을 최적화합니다.
+3. **쿼리 단계**: 시스템이 집계 키를 기준으로 데이터를 최종 집계하여 정확한 쿼리 결과를 보장합니다.
+
+## 테이블 생성 구문 {#table-creation-syntax}
+
+`AGGREGATE KEY` 키워드로 집계 모델을 지정하고, Value 컬럼을 집계하는 데 사용할 Key 컬럼을 선언합니다.
+
+```sql
+CREATE TABLE IF NOT EXISTS example_tbl_agg
+(
+ user_id LARGEINT NOT NULL,
+ load_date DATE NOT NULL,
+ city VARCHAR(20),
+ last_visit_dt DATETIME REPLACE DEFAULT "1970-01-01 00:00:00",
+ cost BIGINT SUM DEFAULT "0",
+ max_dwell INT MAX DEFAULT "0"
+)
+AGGREGATE KEY(user_id, load_date, city)
+DISTRIBUTED BY HASH(user_id) BUCKETS 10;
+```
+
+위 예제는 사용자 정보와 방문 행동을 저장하는 테이블을 정의하며, `user_id`, `load_date`, `city`를 집계용 Key 컬럼으로 사용합니다. 데이터를 적재할 때 Key 컬럼 값이 같은 행은 하나의 행으로 집계되며, Value 컬럼은 선언된 집계 유형에 따라 차원별로 집계됩니다.
+
+### 지원되는 집계 방식 {#supported-aggregation-methods}
+
+집계 테이블의 Value 컬럼은 다음 집계 방식을 지원합니다.
+
+| 집계 방식 | 설명 |
+| ------------------- | -------------------------------------------------------------------------- |
+| SUM | 값을 합산하며, 여러 행의 Value를 누적합니다. |
+| REPLACE | 값을 대체하며, 다음 배치의 Value가 이전 행의 Value를 대체합니다. |
+| MAX | 최댓값을 유지합니다. |
+| MIN | 최솟값을 유지합니다. |
+| REPLACE_IF_NOT_NULL | NULL이 아닌 값으로 대체합니다. REPLACE와 달리 `null` 값으로 대체하지 않습니다. |
+| HLL_UNION | HLL 타입 컬럼에 사용하며, HyperLogLog 알고리즘으로 집계합니다. |
+| BITMAP_UNION | BITMAP 타입 컬럼에 사용하며, 비트맵 합집합 집계를 수행합니다. |
+
+:::info 참고
+위 집계 방식으로 비즈니스 요구 사항을 충족할 수 없다면 [AGG_STATE](#agg_state) 타입을 사용할 수 있습니다.
+:::
+
+## 데이터 쓰기 및 집계 예제 {#data-write-and-aggregation-example}
+
+집계 테이블의 데이터는 Key 컬럼을 기준으로 집계되며, 쓰기가 끝나면 집계가 완료됩니다.
+
+
+
+다음 예제에서 테이블에는 원래 4개의 행이 있습니다. 2개의 행을 추가로 삽입하면 Key 컬럼을 기준으로 Value 컬럼이 집계됩니다.
+
+```sql
+-- 4 rows raw data
+INSERT INTO example_tbl_agg VALUES
+(101, '2024-11-01', 'BJ', '2024-10-29', 10, 20),
+(102, '2024-10-30', 'BJ', '2024-10-29', 20, 20),
+(101, '2024-10-30', 'BJ', '2024-10-28', 5, 40),
+(101, '2024-10-30', 'SH', '2024-10-29', 10, 20);
+
+-- insert into 2 rows
+INSERT INTO example_tbl_agg VALUES
+(101, '2024-11-01', 'BJ', '2024-10-30', 20, 10),
+(102, '2024-11-01', 'BJ', '2024-10-30', 10, 30);
+
+-- check the rows of table
+SELECT * FROM example_tbl_agg;
++---------+------------+------+---------------------+------+----------------+
+| user_id | load_date | city | last_visit_dt | cost | max_dwell |
++---------+------------+------+---------------------+------+----------------+
+| 102 | 2024-10-30 | BJ | 2024-10-29 00:00:00 | 20 | 20 |
+| 102 | 2024-11-01 | BJ | 2024-10-30 00:00:00 | 10 | 30 |
+| 101 | 2024-10-30 | BJ | 2024-10-28 00:00:00 | 5 | 40 |
+| 101 | 2024-10-30 | SH | 2024-10-29 00:00:00 | 10 | 20 |
+| 101 | 2024-11-01 | BJ | 2024-10-30 00:00:00 | 30 | 20 |
++---------+------------+------+---------------------+------+----------------+
+```
+
+## AGG_STATE {#agg_state}
+
+:::info 참고
+AGG_STATE는 실험적 기능입니다. 개발 및 테스트 환경에서 사용하는 것을 권장합니다.
+:::
+
+`AGG_STATE`는 기본 제공 집계 방식으로 요구 사항을 충족할 수 없는 시나리오에 적합합니다. 사용할 때는 다음 제약 사항에 유의하세요.
+
+- Key 컬럼으로 사용할 수 없습니다.
+- 테이블 생성 시 집계 함수 시그니처를 선언해야 합니다.
+- 길이나 기본값을 지정할 필요가 없으며, 실제 저장 크기는 함수 구현에 따라 달라집니다.
+
+### 테이블 생성 예제 {#table-creation-example}
+
+```sql
+set enable_agg_state = true;
+
+CREATE TABLE aggstate
+(
+ k1 INT NULL,
+ v1 INT SUM,
+ v2 agg_state<group_concat(string)> generic
+)
+AGGREGATE KEY(k1)
+DISTRIBUTED BY HASH(k1) BUCKETS 3;
+```
+
+위 예제에서 `agg_state`는 데이터 타입을 선언하는 데 사용하며, `sum` / `group_concat`은 집계 함수 시그니처입니다. `agg_state`는 데이터 타입(`int`, `array`, `string`과 유사)이며, 세 가지 함수 조합자 [state](../../sql-manual/sql-functions/combinators/state), [merge](../../sql-manual/sql-functions/combinators/merge), [union](../../sql-manual/sql-functions/combinators/union)과 함께만 사용할 수 있습니다. 이 타입은 집계 함수의 중간 결과(예: `group_concat`의 중간 상태)를 나타내며, 최종 결과를 나타내지는 않습니다.
+
+### 쓰기: state로 중간 결과 생성 {#write-use-state-to-generate-intermediate-results}
+
+`agg_state` 타입의 데이터는 반드시 `state` 함수를 사용하여 생성해야 합니다. 이 테이블에서는 `group_concat_state`를 사용합니다.
+
+```sql
+INSERT INTO aggstate VALUES (1, 1, group_concat_state('a'));
+INSERT INTO aggstate VALUES (1, 2, group_concat_state('b'));
+INSERT INTO aggstate VALUES (1, 3, group_concat_state('c'));
+INSERT INTO aggstate VALUES (2, 4, group_concat_state('d'));
+```
+
+이 시점에 테이블에서 이루어지는 계산은 다음 그림과 같습니다.
+
+
+
+### 쿼리: merge로 최종 결과 반환 {#query-use-merge-to-return-the-final-result}
+
+쿼리 시점에 [merge](../../sql-manual/sql-functions/combinators/merge) 연산을 사용하여 여러 상태를 결합하고 최종 집계 결과를 반환할 수 있습니다. `group_concat`은 순서에 민감하므로 결과가 일정하지 않습니다.
+
+```sql
+SELECT group_concat_merge(v2) FROM aggstate;
++------------------------+
+| group_concat_merge(v2) |
++------------------------+
+| d,c,b,a |
++------------------------+
+```
+
+### 중간 결과 유지: union 연산 사용 {#retain-intermediate-results-use-the-union-operation}
+
+최종 집계 결과가 필요하지 않고 중간 결과를 유지하려면 `union` 연산을 사용합니다.
+
+```sql
+INSERT INTO aggstate
+SELECT 3, sum(v1), group_concat_union(v2) FROM aggstate;
+```
+
+이 시점에 테이블에서 이루어지는 계산은 다음 그림과 같습니다.
+
+
+
+`group_concat`은 순서에 민감하므로 결과가 일정하지 않습니다. 쿼리 결과는 다음과 같습니다.
+
+```sql
+mysql> SELECT sum(v1), group_concat_merge(v2) FROM aggstate;
++---------+------------------------+
+| sum(v1) | group_concat_merge(v2) |
++---------+------------------------+
+| 20 | c,b,a,d,c,b,a,d |
++---------+------------------------+
+
+mysql> SELECT sum(v1), group_concat_merge(v2) FROM aggstate WHERE k1 != 2;
++---------+------------------------+
+| sum(v1) | group_concat_merge(v2) |
++---------+------------------------+
+| 16 | c,b,a,d,c,b,a |
++---------+------------------------+
+```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-model/duplicate.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-model/duplicate.md
new file mode 100644
index 00000000000..a142d1d1441
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-model/duplicate.md
@@ -0,0 +1,87 @@
+---
+{
+ "title": "Duplicate Key 모델",
+ "language": "ko",
+ "description": "Doris의 Duplicate Key 모델은 중복 제거나 집계 없이 모든 원본 데이터를 보존하므로, 로그, 사용자 행동, 트랜잭션 상세 내역처럼 데이터를 추가만 하는 시나리오에 적합합니다."
+}
+---
+
+<!-- Knowledge type: Table model description -->
+<!-- Applicable scenarios: Logs, behavior analysis, transaction details, and other scenarios that need to retain raw records -->
+
+Duplicate Key 모델은 Doris의 **기본 테이블 모델**입니다. 중복 제거나 집계 없이 모든 원본 데이터 레코드를 저장합니다. 테이블을 생성할 때 `DUPLICATE KEY` 키워드로 데이터 저장에 사용할 정렬 열을 지정하고 자주 사용하는 쿼리를 최적화할 수 있습니다. 일반적으로 정렬 키에는 세 개 이하의 열을 선택하는 것이 좋습니다. 정렬 열을 선택하는 방법은 [정렬 키](../index/prefix-index)를 참조하세요.
+
+## 적용 시나리오 {#applicable-scenarios}
+
+Duplicate Key 모델의 데이터는 일반적으로 **추가 전용**이며, 기존 데이터는 업데이트하지 않습니다. 모든 원본 데이터를 저장해야 하는 시나리오에 적합합니다.
+
+- **로그 저장**: 액세스 로그, 오류 로그 등 다양한 프로그램 운영 로그를 저장하는 데 사용합니다. 이후 감사와 분석을 원활하게 수행할 수 있도록 모든 레코드를 상세히 보존해야 합니다.
+- **사용자 행동 데이터**: 클릭 데이터나 사용자 방문 경로 등 사용자 행동을 분석할 때, 이후 사용자 프로필을 구축하고 행동 경로를 세밀하게 분석할 수 있도록 상세한 사용자 행동을 보존해야 합니다.
+- **트랜잭션 데이터**: 트랜잭션 활동이나 주문 데이터를 저장할 때는 일반적으로 트랜잭션이 종료된 후 데이터를 수정하지 않습니다. Duplicate Key 모델은 이러한 트랜잭션 정보를 레코드 누락 없이 보존하는 데 적합하므로, 정확한 트랜잭션 대사 작업을 편리하게 수행할 수 있습니다.
+
+## 핵심 특징 {#core-features}
+
+Duplicate Key 모델에는 다음과 같은 세 가지 주요 특징이 있습니다.
+
+| 특징 | 설명 |
+| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| **원본 데이터 보존** | 모든 원본 데이터를 보존하므로 원시 데이터를 저장하고 쿼리하는 데 적합합니다. 상세 데이터 분석이 필요한 애플리케이션 시나리오에서 Duplicate Key 모델은 데이터 손실 위험을 방지합니다. |
+| **중복 제거 및 집계 없음** | Aggregate Key 모델 및 Unique Key 모델과 달리, Duplicate Key 모델은 데이터를 중복 제거하거나 집계하지 않습니다. 두 행이 동일하더라도 삽입할 때마다 두 행 모두 온전히 보존됩니다. |
+| **유연한 데이터 쿼리** | 모든 원본 데이터를 보존하므로 전체 데이터에서 상세 정보를 추출하고 전체 데이터셋을 기반으로 원하는 차원에서 집계 연산을 수행할 수 있습니다. 이를 통해 메타데이터 감사와 세밀한 분석이 가능합니다. |
+
+## 테이블 생성 구문 {#table-creation-syntax}
+
+테이블을 생성할 때 `DUPLICATE KEY` 키워드로 Duplicate Key 모델을 지정하고 Key 열을 설정합니다. **Duplicate Key 모델에서 Key 열은 정렬에만 사용되며, 고유할 필요는 없습니다.**
+
+다음 예제는 로그 정보를 저장하는 Duplicate Key 테이블을 생성하며, 세 개의 열 `log_time`, `log_type`, `error_code`를 기준으로 정렬합니다.
+
+```sql
+CREATE TABLE IF NOT EXISTS example_tbl_duplicate
+(
+ log_time DATETIME NOT NULL,
+ log_type INT NOT NULL,
+ error_code INT,
+ error_msg VARCHAR(1024),
+ op_id BIGINT,
+ op_time DATETIME
+)
+DUPLICATE KEY(log_time, log_type, error_code)
+DISTRIBUTED BY HASH(log_type) BUCKETS 10;
+```
+
+## 데이터 쓰기 및 저장 {#data-writes-and-storage}
+
+<!-- Knowledge type: Write behavior description -->
+
+Duplicate Key 테이블에서는 데이터를 중복 제거하거나 집계하지 않습니다. **삽입된 데이터는 그대로 저장**되며, Key 열은 정렬 키로만 사용됩니다.
+
+
+
+위 그림과 같이 테이블에는 원래 4개의 행이 있습니다. 2개의 행을 추가로 삽입하면 모든 데이터가 APPEND 모드로 저장되어 최종적으로 6개의 행이 보존됩니다.
+
+```sql
+-- Write 4 rows of original data
+INSERT INTO example_tbl_duplicate VALUES
+('2024-11-01 00:00:00', 2, 2, 'timeout', 12, '2024-11-01 01:00:00'),
+('2024-11-02 00:00:00', 1, 2, 'success', 13, '2024-11-02 01:00:00'),
+('2024-11-03 00:00:00', 2, 2, 'unknown', 13, '2024-11-03 01:00:00'),
+('2024-11-04 00:00:00', 2, 2, 'unknown', 12, '2024-11-04 01:00:00');
+
+-- Append 2 more rows
+INSERT INTO example_tbl_duplicate VALUES
+('2024-11-01 00:00:00', 2, 2, 'timeout', 12, '2024-11-01 01:00:00'),
+('2024-11-01 00:00:00', 2, 2, 'unknown', 13, '2024-11-01 01:00:00');
+
+-- The query result shows that all 6 rows are retained
+SELECT * FROM example_tbl_duplicate;
++---------------------+----------+------------+-----------+-------+---------------------+
+| log_time | log_type | error_code | error_msg | op_id | op_time |
++---------------------+----------+------------+-----------+-------+---------------------+
+| 2024-11-02 00:00:00 | 1 | 2 | success | 13 | 2024-11-02 01:00:00 |
+| 2024-11-01 00:00:00 | 2 | 2 | timeout | 12 | 2024-11-01 01:00:00 |
+| 2024-11-03 00:00:00 | 2 | 2 | unknown | 13 | 2024-11-03 01:00:00 |
+| 2024-11-04 00:00:00 | 2 | 2 | unknown | 12 | 2024-11-04 01:00:00 |
+| 2024-11-01 00:00:00 | 2 | 2 | unknown | 13 | 2024-11-01 01:00:00 |
+| 2024-11-01 00:00:00 | 2 | 2 | timeout | 12 | 2024-11-01 01:00:00 |
++---------------------+----------+------------+-----------+-------+---------------------+
+```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-model/intro.mdx b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-model/intro.mdx
new file mode 100644
index 00000000000..b26fbabe1e1
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-model/intro.mdx
@@ -0,0 +1,134 @@
+---
+{
+ "title": "테이블 모델 개요",
+ "language": "ko",
+ "description": "Doris 테이블 모델 선택 가이드: Duplicate 모델은 원시 데이터를 유지하고, Unique 모델은 기본 키를 기준으로 중복을 제거하고 데이터를 업데이트하며, Aggregate 모델은 사전 집계를 통해 분석 쿼리의 속도를 높입니다."
+}
+---
+
+import GettingStartedCard from '@site/src/components/getting-started-card/getting-started-card';
+
+{/* Knowledge type: Architecture selection decision */}
+{/* Applicable scenarios: Table creation selection / Data modeling */}
+
+Doris에서 테이블을 생성할 때는 **테이블 모델**을 지정해야 합니다. 테이블 모델은 데이터의 저장, 중복 제거, 집계 및 업데이트 방식을 결정합니다. Doris는 **Duplicate 모델**(Duplicate Key), **Unique 모델**(Unique Key), **Aggregate 모델**(Aggregate Key)의 세 가지 테이블 모델을 제공합니다. 각 모델은 원시 데이터 유지, 기본 키를 기준으로 한 업데이트, 사전 집계 분석이라는 세 가지 대표적인 시나리오에 대응합니다. 테이블을 생성한 후에는 테이블 모델을 변경할 수 없으므로 신중하게 선택해야 합니다.
+
+## 시나리오에 따른 테이블 모델 선택 {#choose-a-table-model-by-scenario}
+
+다음 표를 참고하면 테이블을 생성하기 전에 사용할 테이블 모델을 빠르게 결정할 수 있습니다.
+
+| 비즈니스 시나리오 | 권장 모델 | 주요 특징 |
+| ---------------------------------------------------------------------------------------------- | ----------------------------------- | ---------------------------------------------------------------------------- |
+| 로그, 이벤트, 행동 분석 등 모든 원시 레코드를 유지해야 하는 경우 | **Duplicate 모델**(Duplicate Key) | Key 열의 값이 중복될 수 있음. 모든 차원에 대한 애드혹 쿼리에 적합 |
+| 실시간 차원 테이블, 주문, 사용자 프로필 등 기본 키를 기준으로 업데이트하는 경우 | **Unique 모델**(Unique Key) | Key 열의 값이 고유함. 동일한 Key에 대해 최신 데이터만 유지 |
+| 보고서 요약 집계, 트래픽 통계 등 사전 집계가 필요한 정형화된 분석 | **Aggregate 모델**(Aggregate Key) | Key 열을 기준으로 사전 집계하여 스캔할 데이터양과 연산량을 줄임 |
+
+## 세 가지 테이블 모델 상세 설명 {#the-three-table-models-in-detail}
+
+### Duplicate Key 모델 {#duplicate-key-model}
+
+- **핵심 동작 방식**: 지정한 Key 열의 값이 중복될 수 있습니다. 스토리지 계층은 중복 제거나 집계 없이 기록된 모든 데이터를 유지합니다.
+- **적용 시나리오**: 로그, 상세 이벤트, 행동 스트림 등 모든 원시 데이터 레코드를 유지해야 하는 경우에 적합합니다.
+- **장점**: 집계 제약이 없어 열 기반 스토리지의 이점을 충분히 활용할 수 있습니다. 쿼리는 관련 열만 읽으며 모든 Key 열을 읽을 필요가 없으므로, 모든 차원에 대한 애드혹 쿼리에 적합합니다.
+- **제약 사항**: 사전 집계가 제공하는 쿼리 가속 효과를 활용할 수 없습니다.
+- **자세히 보기**: [Duplicate 모델](./duplicate)
+
+### Unique Key 모델 {#unique-key-model}
+
+- **핵심 동작 방식**: 각 행의 Key 값은 고유합니다. 스토리지 계층은 각 Key에 대해 가장 최근에 기록된 데이터만 유지합니다.
+- **적용 시나리오**: 실시간 차원 테이블, 주문 상태, 사용자 프로필 등 기본 키의 고유성 제약이 필요하고 데이터가 지속적으로 업데이트되는 경우에 적합합니다.
+- **장점**: 기본 키의 고유성을 보장하고, `UPDATE` 및 `DELETE` 문을 지원하며, 데이터 적재 중 전체 행 업데이트와 일부 열 업데이트를 모두 지원합니다.
+- **제약 사항**: ROLLUP과 같은 사전 집계 기능이 제공하는 쿼리 가속 효과를 활용할 수 없습니다.
+- **자세히 보기**: [Unique 모델](./unique)
+
+### Aggregate Key 모델 {#aggregate-key-model}
+
+- **핵심 동작 방식**: Key 열을 기준으로 Value 열을 사전 집계합니다. 스토리지 계층은 집계 결과만 유지합니다.
+- **적용 시나리오**: 지표 요약 집계, 트래픽 통계, 광고 클릭 집계 등 차원이 고정된 보고서형 쿼리에 적합합니다.
+- **장점**: 사전 집계를 통해 쿼리 시 스캔할 데이터양과 필요한 연산량을 크게 줄일 수 있습니다.
+- **제약 사항**:
+ - `count(*)` 쿼리에 적합하지 않습니다.
+ - Value 열의 집계 방식은 테이블 생성 시 고정됩니다. 다른 유형의 집계 쿼리를 실행할 때는 의미상 올바른 결과가 나오는지 고려해야 합니다.
+- **자세히 보기**: [Aggregate 모델](./aggregate)
+
+:::tip 일부 열 업데이트
+Unique 모델과 Aggregate 모델은 모두 일부 열 업데이트를 지원합니다. 권장 사용 방법은 [Unique 모델의 일부 열 업데이트](../../data-operate/update/update-of-unique-model) 및 [Aggregate 모델의 일부 열 업데이트](../../data-operate/update/update-of-aggregate-model)를 참고하세요.
+:::
+
+## 정렬 키 {#sort-key}
+
+{/* Knowledge type: Concept definition */}
+
+Doris는 데이터를 열 단위로 저장하며, 테이블의 열은 두 가지로 나뉩니다.
+
+- **Key 열**: 그룹화와 정렬에 사용되며, 테이블 생성 시 명시적으로 지정합니다.
+- **Value 열**: Key 열과 함께 저장되며, 집계 연산에 사용됩니다.
+
+Key 열은 하나 이상의 필드로 구성될 수 있습니다. 어떤 테이블 모델을 사용하든 테이블 생성 시 Key 열을 지정해야 하며, 스토리지 계층에서는 Key 열을 기준으로 데이터를 정렬하여 저장합니다. Key 열의 의미는 모델에 따라 조금씩 다릅니다.
+
+| 테이블 모델 | Key 열의 역할 |
+| ------------------------------- | ---------------------------------------------------------------------- |
+| Duplicate 모델(Duplicate Key) | 정렬에만 사용하며, 고유성을 강제하지 않음 |
+| Unique 모델(Unique Key) | 정렬과 고유성 제약을 적용하며, 기본 키를 기준으로 중복 제거에 사용 |
+| Aggregate 모델(Aggregate Key) | 정렬과 고유성 제약을 적용하며, Key를 기준으로 사전 집계에 사용 |
+
+### 잘 설계된 정렬 키의 이점 {#benefits-of-a-well-designed-sort-key}
+
+잘 설계된 정렬 키는 다음 세 가지 측면에서 성능을 개선합니다.
+
+1. **쿼리 성능 향상**: 정렬 키는 스캔할 데이터양을 줄이는 데 도움이 됩니다. 범위 쿼리나 필터 쿼리는 정렬 키를 기준으로 데이터를 바로 찾을 수 있으며, 정렬이 필요한 쿼리도 정렬 키를 통해 속도를 높일 수 있습니다.
+2. **데이터 압축 최적화**: 정렬 키에 따라 유사한 데이터가 한곳에 모이므로 압축률이 크게 높아지고 스토리지 사용량이 줄어듭니다.
+3. **중복 제거 비용 절감**: Unique 모델에서는 정렬 키를 통해 Doris가 기본 키 중복을 더 효율적으로 제거하고 데이터의 고유성을 보장할 수 있습니다.
+
+### 정렬 키 설계 권장 사항 {#sort-key-design-recommendations}
+
+Key 열을 설계할 때는 다음 원칙을 따르세요.
+
+- **Key 열은 모든 Value 열보다 앞에 와야 합니다**.
+- **정수 타입을 우선 사용하세요**: 정수는 연산과 조회에서 문자열보다 훨씬 효율적입니다.
+- **정수의 길이는 필요한 만큼만 사용하세요**: 비즈니스에서 요구하는 값의 범위를 충족하는 가장 짧은 정수 타입을 선택하세요.
+- **`VARCHAR` 및 `STRING`의 길이는 필요한 만큼만 사용하세요**: 필드 길이를 지나치게 길게 설정하지 마세요.
+
+## 테이블 모델별 기능 비교 {#capability-comparison-of-table-models}
+
+다음 표는 세 가지 테이블 모델의 중복 제거, 뷰, 업데이트 및 데이터 적재 기능 차이를 요약한 것입니다.
+
+| 기능 | Duplicate 모델 | Unique 모델 | Aggregate 모델 |
+| -------------------------------------- | -------------------------------------------- | ------------- | ------------------- |
+| Key 열의 고유성 제약 | 지원하지 않음. Key 열의 값이 중복될 수 있음 | 지원 | 지원 |
+| 동기 구체화된 뷰 | 지원 | 지원 | 지원 |
+| 비동기 구체화된 뷰 | 지원 | 지원 | 지원 |
+| `UPDATE` 문 | 지원하지 않음 | 지원 | 지원하지 않음 |
+| `DELETE` 문 | 일부 지원 | 지원 | 지원하지 않음 |
+| 데이터 적재 중 전체 행 업데이트 | 지원하지 않음 | 지원 | 지원하지 않음 |
+| 데이터 적재 중 일부 열 업데이트 | 지원하지 않음 | 지원 | 일부 지원 |
+
+## 다음 단계 {#next-steps}
+
+모델 간 차이를 이해했다면 각 모델의 상세 문서를 살펴보세요.
+
+<div className="cards-grid">
+<GettingStartedCard
+ title="Duplicate 모델"
+ description="Duplicate Key 모델의 테이블 생성 구문과 쓰기 동작을 자세히 설명합니다. 로그와 이벤트처럼 원시 레코드를 유지해야 하는 시나리오에 적합합니다."
+ link="./duplicate"
+/>
+
+<GettingStartedCard
+ title="Unique 모델"
+ description="Unique Key 모델의 기본 키 중복 제거, UPDATE/DELETE 및 일부 열 업데이트를 자세히 설명합니다. 실시간 업데이트 시나리오에 적합합니다."
+ link="./unique"
+/>
+
+<GettingStartedCard
+ title="Aggregate 모델"
+ description="Aggregate Key 모델의 사전 집계 동작 방식과 집계 함수 선택 방법을 자세히 설명합니다. 보고서 및 지표 요약 집계 분석에 적합합니다."
+ link="./aggregate"
+/>
+
+<GettingStartedCard
+ title="모범 사례"
+ description="테이블 모델 선택 권장 사항, Aggregate 모델의 제약 사항, 테이블 생성 시 Key 열과 데이터 타입에 관한 모범 사례를 설명합니다."
+ link="./tips"
+/>
+</div>
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-model/merge-on-write.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-model/merge-on-write.md
new file mode 100644
index 00000000000..ffcb1eabc4c
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-model/merge-on-write.md
@@ -0,0 +1,99 @@
+---
+{
+ "title": "Merge-on-Write",
+ "language": "ko",
+ "description": "Doris Unique Key 모델이 Key의 고유성을 보장하는 방식: merge-on-write와 merge-on-read 구현 방식, 성능상의 장단점, 두 방식의 선택 기준을 설명합니다."
+}
+---
+
+**Merge-on-write**와 **merge-on-read**는 [Unique Key 모델](./unique)의 두 가지 스토리지 구현 방식입니다. 두 방식 모두 Key 컬럼의 고유성을 유지하고 동일한 쿼리 결과를 반환하지만, 중복 Key를 처리하는 시점이 달라 읽기 및 쓰기 성능에 차이가 있습니다. 기본값인 Merge-on-write는 대부분의 워크로드에 가장 적합합니다.
+
+<!-- Knowledge type: Concept -->
+<!-- Applicable scenarios: Choosing a Unique Key implementation -->
+
+## 비교 {#comparison}
+
+| 구현 방식 | 병합 시점 | 쓰기 성능 | 쿼리 성능 | 적합한 시나리오 |
+| --- | --- | --- | --- | --- |
+| Merge-on-write(기본값) | 쓰기 시점 | 보통 | 높음 | 쿼리와 쓰기 성능의 균형이 필요한 대부분의 시나리오 |
+| Merge-on-read | 쿼리 또는 compaction 시점 | 높음 | 상대적으로 낮음 | 쓰기가 많고 읽기가 적은 시나리오 |
+
+## Merge-on-Write의 작동 방식 {#how-merge-on-write-works}
+
+merge-on-write 방식에서는 Doris가 데이터를 쓰는 시점에 중복 Key를 처리합니다. 새로 들어오는 각 행에 대해 해당 Key가 이미 존재하는지 확인하고, 기존 버전이 있으면 delete bitmap에 삭제된 것으로 표시합니다. 쿼리는 이 비트맵을 사용해 표시된 행을 건너뛰므로 최신 버전만 읽습니다. 이후 compaction 과정에서 해당 행이 디스크에서 제거됩니다.
+
+쓰기 시점에 중복을 처리하므로 다음과 같은 이점이 있습니다.
+
+- 쿼리는 Key마다 하나의 버전만 읽으며, 읽기 시점에 병합할 필요가 없습니다.
+- Doris는 필터를 스토리지 계층으로 푸시다운할 수 있으므로, 스캔 시 조건에 맞지 않는 데이터를 건너뜁니다.
+- 과거 업데이트가 누적되어도 읽기 성능이 저하되지 않습니다.
+
+대신 쓰기 측에 비용이 발생합니다. 각 upsert는 기본 키를 조회해 이전 버전을 찾아 표시하므로, merge-on-read에 비해 쓰기 오버헤드가 다소 늘어납니다. 대부분의 워크로드에서는 이러한 비용보다 이점이 크므로 merge-on-write가 기본값입니다.
+
+## Merge-on-Read의 작동 방식 {#how-merge-on-read-works}
+
+merge-on-read 방식에서는 쓰기 작업이 데이터를 추가하기만 합니다. Doris는 Key의 모든 버전을 유지하고, 쿼리 시점이나 compaction 과정에서 이를 병합해 최신 버전을 반환합니다.
+
+읽기 시점에 중복을 처리하므로 다음과 같은 특성이 있습니다.
+
+- 기본 키 조회를 생략하므로 쓰기 작업의 부담이 적습니다.
+- 모든 쿼리에서 각 Key의 버전을 병합해야 하고, Doris가 필터를 푸시다운할 수 없어 쿼리가 느려집니다.
+- compaction 사이에 버전이 누적될수록 쿼리 지연 시간이 늘어납니다.
+
+따라서 쿼리 속도보다 쓰기 처리량이 중요하고, 쓰기가 많으며 읽기가 적은 파이프라인에 적합합니다.
+
+## 선택 기준 {#choosing-between-them}
+
+- 실시간 업데이트, 차원 데이터 동기화 등 쿼리 성능이 중요한 경우를 포함한 대부분의 워크로드에는 **merge-on-write(기본값)를 사용하세요**. 이 방식은 부분 컬럼 업데이트와 같은 기능도 지원합니다.
+- 읽기보다 쓰기가 훨씬 많고 쓰기 오버헤드를 최소화해야 하는 경우에만 **merge-on-read를 사용하세요**.
+
+구현 방식은 테이블 생성 시 고정되며 **나중에 스키마 변경으로 바꿀 수 없으므로**, 테이블을 생성하기 전에 결정해야 합니다.
+
+## 각 구현 방식 활성화 {#enabling-each-implementation}
+
+`enable_unique_key_merge_on_write` 테이블 속성으로 구현 방식을 제어합니다.
+
+Merge-on-write(기본값):
+
+```sql
+CREATE TABLE IF NOT EXISTS example_tbl_unique
+(
+ user_id LARGEINT NOT NULL,
+ user_name VARCHAR(50) NOT NULL,
+ city VARCHAR(20),
+ age SMALLINT,
+ sex TINYINT
+)
+UNIQUE KEY(user_id, user_name)
+DISTRIBUTED BY HASH(user_id) BUCKETS 10
+PROPERTIES (
+ "enable_unique_key_merge_on_write" = "true"
+);
+```
+
+Merge-on-read(속성을 `false`로 설정):
+
+```sql
+CREATE TABLE IF NOT EXISTS example_tbl_unique
+(
+ user_id LARGEINT NOT NULL,
+ user_name VARCHAR(50) NOT NULL,
+ city VARCHAR(20),
+ age SMALLINT,
+ sex TINYINT
+)
+UNIQUE KEY(user_id, user_name)
+DISTRIBUTED BY HASH(user_id) BUCKETS 10
+PROPERTIES (
+ "enable_unique_key_merge_on_write" = "false"
+);
+```
+
+## Merge-on-Write가 필요한 기능 {#capabilities-that-require-merge-on-write}
+
+[부분 컬럼 업데이트](../../data-operate/update/update-of-unique-model)에는 merge-on-write가 필요합니다. 이 기능은 전체 행을 다시 쓰지 않고 일부 컬럼만 업데이트합니다.
+
+## 관련 문서 {#related}
+
+- [Unique Key 모델](./unique)
+- [부분 컬럼 업데이트](../../data-operate/update/update-of-unique-model)
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-model/tips.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-model/tips.md
new file mode 100644
index 00000000000..1261ec910ee
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-model/tips.md
@@ -0,0 +1,201 @@
+---
+{
+ "title": "테이블 모델 모범 사례",
+ "language": "ko",
+ "description": "Doris 데이터 모델 선택 권장 사항, 테이블 생성 시 열 유형 규칙, Aggregate 모델의 count(*) 제한 사항, Unique 모델의 merge-on-write 최적화, Key 열의 의미 차이에 대한 상세 설명."
+}
+---
+
+<!-- Knowledge type: Architecture selection decision + Configuration parameters + Performance tuning -->
+<!-- Applicable scenarios: Model selection before table creation / Understanding data models / count(*) performance optimization -->
+
+이 문서에서는 모델 선택, 테이블 스키마 설계, 모델의 제한 사항이라는 관점에서 Doris 데이터 모델을 사용할 때 주의해야 할 사항을 설명합니다. 적합한 모델을 선택하고 흔히 발생하는 성능 문제를 피하는 데 도움이 됩니다.
+
+## 데이터 모델 선택 권장 사항 {#data-model-selection-recommendations}
+
+데이터 모델은 테이블 생성 시 결정되며 **수정할 수 없습니다**. 따라서 적합한 데이터 모델을 선택하는 것이 매우 중요합니다.
+
+### 세 가지 모델 비교 {#comparison-of-the-three-models}
+
+| 데이터 모델 | 적용 시나리오 | 장점 | 참고 사항 |
+| ---------- | ------------------------------- | --------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
+| Duplicate | 모든 차원에 대한 애드혹 쿼리 | 집계 모델의 제약을 받지 않으며, 필요한 열만 읽는 열 기반 스토리지의 이점을 최대한 활용 | 사전 집계를 활용할 수 없음(단, 비동기 구체화된 뷰를 통해 지원 가능) |
+| Unique | 기본 키의 고유성과 데이터 업데이트가 필요한 경우 | 기본 키의 고유성을 보장하고 유연한 업데이트 지원 | 사전 집계를 활용할 수 없음(단, 비동기 구체화된 뷰를 통해 지원 가능) |
+| Aggregate | 패턴이 고정된 보고서 쿼리 | 사전 집계로 쿼리 시 스캔하고 계산하는 데이터양을 크게 줄임 | `count(*)` 쿼리에 비효율적이며, 선언된 집계 유형과 다른 집계 쿼리를 실행할 때 의미적 정확성에 주의해야 함 |
+
+### 부분 열 업데이트 요구 사항 {#partial-column-update-requirements}
+
+업무상 부분 열 업데이트가 필요하다면 다음 문서에서 사용 권장 사항을 확인하세요.
+
+- [Unique 모델의 부분 열 업데이트](../../data-operate/update/update-of-unique-model)
+- [Aggregate 모델의 부분 열 업데이트](../../data-operate/update/update-of-aggregate-model)
+
+## 테이블 생성 시 열 유형 권장 사항 {#recommendations-for-column-types-when-creating-tables}
+
+<!-- Knowledge type: Configuration parameters -->
+
+테이블을 생성할 때 열 유형과 순서에 대해 다음 규칙을 따르세요.
+
+1. **열 순서**: Key 열은 모든 Value 열보다 앞에 와야 합니다.
+2. **정수형 우선 사용**: 정수 연산과 조회는 문자열보다 훨씬 효율적이므로 가능하면 정수형을 사용하세요.
+3. **요구 사항을 충족하는 가장 작은 정수 길이 사용**: 길이가 다른 정수형 중에서 선택할 때는 필요한 만큼만 사용한다는 원칙을 따르세요.
+4. **요구 사항을 충족하는 가장 작은 가변 길이 문자열 사용**: VARCHAR 및 STRING 유형의 길이에도 필요한 만큼만 사용한다는 동일한 원칙을 적용하세요.
+
+## 모델별 Key 열의 의미 차이 {#semantic-differences-of-key-columns-across-models}
+
+<!-- Knowledge type: Architecture selection decision -->
+
+Duplicate, Aggregate, Unique 모델은 모두 테이블 생성 시 Key 열을 지정하지만, 그 의미는 서로 다릅니다.
+
+| 모델 | Key 열의 역할 |
+| ------------------ | ------------------------------------------------------------- |
+| Duplicate | "정렬 열"로만 사용되며, 고유 식별 기능은 제공하지 않음 |
+| Aggregate, Unique | "정렬 열"과 "고유 식별 열"의 역할을 모두 수행하며, 진정한 의미의 Key 열에 해당함 |
+
+## Aggregate 모델의 제한 사항 {#limitations-of-the-aggregate-model}
+
+<!-- Knowledge type: Performance tuning -->
+<!-- Applicable scenarios: Performance troubleshooting / count(*) query optimization -->
+
+Aggregate 모델은 최종 집계된 데이터를 외부에 제공합니다. 즉, **아직 집계되지 않은 모든 데이터**(예: 서로 다른 두 데이터 적재 배치에 속한 데이터)는 외부에 제공하기 전에 특정 메커니즘을 통해 일관성을 확보해야 합니다.
+
+### 일관성 보장 예시 {#example-of-consistency-guarantees}
+
+다음과 같은 테이블 스키마가 있다고 가정합니다.
+
+| 열 이름 | 유형 | 집계 유형 | 설명 |
+| ---------- | -------- | --------------- | ------------- |
+| user_id | LARGEINT | | 사용자 ID |
+| date | DATE | | 데이터 적재 날짜 |
+| cost | BIGINT | SUM | 사용자 총 지출액 |
+
+스토리지 엔진에는 이미 두 데이터 적재 배치의 데이터가 저장되어 있습니다.
+
+**배치 1**
+
+| user_id | date | cost |
+| ------- | ---------- | ---- |
+| 10001 | 2017/11/20 | 50 |
+| 10002 | 2017/11/21 | 39 |
+
+**배치 2**
+
+| user_id | date | cost |
+| ------- | ---------- | ---- |
+| 10001 | 2017/11/20 | 1 |
+| 10001 | 2017/11/21 | 5 |
+| 10003 | 2017/11/22 | 22 |
+
+위에서 볼 수 있듯이, 두 데이터 적재 배치에 걸쳐 있는 사용자 10001의 데이터는 아직 집계되지 않았습니다. 사용자에게는 아래와 같이 최종 집계된 데이터만 보여야 합니다.
+
+| user_id | date | cost |
+| ------- | ---------- | ---- |
+| 10001 | 2017/11/20 | 51 |
+| 10001 | 2017/11/21 | 5 |
+| 10002 | 2017/11/21 | 39 |
+| 10003 | 2017/11/22 | 22 |
+
+이를 위해 Doris는 쿼리 엔진에 집계 연산자를 추가하여 외부에 제공하는 데이터의 일관성을 보장합니다.
+
+### 집계 유형이 일치하지 않는 쿼리의 의미적 함정 {#semantic-pitfall-of-inconsistent-aggregation-queries}
+
+Value 열에 대해 **선언된 유형과 다른 집계 유형**으로 집계 쿼리를 실행할 때는 의미에 주의해야 합니다. 예를 들면 다음과 같습니다.
+
+```sql
+SELECT MIN(cost) FROM table;
+```
+
+결과는 `5`이며, `1`이 아닙니다.
+
+### count(*) 쿼리 오버헤드 {#count-query-overhead}
+
+Aggregate 모델의 일관성 보장 메커니즘은 특정 쿼리의 효율을 크게 떨어뜨립니다. 가장 대표적인 사례는 `count(*)` 쿼리입니다.
+
+```sql
+SELECT COUNT(*) FROM table;
+```
+
+다른 데이터베이스에서는 이러한 쿼리가 매우 빠르게 결과를 반환합니다. "데이터 적재 중 행 수를 세어 통계로 저장"하거나 "쿼리 시 열 하나만 스캔하여 개수를 계산"하는 방식으로 아주 적은 오버헤드만으로 결과를 얻을 수 있습니다. 하지만 Doris의 Aggregate 모델에서는 이 쿼리의 비용이 매우 큽니다.
+
+앞서 살펴본 데이터를 예로 들면, 최종 집계 결과는 다음과 같습니다.
+
+| user_id | date | cost |
+| ------- | ---------- | ---- |
+| 10001 | 2017/11/20 | 51 |
+| 10001 | 2017/11/21 | 5 |
+| 10002 | 2017/11/21 | 39 |
+| 10003 | 2017/11/22 | 22 |
+
+`SELECT COUNT(*) FROM table;`의 올바른 결과는 `4`여야 합니다. 하지만 다음과 같은 문제가 있습니다.
+
+- `user_id` 열만 스캔하고 쿼리 시점에 집계하면 `3`(10001, 10002, 10003)이 반환되므로 올바르지 않습니다.
+- `user_id` 열만 스캔하고 쿼리 시점에 집계하지 않으면 `5`(두 배치에 걸쳐 총 5행)가 반환되므로 올바르지 않습니다.
+
+올바른 결과를 얻으려면 **`user_id` 열과 `date` 열을 모두 읽고**, 쿼리 시점에 집계해야 올바른 결과인 `4`를 반환할 수 있습니다. 즉, `count(*)` 쿼리에서 *Doris는 의미적으로 올바른 결과를 얻기 위해 모든 AGGREGATE KEY 열(여기서는 `user_id`와 `date`)을 스캔하고 집계해야 합니다*. 집계 열이 많으면 `count(*)` 쿼리가 많은 양의 데이터를 스캔해야 합니다.
+
+### count(*) 성능 최적화 {#count-performance-optimization}
+
+워크로드에서 `count(*)` 쿼리를 자주 실행한다면, **값이 항상 1이고 집계 유형이 SUM인** 열을 추가하여 `count(*)`를 대신할 수 있습니다. 앞선 예시의 테이블 스키마를 다음과 같이 수정합니다.
+
+| 열 이름 | 유형 | 집계 유형 | 설명 |
+| ---------- | ------ | ------------- | -------------------- |
+| user_id | BIGINT | | 사용자 ID |
+| date | DATE | | 데이터 적재 날짜 |
+| cost | BIGINT | SUM | 사용자 총 지출액 |
+| count | BIGINT | SUM | 개수 계산에 사용 |
+
+데이터를 적재할 때 `count` 열의 값을 상수 1로 설정합니다. 그러면 다음과 같습니다.
+
+```sql
+SELECT COUNT(*) FROM table;
+-- equivalent to
+SELECT SUM(count) FROM table;
+```
+
+후자가 전자보다 훨씬 효율적입니다.
+
+**사용 제한 사항**: AGGREGATE KEY 열의 값이 동일한 행이 여러 번 적재되지 않도록 해야 합니다. 그렇지 않으면 `SELECT SUM(count) FROM table;`는 적재한 원본 행의 수만 나타내며, 더 이상 `SELECT COUNT(*) FROM table;`와 동등하지 않습니다.
+
+**대안**: 위의 `count` 열의 집계 유형을 `REPLACE`로 변경하고, 값은 계속 상수 1로 유지합니다. 이 경우 `SELECT SUM(count) FROM table;`와 `SELECT COUNT(*) FROM table;`는 동일한 결과를 반환하며, 중복 행의 데이터 적재에도 제한이 없습니다.
+
+## Unique 모델의 merge-on-write 구현 {#merge-on-write-implementation-of-the-unique-model}
+
+<!-- Knowledge type: Performance tuning -->
+
+Unique 모델의 merge-on-write 구현에는 앞서 설명한 Aggregate 모델의 제한 사항이 없습니다. 앞서 사용한 동일한 데이터를 예로 들면, merge-on-write는 각 데이터 적재의 rowset에 해당하는 delete bitmap을 추가하여 덮어쓴 데이터를 표시합니다.
+
+**첫 번째 배치 적재 후**:
+
+배치 1
+
+| user_id | date | cost | 삭제 비트 |
+| ------- | ---------- | ---- | ---------- |
+| 10001 | 2017/11/20 | 50 | FALSE |
+| 10002 | 2017/11/21 | 39 | FALSE |
+
+**두 번째 배치 적재 후**, 첫 번째 배치의 중복 행은 삭제된 것으로 표시됩니다.
+
+배치 1
+
+| user_id | date | cost | 삭제 비트 |
+| ------- | ---------- | ---- | ---------- |
+| 10001 | 2017/11/20 | 50 | TRUE |
+| 10002 | 2017/11/21 | 39 | FALSE |
+
+배치 2
+
+| user_id | date | cost | 삭제 비트 |
+| ------- | ---------- | ---- | ---------- |
+| 10001 | 2017/11/20 | 1 | FALSE |
+| 10001 | 2017/11/21 | 5 | FALSE |
+| 10003 | 2017/11/22 | 22 | FALSE |
+
+쿼리 시점에는 delete bitmap에서 삭제된 것으로 표시된 모든 행을 필터링하며, **데이터 집계가 필요하지 않습니다**. 위 데이터에는 유효한 행이 4개 있으며, 쿼리 결과도 4행입니다. 따라서 앞서 언급한 "열 하나만 스캔하여 개수를 계산"하는, 오버헤드가 가장 적은 방식을 사용할 수 있습니다.
+
+**성능 데이터**: 테스트 환경에서 Unique 모델의 merge-on-write 구현에 대한 `count(*)` 쿼리는 Aggregate 모델보다 성능이 **10배 넘게** 높습니다.
+
+## Duplicate 모델 {#duplicate-model}
+
+<!-- Knowledge type: Architecture selection decision -->
+
+Duplicate 모델에는 앞서 설명한 Aggregate 모델의 제한 사항이 없습니다. 이 모델에는 집계 의미가 적용되지 않으므로, `count(*)` 쿼리는 **임의의 단일 열**을 스캔하여 의미적으로 올바른 결과를 얻을 수 있습니다.
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-model/unique.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-model/unique.md
new file mode 100644
index 00000000000..4a51b9ab790
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-model/unique.md
@@ -0,0 +1,93 @@
+---
+{
+ "title": "Unique Key 모델",
+ "language": "ko",
+ "description": "Doris Unique Key 모델은 Key 컬럼의 고유성을 보장하며 UPSERT와 중복 제거를 지원합니다. 빈번한 업데이트, 차원 데이터 동기화, 프로필 태깅과 같은 데이터 업데이트 시나리오에 적합합니다."
+}
+---
+
+Unique Key 모델은 Key 컬럼의 고유성을 유지합니다. 행을 삽입하거나 업데이트하면 새 데이터가 동일한 Key를 가진 기존 행을 덮어쓰므로 테이블에는 항상 최신 버전이 유지됩니다. 기본 키를 기준으로 데이터를 업데이트할 때 사용하세요.
+
+<!-- Knowledge type: Data model -->
+<!-- Applicable scenarios: Data update / High-frequency writes / Primary key deduplication -->
+
+## 사용 시나리오 {#when-to-use}
+
+Unique Key 모델은 다음 세 가지 주요 시나리오에 적합합니다.
+
+1. **빈번한 데이터 업데이트**: 업스트림 OLTP 데이터베이스의 차원 테이블을 실시간으로 동기화하는 경우로, 효율적인 UPSERT 연산이 필요합니다.
+2. **효율적인 데이터 중복 제거**: 광고 게재, 고객 관계 관리(CRM) 등의 시스템에서 사용자 ID를 기준으로 레코드의 중복을 제거합니다.
+3. **일부 컬럼 업데이트**: 동적 태그가 자주 바뀌는 프로필 태깅이나 거래 상태가 바뀌는 주문 처리 시나리오에서 영향을 받는 컬럼만 업데이트할 수 있습니다.
+
+## Unique Key 테이블 생성 {#create-a-unique-key-table}
+
+`UNIQUE KEY` 키워드로 기본 키를 선언합니다. Merge-on-write는 기본적으로 활성화되어 있으며 거의 모든 워크로드에 적합하므로 추가 속성을 지정할 필요가 없습니다.
+
+```sql
+CREATE TABLE IF NOT EXISTS example_tbl_unique
+(
+ user_id LARGEINT NOT NULL,
+ user_name VARCHAR(50) NOT NULL,
+ city VARCHAR(20),
+ age SMALLINT,
+ sex TINYINT
+)
+UNIQUE KEY(user_id, user_name)
+DISTRIBUTED BY HASH(user_id) BUCKETS 10;
+```
+
+각 행은 `(user_id, user_name)`으로 식별됩니다. 이미 존재하는 Key를 가진 행을 쓰면 기존 행을 덮어쓰고, 새로운 Key를 가진 행을 쓰면 삽입합니다.
+
+## 데이터 UPSERT {#upsert-data}
+
+Doris는 어떤 데이터 적재 방식을 사용하든 Key를 기준으로 UPSERT를 수행합니다. 기존 Key를 가진 행은 업데이트하고, 새로운 Key를 가진 행은 삽입합니다. Doris는 정렬과 중복 제거 모두에 Key 컬럼을 사용합니다. 아래 예시에서는 `INSERT`를 사용하며, Stream Load, Broker Load, Routine Load도 동일하게 동작합니다.
+
+
+
+다음 예시에서 원래 테이블에는 4개의 행이 있습니다. 기존 Key를 가진 2개의 행을 다시 삽입하면 해당 행이 업데이트됩니다.
+
+```sql
+-- Insert original data
+INSERT INTO example_tbl_unique VALUES
+(101, 'Tom', 'BJ', 26, 1),
+(102, 'Jason', 'BJ', 27, 1),
+(103, 'Juice', 'SH', 20, 2),
+(104, 'Olivia', 'SZ', 22, 2);
+
+-- Re-insert the same Keys with new values
+INSERT INTO example_tbl_unique VALUES
+(101, 'Tom', 'BJ', 27, 1),
+(102, 'Jason', 'SH', 28, 1);
+
+-- Query the updated data
+SELECT * FROM example_tbl_unique;
++---------+-----------+------+------+------+
+| user_id | user_name | city | age | sex |
++---------+-----------+------+------+------+
+| 101 | Tom | BJ | 27 | 1 |
+| 102 | Jason | SH | 28 | 1 |
+| 104 | Olivia | SZ | 22 | 2 |
+| 103 | Juice | SH | 20 | 2 |
++---------+-----------+------+------+------+
+```
+
+행 전체를 UPSERT할 때 `INSERT INTO`에 일부 컬럼만 지정하면 Doris가 나머지 컬럼을 NULL 또는 기본값으로 채웁니다.
+
+## 일부 컬럼만 업데이트 {#update-only-some-columns}
+
+행 전체를 다시 쓰지 않고 몇몇 필드만 변경하려면 부분 컬럼 업데이트를 사용하세요. 이 기능에는 기본 설정인 merge-on-write가 필요하며, 매개변수로 활성화합니다. [부분 컬럼 업데이트](../../data-operate/update/update-of-unique-model)를 참고하세요.
+
+## 구현 방식 선택 {#choose-an-implementation}
+
+Unique Key 모델에는 두 가지 스토리지 구현 방식이 있습니다. **merge-on-write**는 기본 방식으로 대부분의 워크로드에 권장되며, **merge-on-read**는 쓰기가 많고 읽기가 적은 파이프라인에 적합합니다. 구현 방식은 테이블을 생성할 때 결정되며, 이후 스키마 변경으로 바꿀 수 없습니다.
+
+각 방식의 동작 원리, 성능상의 장단점, merge-on-read 활성화 방법은 [Merge-on-Write](./merge-on-write)를 참고하세요.
+
+## 유의 사항 {#notes}
+
+Unique Key 모델을 사용할 때는 다음 제약 사항에 유의하세요.
+
+1. **구현 방식은 변경할 수 없음**: merge-on-write 또는 merge-on-read는 테이블을 생성할 때만 설정할 수 있으며, 스키마 변경으로 수정할 수 없습니다.
+2. **행 전체 UPSERT 시 기본값으로 채움**: `INSERT INTO`에 일부 컬럼만 지정하더라도 Doris는 지정하지 않은 컬럼을 NULL 또는 기본값으로 채웁니다.
+3. **부분 컬럼 업데이트에는 merge-on-write가 필요함**: 일부 컬럼만 업데이트하려면 merge-on-write를 사용하고 매개변수로 부분 컬럼 업데이트를 활성화하세요. [부분 컬럼 업데이트](../../data-operate/update/update-of-unique-model)를 참고하세요.
+4. **파티션 키는 Key 컬럼의 부분집합이어야 함**: Doris는 데이터의 고유성을 보장하기 위해 이 조건을 요구합니다.
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-partitioning/auto-partitioning.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-partitioning/auto-partitioning.md
new file mode 100644
index 00000000000..5bb554999fd
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-partitioning/auto-partitioning.md
@@ -0,0 +1,345 @@
+---
+{
+ "title": "자동 파티셔닝",
+ "language": "ko",
+ "description": "Doris의 자동 파티셔닝(AUTO PARTITION)은 데이터 적재 시 파티션 컬럼 값을 기준으로 RANGE 또는 LIST 파티션을 자동으로 생성하여, 불연속적인 데이터나 방대한 파티션 수로 인해 파티션을 미리 정의할 수 없는 문제를 해결합니다."
+}
+---
+
+<!-- Knowledge type: Feature / Procedure -->
+<!-- Use cases: Partitioned table design / Large-scale partition management / Data lifecycle management -->
+
+Doris의 자동 파티셔닝(AUTO PARTITION)은 데이터 적재 중 파티션 컬럼의 값에 따라 파티션을 자동으로 생성하는 기능입니다. 다음과 같은 문제를 해결합니다:
+
+- 파티션 컬럼의 데이터가 흩어져 있고 예측하기 어려워, 테이블 생성 시 필요한 파티션을 정확하게 나열할 수 없습니다.
+- 파티션 수가 너무 많아 수동으로 생성하기 어렵습니다.
+- 파티션 컬럼이 시스템 시간과 관련이 없어 동적 파티셔닝을 적용할 수 없습니다.
+
+Doris는 두 가지 유형의 자동 파티셔닝을 지원합니다:
+
+| 유형 | 파티셔닝 방식 | 파티션 함수 | 지원하는 파티션 컬럼 타입 |
+| --- | --- | --- | --- |
+| AUTO **RANGE** PARTITION | 범위별 자동 파티셔닝 | `date_trunc` | `DATE`, `DATETIME`, `TIMESTAMP_NS` |
+| AUTO **LIST** PARTITION | 열거 값별 자동 파티셔닝 | 함수 호출 미지원 | `BOOLEAN`, `TINYINT`, `SMALLINT`, `INT`, `BIGINT`, `LARGEINT`, `DATE`, `DATETIME`, `TIMESTAMP_NS`, `CHAR`, `VARCHAR` |
+
+## 사용 사례 {#use-cases}
+
+시간 타입의 파티션 컬럼을 예로 들어 보겠습니다:
+
+- 동적 파티셔닝을 사용하면 Doris가 일정한 시간 주기에 따라 새 파티션을 자동으로 생성하여 실시간 데이터를 저장할 수 있습니다. 실시간 사용자 행동 로그와 같은 시나리오에서는 일반적으로 이 기능만으로 요구 사항을 충족할 수 있습니다.
+- 하지만 더 복잡한 시나리오(예: 비실시간 데이터 처리)에서는 파티션 컬럼이 현재 시스템 시간과 관련이 없고, 불연속적인 값을 많이 포함할 수 있습니다. 이 컬럼을 기준으로 파티셔닝하려 해도 어떤 파티션이 필요한지 미리 알 수 없거나, 필요한 파티션 수가 너무 많을 수 있습니다.
+
+이러한 경우에는 동적 파티셔닝이나 수동 파티셔닝으로 요구 사항을 충족하기 어려우며, 자동 파티셔닝이 적합합니다.
+
+### 예시 시나리오: 거래 이력 테이블 {#example-scenario-trade-history-table}
+
+거래일을 기준으로 파티셔닝된 거래 이력 테이블이 있다고 가정해 보겠습니다. 수동 파티셔닝을 사용하는 경우 DDL은 일반적으로 다음과 같습니다:
+
+```sql
+CREATE TABLE `DAILY_TRADE_VALUE`
+(
+ `TRADE_DATE` datev2 NOT NULL COMMENT 'Trade date',
+ `TRADE_ID` varchar(40) NOT NULL COMMENT 'Trade ID',
+ ......
+)
+UNIQUE KEY(`TRADE_DATE`, `TRADE_ID`)
+PARTITION BY RANGE(`TRADE_DATE`)
+(
+ PARTITION p_2000 VALUES [('2000-01-01'), ('2001-01-01')),
+ PARTITION p_2001 VALUES [('2001-01-01'), ('2002-01-01')),
+ PARTITION p_2002 VALUES [('2002-01-01'), ('2003-01-01')),
+ PARTITION p_2003 VALUES [('2003-01-01'), ('2004-01-01')),
+ PARTITION p_2004 VALUES [('2004-01-01'), ('2005-01-01')),
+ PARTITION p_2005 VALUES [('2005-01-01'), ('2006-01-01')),
+ PARTITION p_2006 VALUES [('2006-01-01'), ('2007-01-01')),
+ PARTITION p_2007 VALUES [('2007-01-01'), ('2008-01-01')),
+ PARTITION p_2008 VALUES [('2008-01-01'), ('2009-01-01')),
+ PARTITION p_2009 VALUES [('2009-01-01'), ('2010-01-01')),
+ PARTITION p_2010 VALUES [('2010-01-01'), ('2011-01-01')),
+ PARTITION p_2011 VALUES [('2011-01-01'), ('2012-01-01')),
+ PARTITION p_2012 VALUES [('2012-01-01'), ('2013-01-01')),
+ PARTITION p_2013 VALUES [('2013-01-01'), ('2014-01-01')),
+ PARTITION p_2014 VALUES [('2014-01-01'), ('2015-01-01')),
+ PARTITION p_2015 VALUES [('2015-01-01'), ('2016-01-01')),
+ PARTITION p_2016 VALUES [('2016-01-01'), ('2017-01-01')),
+ PARTITION p_2017 VALUES [('2017-01-01'), ('2018-01-01')),
+ PARTITION p_2018 VALUES [('2018-01-01'), ('2019-01-01')),
+ PARTITION p_2019 VALUES [('2019-01-01'), ('2020-01-01')),
+ PARTITION p_2020 VALUES [('2020-01-01'), ('2021-01-01')),
+ PARTITION p_2021 VALUES [('2021-01-01'), ('2022-01-01'))
+)
+DISTRIBUTED BY HASH(`TRADE_DATE`) BUCKETS 10
+PROPERTIES (
+ "replication_num" = "1"
+);
+```
+
+이 방식에는 다음과 같은 문제가 있습니다:
+
+1. 테이블 생성 시 모든 파티션을 수동으로 나열해야 합니다.
+2. 파티션 컬럼의 값 범위가 변경되면(예: 2022년 데이터가 추가되는 경우) [ALTER-TABLE-PARTITION](../../sql-manual/sql-statements/table-and-view/table/ALTER-TABLE-PARTITION)을 통해 파티션을 수정해야 하므로 번거롭습니다.
+3. 파티션을 변경하거나 더 세분화해야 하는 경우 수정 비용이 큽니다.
+
+AUTO PARTITION을 사용하면 DDL을 다음과 같이 간소화할 수 있습니다:
+
+```sql
+CREATE TABLE `DAILY_TRADE_VALUE`
+(
+ `TRADE_DATE` datev2 NOT NULL,
+ `TRADE_ID` varchar(40) NOT NULL,
+ ......
+)
+UNIQUE KEY(`TRADE_DATE`, `TRADE_ID`)
+AUTO PARTITION BY RANGE (date_trunc(`TRADE_DATE`, 'year'))
+(
+)
+DISTRIBUTED BY HASH(`TRADE_DATE`) BUCKETS 10
+PROPERTIES (
+ "replication_num" = "1"
+);
+```
+
+새로 생성된 테이블에는 기본 파티션이 없습니다:
+
+```sql
+show partitions from `DAILY_TRADE_VALUE`;
+Empty set (0.12 sec)
+```
+
+데이터를 삽입하면 해당 파티션이 자동으로 생성됩니다:
+
+```sql
+insert into `DAILY_TRADE_VALUE` values ('2012-12-13', 1), ('2008-02-03', 2), ('2014-11-11', 3);
+
+show partitions from `DAILY_TRADE_VALUE`;
++-------------+-----------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+----------+------------+-------------------------+-----------+
+| PartitionId | PartitionName | VisibleVersion | VisibleVersionTime | State | PartitionKey | Range | DistributionKey | Buckets | ReplicationNum | StorageMedium | CooldownTime | RemoteStoragePolicy | LastConsistencyCheckTime | DataSize | IsInMemory | ReplicaAllocation | IsMutable |
++-------------+-----------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+----------+------------+-------------------------+-----------+
+| 180060 | p20080101000000 | 2 | 2023-09-18 21:49:29 | NORMAL | TRADE_DATE | [types: [DATEV2]; keys: [2008-01-01]; ..types: [DATEV2]; keys: [2009-01-01]; ) | TRADE_DATE | 10 | 1 | HDD | 9999-12-31 23:59:59 | | NULL | 0.000 | false | tag.location.default: 1 | true |
+| 180039 | p20120101000000 | 2 | 2023-09-18 21:49:29 | NORMAL | TRADE_DATE | [types: [DATEV2]; keys: [2012-01-01]; ..types: [DATEV2]; keys: [2013-01-01]; ) | TRADE_DATE | 10 | 1 | HDD | 9999-12-31 23:59:59 | | NULL | 0.000 | false | tag.location.default: 1 | true |
+| 180018 | p20140101000000 | 2 | 2023-09-18 21:49:29 | NORMAL | TRADE_DATE | [types: [DATEV2]; keys: [2014-01-01]; ..types: [DATEV2]; keys: [2015-01-01]; ) | TRADE_DATE | 10 | 1 | HDD | 9999-12-31 23:59:59 | | NULL | 0.000 | false | tag.location.default: 1 | true |
++-------------+-----------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+----------+------------+-------------------------+-----------+
+```
+
+자동 파티셔닝으로 생성한 파티션은 수동으로 생성한 파티션과 기능적으로 동일합니다.
+
+## 구문 {#syntax}
+
+테이블을 생성할 때 `partitions_definition` 부분에 다음 구문을 사용합니다([CREATE-TABLE](../../sql-manual/sql-statements/table-and-view/table/CREATE-TABLE)).
+
+### AUTO RANGE PARTITION {#auto-range-partition}
+
+```sql
+[AUTO] PARTITION BY RANGE(<partition_expr>)
+<origin_partitions_definition>
+```
+
+각 항목의 정의는 다음과 같습니다:
+
+```sql
+partition_expr ::= date_trunc(<partition_column>, '<interval>')
+```
+
+:::tip
+AUTO RANGE PARTITION에서는 `AUTO` 키워드를 생략해도 자동 파티셔닝의 의미가 유지됩니다.
+:::
+
+예시:
+
+```sql
+CREATE TABLE `date_table` (
+ `TIME_STAMP` datev2 NOT NULL
+) ENGINE=OLAP
+DUPLICATE KEY(`TIME_STAMP`)
+AUTO PARTITION BY RANGE (date_trunc(`TIME_STAMP`, 'month'))
+(
+)
+DISTRIBUTED BY HASH(`TIME_STAMP`) BUCKETS 10
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 1"
+);
+```
+
+### AUTO LIST PARTITION {#auto-list-partition}
+
+```sql
+AUTO PARTITION BY LIST(`partition_col1` [, `partition_col2`, ...])
+<origin_partitions_definition>
+```
+
+LIST 자동 파티셔닝은 다중 컬럼 파티셔닝을 지원하며, 구문은 일반 LIST 파티션과 동일합니다: `AUTO PARTITION BY LIST(`col1`, `col2`, ...)`. 파티션 컬럼의 값 중 해당하는 파티션이 아직 없는 각 값에 대해 독립적인 새 파티션이 생성됩니다.
+
+예시:
+
+```sql
+CREATE TABLE `str_table` (
+ `str` varchar not null
+) ENGINE=OLAP
+DUPLICATE KEY(`str`)
+AUTO PARTITION BY LIST (`str`)
+()
+DISTRIBUTED BY HASH(`str`) BUCKETS 10
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 1"
+);
+```
+
+### 제약 조건 비교 {#constraint-comparison}
+
+| 제약 조건 | AUTO RANGE PARTITION | AUTO LIST PARTITION |
+| --- | --- | --- |
+| 지원하는 파티션 함수 | `date_trunc`만 지원 | 함수 호출 미지원 |
+| 지원하는 파티션 컬럼 타입 | `DATE`, `DATETIME`, `TIMESTAMP_NS` | `BOOLEAN`, `TINYINT`, `SMALLINT`, `INT`, `BIGINT`, `LARGEINT`, `DATE`, `DATETIME`, `TIMESTAMP_NS`, `CHAR`, `VARCHAR` |
+| 다중 컬럼 파티셔닝 지원 여부 | 미지원 | 지원 |
+| 파티션 이름 길이 제한 | - | 50을 초과할 수 없음(파티션 컬럼 내용을 연결하고 이스케이프한 결과를 기준으로 하며, 실제 허용 길이는 더 짧을 수 있음) |
+| 파티션 값 규칙 | `date_trunc`로 절삭한 시간 범위에 따라 분할 | 기존 파티션이 없는 새로운 열거 값마다 독립적인 새 파티션 생성 |
+
+## NULL 값 파티셔닝 {#null-value-partitioning}
+
+세션 변수 `allow_partition_column_nullable`을 활성화하면 두 자동 파티셔닝 유형은 NULLABLE 컬럼 지원 여부에서 차이가 있습니다:
+
+| 자동 파티셔닝 유형 | NULLABLE 파티션 컬럼 지원 여부 |
+| --- | --- |
+| AUTO LIST PARTITION | 지원. NULL을 쓰면 NULL 파티션이 정상적으로 생성됩니다. |
+| AUTO RANGE PARTITION | 미지원 |
+
+### AUTO LIST PARTITION: NULLABLE 컬럼 지원 {#auto-list-partition-nullable-column-supported}
+
+```sql
+create table auto_null_list(
+ k0 varchar null
+)
+auto partition by list (k0)
+(
+)
+DISTRIBUTED BY HASH(`k0`) BUCKETS 1
+properties("replication_num" = "1");
+
+insert into auto_null_list values (null);
+
+select * from auto_null_list;
++------+
+| k0 |
++------+
+| NULL |
++------+
+
+select * from auto_null_list partition(pX);
++------+
+| k0 |
++------+
+| NULL |
++------+
+```
+
+### AUTO RANGE PARTITION: NULLABLE 컬럼 미지원 {#auto-range-partition-nullable-column-not-supported}
+
+```sql
+CREATE TABLE `range_table_nullable` (
+ `k1` INT,
+ `k2` DATETIMEV2(3),
+ `k3` DATETIMEV2(6)
+) ENGINE=OLAP
+DUPLICATE KEY(`k1`)
+AUTO PARTITION BY RANGE (date_trunc(`k2`, 'day'))
+()
+DISTRIBUTED BY HASH(`k1`) BUCKETS 16
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 1"
+);
+
+ERROR 1105 (HY000): errCode = 2, detailMessage = AUTO RANGE PARTITION doesn't support NULL column
+```
+
+## 수명 주기 관리 {#lifecycle-management}
+
+:::info
+Doris는 수명 주기 관리를 위해 자동 파티셔닝과 동적 파티셔닝을 함께 사용하는 방식을 지원하지만, 이 조합은 더 이상 권장하지 않습니다.
+:::
+
+AUTO RANGE PARTITION 테이블에서는 `partition.retention_count` 속성을 통해 과거 파티션의 수명 주기를 관리할 수 있습니다. 이 속성은 양의 정수 `N`을 받으며, **파티션 값이 가장 큰 과거 파티션 `N`개만 유지**한다는 의미입니다. 현재 및 미래 파티션은 모두 유지됩니다.
+
+사용 제약 사항:
+
+- AUTO RANGE PARTITION 테이블에서만 이 속성을 설정할 수 있습니다. 다른 테이블에서 설정하면 `Only AUTO RANGE PARTITION table could set partition.retention_count` 오류와 함께 구문 실행이 실패합니다.
+- **이미 활성화된 동적 파티셔닝과 함께 사용할 수 없습니다**(`dynamic_partition.enable = true`). 함께 사용하면 `Can not use partition.retention_count and dynamic_partition properties at the same time` 오류와 함께 구문 실행이 실패합니다. 동적 파티셔닝을 통한 파티션 생성과 보존 개수에 따른 파티션 정리는 상호 배타적인 스케줄링 모드입니다. 이 제한은 버전 4.1.4부터 컴퓨팅과 스토리지가 결합된 모드 및 분리된 모드 모두에 적용됩니다.
+- 버전 4.1.4부터는 컴퓨팅과 스토리지가 분리된 모드에서도 `ALTER TABLE ... SET ("partition.retention_count" = "N")`으로 이 속성을 변경할 수 있습니다. 4.1.4 이전에는 컴퓨팅과 스토리지가 분리된 모드에서 해당 `ALTER`가 거부되거나 아무런 효과가 없었습니다.
+
+### 개념 정의 {#concept-definitions}
+
+- **과거 파티션**: 상한이 현재 시간보다 작거나 같은 파티션입니다.
+- **현재 및 미래 파티션**: 하한이 현재 시간보다 크거나 같은 파티션입니다.
+- **파티션 값 비교**: RANGE 파티션은 서로 겹치지 않으므로, "파티션 A의 값이 파티션 B의 값보다 크다"는 "파티션 A의 하한이 파티션 B의 상한보다 크다"와 같으며, "파티션 A의 상한이 파티션 B의 상한보다 크다"와도 같습니다.
+
+### 예시 {#example}
+
+```sql
+create table auto_recycle(
+ k0 datetime(6) not null
+)
+AUTO PARTITION BY RANGE (date_trunc(k0, 'day')) ()
+DISTRIBUTED BY HASH(`k0`) BUCKETS 1
+properties(
+ "partition.retention_count" = "3"
+);
+```
+
+이 설정은 날짜 값이 가장 큰 과거 파티션 3개만 유지한다는 의미입니다. 현재 날짜가 `2025-10-21`이고 `2025-10-16`부터 `2025-10-23`까지 매일 데이터가 삽입된다고 가정해 보겠습니다. 한 차례 정리가 수행되면 아래와 같이 6개의 파티션이 남습니다:
+
+
+
+남은 파티션 목록:
+
+- p20251018000000
+- p20251019000000
+- p20251020000000 (이 파티션과 그 위의 파티션: 과거 파티션 세 개만 유지)
+- p20251021000000 (이 파티션과 그 아래의 파티션: 현재 및 미래 파티션은 영향을 받지 않음)
+- p20251022000000
+- p20251023000000
+
+## 자동 버킷팅과 함께 사용 {#used-together-with-auto-bucketing}
+
+AUTO RANGE PARTITION만 [자동 버킷팅](./data-bucketing.md#2-automatically-set-the-number-of-buckets) 기능과 함께 사용할 수 있습니다.
+
+이 조합을 사용할 때 Doris는 데이터가 시간 순서대로 테이블에 증분 적재되고, 각 데이터 적재에는 하나의 파티션만 포함된다고 가정합니다. 따라서 **이 조합은 배치 단위로 증분 적재하는 테이블에만 권장합니다**.
+
+:::warning 참고
+데이터 적재 패턴이 위 방식을 따르지 않는 상태에서 자동 파티셔닝과 자동 버킷팅을 함께 사용하면, 새 파티션의 버킷 수가 매우 부적절하게 설정되어 쿼리 성능에 큰 영향을 줄 수 있습니다.
+:::
+
+## 파티션 관리 {#partition-management}
+
+자동 파티셔닝을 활성화한 후에는 다음 두 도구로 파티션을 정확하게 찾을 수 있습니다:
+
+- `auto_partition_name` 함수: 파티션 컬럼 값을 파티션 이름에 매핑합니다.
+- `partitions` 테이블 함수: 파티션 이름으로 파티션의 상세 정보를 조회합니다.
+
+앞서 사용한 `DAILY_TRADE_VALUE` 테이블에 데이터를 삽입한 후, 특정 레코드가 속한 파티션을 쿼리합니다:
+
+```sql
+select * from partitions("catalog"="internal","database"="optest","table"="DAILY_TRADE_VALUE") where PartitionName = auto_partition_name('range', 'year', '2008-02-03');
++-------------+-----------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+-----------+------------+-------------------------+-----------+--------------------+--------------+
+| PartitionId | PartitionName | VisibleVersion | VisibleVersionTime | State | PartitionKey | Range | DistributionKey | Buckets | ReplicationNum | StorageMedium | CooldownTime | RemoteStoragePolicy | LastConsistencyCheckTime | DataSize | IsInMemory | ReplicaAllocation | IsMutable | SyncWithBaseTables | UnsyncTables |
++-------------+-----------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+-----------+------------+-------------------------+-----------+--------------------+--------------+
+| 127095 | p20080101000000 | 2 | 2024-11-14 17:29:02 | NORMAL | TRADE_DATE | [types: [DATEV2]; keys: [2008-01-01]; ..types: [DATEV2]; keys: [2009-01-01]; ) | TRADE_DATE | 10 | 1 | HDD | 9999-12-31 23:59:59 | | \N | 985.000 B | 0 | tag.location.default: 1 | 1 | 1 | \N |
++-------------+-----------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+-----------+------------+-------------------------+-----------+--------------------+--------------+
+```
+
+이 방법을 사용하면 각 파티션의 ID와 값을 정확하게 선택하여 이후 파티션별 작업(예: `insert overwrite partition`)에 활용할 수 있습니다.
+
+자세한 구문:
+
+- [auto_partition_name 함수 참조](../../sql-manual/sql-functions/scalar-functions/string-functions/auto-partition-name)
+- [partitions 테이블 함수 참조](../../sql-manual/sql-functions/table-valued-functions/partitions)
+
+## 참고 사항 {#notes}
+
+| 참고 사항 | 설명 |
+| --- | --- |
+| 다중 컬럼 파티셔닝 지원 | AUTO LIST PARTITION은 다중 컬럼 파티셔닝을 지원하며, 구문은 일반 LIST 파티션과 동일합니다. |
+| 실패한 데이터 적재에서 생성된 파티션은 자동으로 정리되지 않음 | 데이터 삽입 또는 적재 중 파티션이 생성되었지만 전체 데이터 적재가 완료되지 않은 경우(실패하거나 취소된 경우), 생성된 파티션은 자동으로 삭제되지 않습니다. |
+| 일반 파티션과 동일한 사용 방식 | AUTO PARTITION을 사용하는 테이블에서는 파티션 생성 방식만 수동에서 자동으로 바뀝니다. 테이블과 파티션의 나머지 사용 방식은 AUTO PARTITION을 사용하지 않는 테이블과 동일합니다. |
+| 최대 파티션 수 제한 | 테이블당 최대 파티션 수는 `max_auto_partition_num`으로 제어하며, 이 항목은 [FE 구성](../../admin-manual/config/fe-config)에서 설정합니다. 실수로 너무 많은 파티션이 생성되지 않도록 필요에 따라 조정하세요. |
+| 데이터 전송 폴링 간격 | AUTO PARTITION 테이블에 데이터를 적재할 때 Coordinator가 데이터를 전송하는 폴링 간격은 일반 테이블과 다릅니다. 이 간격은 `olap_table_sink_send_interval_auto_partition_factor`로 제어하며, [BE 구성](../../admin-manual/config/be-config)에서 설정합니다. sink-node memtable을 활성화하면(`enable_memtable_on_sink_node = true`) 이 변수는 적용되지 않습니다. |
+| INSERT OVERWRITE 동작 | [insert-overwrite](../../sql-manual/sql-statements/data-modification/DML/INSERT-OVERWRITE)로 데이터를 삽입할 때 AUTO PARTITION 테이블이 어떻게 동작하는지는 INSERT OVERWRITE 문서를 참조하세요. |
+| 메타데이터 충돌로 인한 데이터 적재 실패 가능성 | 데이터 적재 중 파티션을 생성할 때 테이블에서 다른 메타데이터 작업(예: Schema Change 또는 Rebalance)이 진행 중이면 데이터 적재가 실패할 수 있습니다. |
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-partitioning/basic-concepts.mdx b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-partitioning/basic-concepts.mdx
new file mode 100644
index 00000000000..2418d7320f3
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-partitioning/basic-concepts.mdx
@@ -0,0 +1,304 @@
+---
+{
+ "title": "파티셔닝과 버키팅의 작동 방식",
+ "sidebar_label": "작동 방식",
+ "language": "ko",
+ "description": "Doris 파티셔닝과 버키팅의 기반이 되는 데이터 분산 모델을 설명합니다. 파티션, 버킷, Tablet, 노드뿐 아니라 고급 파티션 및 버킷 모드, 설계 권장 사항, 운영 지침도 다룹니다."
+}
+---
+
+
+{/* Knowledge type: Concept introduction / Procedure */}
+{/* Applicable scenarios: Table design / Data organization and management */}
+
+이 페이지에서는 Doris가 데이터를 파티션, 버킷, Tablet에 분산하는 방식을 설명합니다. 고급 파티션 및 버킷 모드, 설계 권장 사항, 운영 명령도 다룹니다. 권장 초기 구성과 선택 기준은 [파티셔닝과 버키팅](./overview)에서 먼저 확인하고, 기반 모델을 이해하고 싶을 때 이 페이지를 읽어 보세요.
+
+## 1. 개요 {#1-overview}
+
+Doris는 테이블의 데이터를 **파티션**과 **버킷**이라는 두 단계로 나누어 클러스터에 분산합니다.
+
+- **파티션**: 시간이나 지역 같은 컬럼 값을 기준으로 테이블을 더 작은 부분집합으로 수평 분할하여 쿼리 프루닝과 데이터 수명 주기 관리를 쉽게 합니다.
+- **버킷**: 각 파티션의 데이터를 여러 데이터 샤드(Tablet)에 균등하게 분산하여 클러스터의 병렬 처리 능력을 충분히 활용합니다.
+
+
+
+데이터 흐름은 다음과 같이 요약할 수 있습니다.
+
+```
+Table ──► Partition ──► Bucket ──► Tablet (data shard, stored on BE nodes)
+```
+
+파티셔닝과 버키팅을 잘 설계하면 **더 빠른 쿼리**(파티션 프루닝과 병렬 스캔), **더 쉬운 관리**(시간 기준 보관 또는 정리), **더 균등한 쓰기**(핫스팟 위험 감소)라는 세 가지 이점을 동시에 얻을 수 있습니다.
+
+## 2. 핵심 개념 {#2-core-concepts}
+
+### 2.1 테이블 구조: 행과 컬럼 {#21-table-structure-rows-and-columns}
+
+Doris에서 데이터는 논리적으로 테이블 형태로 표현됩니다. 테이블은 행(Row)과 컬럼(Column)으로 구성됩니다.
+
+| 개념 | 설명 |
+| ------- | --------------------------------- |
+| 행 | 사용자 데이터의 한 행 |
+| 컬럼 | 데이터 행의 각 필드를 나타냄 |
+
+컬럼은 다시 두 가지 유형으로 나눌 수 있습니다.
+
+| 컬럼 유형 | 비즈니스 매핑 | 설명 |
+| ----------- | ---------------- | ---------------------------------------------------------------------------------------------------------- |
+| Key 컬럼 | 차원 컬럼 | CREATE TABLE 문에서 `unique key`, `aggregate key` 또는 `duplicate key` 키워드 뒤에 지정하는 컬럼 |
+| Value 컬럼 | 지표 컬럼 | Key 컬럼 이외의 컬럼으로, 테이블 생성 시 집계 방식을 지정함 |
+
+Aggregate 모델에서는 Key 컬럼 값이 동일한 행을 하나의 행으로 집계하며, Value 컬럼의 집계 방식은 사용자가 테이블 생성 시 지정합니다. Aggregate 모델에 대한 자세한 내용은 [Doris 데이터 모델](../../table-design/data-model/intro.mdx)을 참조하세요.
+
+### 2.2 파티션 {#22-partition}
+
+파티션은 테이블의 특정 컬럼 값을 기준으로 데이터를 서로 겹치지 않는 더 작은 부분집합으로 나눕니다. 각 데이터 행은 반드시 하나의 특정 파티션에 속하며, 파티션은 가장 작은 논리적 관리 단위입니다.
+
+Doris는 두 가지 **파티션 유형**을 지원합니다.
+
+- **Range 파티션**: 숫자 또는 시간 범위로 분할하며, 주로 시계열 데이터에 사용합니다.
+- **List 파티션**: 열거된 값의 집합으로 분할하며, 주로 지역이나 범주 같은 이산 차원으로 데이터를 나눌 때 사용합니다.
+
+테이블 생성 시 파티션을 지정하지 않으면 Doris는 테이블의 모든 데이터를 포함하는 기본 파티션을 생성합니다. 이 파티션은 사용자에게 드러나지 않습니다.
+
+파티션을 잘 설계하면 다음과 같은 이점이 있습니다.
+
+- **더 빠른 쿼리**: 파티션 프루닝은 쿼리 조건에 맞지 않는 파티션을 건너뛰므로, Doris가 스캔하는 데이터와 I/O가 줄어듭니다. 데이터셋이 클수록 효과가 큽니다.
+- **더 쉬운 관리**: 시간이나 지역으로 분할하면 보관, 정리, 백업이 간단해집니다. 예를 들어 시간으로 파티셔닝하면 과거 데이터와 새로 들어오는 데이터를 별도로 관리할 수 있습니다.
+
+### 2.3 버킷 {#23-bucket}
+
+버키팅은 일정한 규칙에 따라 파티션 내 데이터를 서로 겹치지 않는 더 작은 데이터 단위로 나눕니다. 각 데이터 행은 반드시 하나의 특정 버킷에 속합니다.
+
+파티션은 컬럼 값의 범위나 목록에 따라 데이터를 나눕니다. 버키팅의 목적은 파티션 내 버킷에 데이터를 **균등하게** 분산하여 데이터 편향을 줄이고 병렬 스캔을 지원하는 것입니다. 실제 결과는 버키팅 방식과 키 값의 분포에 따라 달라집니다.
+
+Doris는 두 가지 **버키팅 방식**을 지원합니다.
+
+- **Hash 버키팅**: 버키팅 컬럼 값의 `crc32` 해시를 계산한 뒤 버킷 수로 나눈 나머지를 사용하여 데이터를 균등하게 분산합니다.
+- **Random 버키팅**: 데이터를 버킷에 무작위로 할당합니다. Random 버키팅을 사용할 때는 `load_to_single_tablet` 매개변수를 함께 사용하여 소규모 데이터를 빠르게 쓰도록 최적화할 수 있습니다.
+
+버키팅을 잘 설계하면 다음과 같은 이점이 있습니다.
+
+- **더 균등한 데이터 분산**: 적절한 버킷 키를 선택하면 데이터 편향과 노드 또는 디스크 간 부하 불균형의 위험을 줄일 수 있습니다.
+- **핫스팟 감소**: 작업을 여러 버킷에 분산하면 과부하를 줄이고 안정성을 높일 수 있습니다.
+- **더 높은 동시 처리 성능**: Doris는 동일한 파티션의 여러 버킷을 병렬로 읽어 처리량을 높입니다.
+
+### 2.4 Tablet과 노드 아키텍처 {#24-tablet-and-node-architecture}
+
+버킷은 물리적으로 **Tablet(데이터 샤드)**에 대응합니다. Tablet은 Doris에서 가장 작은 데이터 관리 단위이며, 데이터 이동과 복제 같은 작업의 기본 물리 단위이기도 합니다.
+
+Doris 클러스터는 두 가지 유형의 노드로 구성됩니다.
+
+- **FE 노드(Frontend)**: 테이블 및 Tablet 정보 같은 클러스터 메타데이터를 관리하며, SQL 파싱과 실행 계획 수립을 담당합니다.
+- **BE 노드(Backend)**: Tablet 데이터를 저장하고 연산 작업을 실행합니다. FE는 BE에서 나온 결과를 취합하여 사용자에게 반환합니다.
+
+데이터를 쓰고 쿼리할 때 파티션과 버킷은 다음과 같이 함께 작동합니다.
+
+- **데이터 쓰기**: 데이터 행은 먼저 파티셔닝 전략에 따라 해당 파티션에 할당된 다음, 버키팅 전략에 따라 파티션 내 특정 Tablet에 매핑됩니다.
+- **쿼리 실행**: FE 옵티마이저는 쿼리 조건을 기준으로 관련 없는 파티션과 버킷을 프루닝하여 스캔 범위를 최소화합니다. JOIN 또는 집계 쿼리에서는 노드 간 Shuffle이 발생할 수 있습니다. 파티셔닝과 버키팅을 적절히 설계하고 필요에 따라 [Colocate](#52-colocate)를 함께 사용하면 Shuffle 비용을 크게 줄일 수 있습니다.
+
+## 3. 첫 번째 CREATE TABLE 예제 {#3-the-first-create-table-example}
+
+Doris에서 테이블 생성은 동기식 명령입니다. SQL 문 실행이 완료되면 결과가 반환되며, 성공 결과가 반환되면 테이블이 생성된 것입니다. 전체 CREATE TABLE 구문은 [CREATE TABLE](../../sql-manual/sql-statements/table-and-view/table/CREATE-TABLE)을 참조하거나, `HELP CREATE TABLE`을 사용하여 추가 도움말을 확인하세요.
+
+다음은 Range 파티셔닝 + Hash 버키팅을 사용하는 최소 구성의 CREATE TABLE 예제입니다.
+
+```sql
+-- Range Partition
+CREATE TABLE example_range_tbl
+(
+ `user_id` LARGEINT NOT NULL COMMENT "User ID",
+ `date` DATE NOT NULL COMMENT "Data ingestion date",
+ `timestamp` DATETIME NOT NULL COMMENT "Data ingestion timestamp",
+ `city` VARCHAR(20) COMMENT "User's city",
+ `age` SMALLINT COMMENT "User age",
+ `sex` TINYINT COMMENT "User gender",
+ `last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "User's last visit time",
+ `cost` BIGINT SUM DEFAULT "0" COMMENT "Total user spending",
+ `max_dwell_time` INT MAX DEFAULT "0" COMMENT "Maximum user dwell time",
+ `min_dwell_time` INT MIN DEFAULT "99999" COMMENT "Minimum user dwell time"
+)
+PARTITION BY RANGE(`date`)
+(
+ PARTITION `p201701` VALUES LESS THAN ("2017-02-01"),
+ PARTITION `p201702` VALUES LESS THAN ("2017-03-01"),
+ PARTITION `p201703` VALUES LESS THAN ("2017-04-01"),
+ PARTITION `p2018` VALUES [("2018-01-01"), ("2019-01-01"))
+)
+DISTRIBUTED BY HASH(`user_id`) BUCKETS 16
+PROPERTIES
+(
+ "replication_num" = "1"
+);
+```
+
+**이 예제로 쓰기 및 쿼리 과정 이해하기**:
+
+- 쓰기 시 각 데이터 행은 먼저 `date`에 따라 해당 Range 파티션에 배치됩니다(예: `2017-02-15`는 `p201702`에 배치됨). 그런 다음 `user_id`의 해시 값에 따라 해당 파티션의 16개 Tablet 중 하나에 매핑됩니다.
+- 쿼리에 `WHERE date = '2017-02-15'` 조건이 있으면 옵티마이저는 `p201702` 파티션만 스캔합니다. 여기에 `user_id = 123` 조건도 추가하면 Tablet 하나만 조회합니다.
+
+## 4. 고급: 파티션 모드 {#4-advanced-partition-modes}
+
+Doris는 테이블 생성 시 파티션을 수동으로 선언하는 방식 외에도 시간 일정에 따른 자동 파티션 생성(Dynamic Partition)과 유입 데이터에 따른 필요 시 파티션 생성(Auto Partition)을 지원합니다. 세 가지 모드를 비교하면 다음과 같습니다.
+
+| 파티션 모드 | 파티션 생성 시점 | 적용 시나리오 |
+| -------------- | --------------------------------------- | ---------------------------------------------------------- |
+| 수동 파티션 | 테이블 생성 시 명시적으로 선언하거나 `ALTER`로 추가 | 파티션 구성이 안정적이며 세밀한 제어가 필요한 경우 |
+| 동적 파티션 | 시간 일정 규칙에 따라 시스템이 자동으로 생성하거나 회수 | 과거 N일/주/월의 롤링 파티션을 자동으로 유지하려는 시계열 데이터 |
+| 자동 파티션 | 데이터 쓰기 시 필요에 따라 생성 | 멀티 테넌트나 시간 값이 드문드문 들어오는 경우처럼 파티션 값을 예측할 수 없어 사전 생성을 피해야 하는 경우 |
+
+자동 파티셔닝과 동적 파티셔닝을 함께 사용하는 예제를 비롯해 각 모드에서 바로 사용할 수 있는 CREATE TABLE 예제는 [자동 파티셔닝](./auto-partitioning), [동적 파티셔닝](./dynamic-partitioning), [수동 파티셔닝](./manual-partitioning)을 참조하세요.
+
+## 5. 고급: 버키팅 {#5-advanced-bucketing}
+
+### 5.1 자동 버키팅 {#51-auto-bucketing}
+
+버킷 수를 얼마로 설정할지 확실하지 않다면 `BUCKETS AUTO`를 설정하여 Doris가 예상 데이터 크기(`estimate_partition_size`)를 기준으로 버킷 수를 결정하도록 할 수 있습니다. 이 방식은 매우 큰 테이블에는 적합하지 않습니다. 자세한 내용은 [데이터 버키팅](./data-bucketing)을 참조하세요.
+
+### 5.2 Colocate {#52-colocate}
+
+여러 대형 테이블에서 JOIN 또는 집계 쿼리를 자주 수행한다면 **Colocate** 전략을 활성화하여 버키팅 컬럼 값이 같은 데이터를 동일한 물리 노드에 배치할 수 있습니다. 이렇게 하면 노드 간 Shuffle을 피하고 쿼리 성능을 크게 높일 수 있습니다. 자세한 사용법은 Colocate Join 문서를 참조하세요.
+
+## 6. 설계 권장 사항 {#6-design-recommendations}
+
+파티셔닝과 버키팅을 적절히 설계하려면 쿼리 성능, 데이터 관리, 시스템 안정성 사이의 균형을 맞춰야 합니다. 다음은 일반적인 지침입니다.
+
+### 6.1 설계 목표 {#61-design-goals}
+
+1. **균등한 데이터 분산**: 카디널리티가 높은 컬럼을 버키팅 컬럼으로 선택하여 데이터 편향으로 일부 노드에 과부하가 걸리지 않도록 합니다.
+2. **쿼리 성능 최적화**: 파티션 프루닝은 스캔할 데이터양을 크게 줄이고, 적절한 버킷 수는 연산 병렬성을 높입니다. 필요에 따라 Colocate를 사용하여 Shuffle 비용을 줄이세요.
+3. **유연한 데이터 관리**: 시간으로 파티셔닝하면 콜드/핫 계층화(HDD/SSD)가 쉬워지며, 과거 파티션을 삭제하여 저장 공간을 회수할 수 있습니다.
+
+### 6.2 경험적 권장값과 한도 {#62-empirical-values-and-limits}
+
+- **메타데이터 규모**: 각 Tablet의 메타데이터는 FE와 BE 모두에 저장되므로 규모를 적절히 제어해야 합니다.
+ - Tablet 10백만 개당 FE에 최소 약 100 GB의 메모리가 필요합니다.
+ - 단일 BE가 담당하는 Tablet 수는 20,000개 미만이어야 합니다.
+- **쓰기 처리량**:
+ - 파티션당 버킷 수는 128개 미만을 권장합니다. 버킷이 너무 많으면 쓰기 성능에 큰 영향을 줍니다.
+ - 쓰기가 분산되어 작은 파일이 너무 많이 생성되지 않도록 각 쓰기는 소수의 파티션에 집중해야 합니다.
+- **파티션/버키팅 컬럼 선택**:
+ - 파티션 컬럼은 시간 또는 카디널리티가 낮은 열거형 컬럼을 우선 선택하세요.
+ - 버키팅 컬럼은 균등한 분산을 위해 카디널리티가 높은 컬럼(예: `user_id`)을 선택하세요.
+ - 단일 Tablet의 데이터 크기는 1-10 GB를 권장합니다.
+
+## 7. 파티션 조회 및 수정 {#7-viewing-and-modifying-partitions}
+
+### 7.1 SHOW CREATE TABLE로 CREATE TABLE 문 조회 {#71-view-the-create-table-statement-via-show-create-table}
+
+`SHOW CREATE TABLE`을 사용하면 파티션 정보를 포함한 테이블의 전체 CREATE TABLE 문을 확인할 수 있습니다.
+
+```sql
+> show create table example_range_tbl
++-------------------+---------------------------------------------------------------------------------------------------------+
+| Table | Create Table |
++-------------------+---------------------------------------------------------------------------------------------------------+
+| example_range_tbl | CREATE TABLE `example_range_tbl` ( |
+| | `user_id` largeint(40) NOT NULL COMMENT 'User ID', |
+| | `date` date NOT NULL COMMENT 'Data ingestion date', |
+| | `timestamp` datetime NOT NULL COMMENT 'Data ingestion timestamp', |
+| | `city` varchar(20) NULL COMMENT 'User city', |
+| | `age` smallint(6) NULL COMMENT 'User age', |
+| | `sex` tinyint(4) NULL COMMENT 'User gender', |
+| | `last_visit_date` datetime REPLACE NULL DEFAULT "1970-01-01 00:00:00" COMMENT 'User last visit time', |
+| | `cost` bigint(20) SUM NULL DEFAULT "0" COMMENT 'Total user spending', |
+| | `max_dwell_time` int(11) MAX NULL DEFAULT "0" COMMENT 'Maximum user dwell time', |
+| | `min_dwell_time` int(11) MIN NULL DEFAULT "99999" COMMENT 'Minimum user dwell time' |
+| | ) |
+| | PARTITION BY RANGE(`date`) |
+| | (PARTITION p201701 VALUES [('0000-01-01'), ('2017-02-01')), |
+| | PARTITION p201702 VALUES [('2017-02-01'), ('2017-03-01')), |
+| | PARTITION p201703 VALUES [('2017-03-01'), ('2017-04-01'))) |
+| | DISTRIBUTED BY HASH(`user_id`) BUCKETS 16 |
+| | PROPERTIES ( |
+| | "replication_allocation" = "tag.location.default: 1", |
+| | "storage_format" = "V2", |
+| | "light_schema_change" = "true", |
+| | "disable_auto_compaction" = "false" |
+| | ); |
++-------------------+---------------------------------------------------------------------------------------------------------+
+```
+
+### 7.2 SHOW PARTITIONS로 파티션 목록 조회 {#72-view-the-partition-list-via-show-partitions}
+
+`SHOW PARTITIONS FROM <table_name>`을 사용하면 테이블의 파티션 목록과 상세 정보를 확인할 수 있습니다.
+
+```sql
+> show partitions from example_range_tbl
++-------------+---------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------
++---------------------+---------------------+--------------------------+----------+------------+-------------------------+-----------+
+| PartitionId | PartitionName | VisibleVersion | VisibleVersionTime | State | PartitionKey | Range | DistributionKey | Buckets | ReplicationNum | StorageMedium
+| CooldownTime | RemoteStoragePolicy | LastConsistencyCheckTime | DataSize | IsInMemory | ReplicaAllocation | IsMutable |
++-------------+---------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------
++---------------------+---------------------+--------------------------+----------+------------+-------------------------+-----------+
+| 28731 | p201701 | 1 | 2024-01-25 10:50:51 | NORMAL | date | [types: [DATEV2]; keys: [0000-01-01]; ..types: [DATEV2]; keys: [2017-02-01]; ) | user_id | 16 | 1 | HDD
+| 9999-12-31 23:59:59 | | | 0.000 | false | tag.location.default: 1 | true |
+| 28732 | p201702 | 1 | 2024-01-25 10:50:51 | NORMAL | date | [types: [DATEV2]; keys: [2017-02-01]; ..types: [DATEV2]; keys: [2017-03-01]; ) | user_id | 16 | 1 | HDD
+| 9999-12-31 23:59:59 | | | 0.000 | false | tag.location.default: 1 | true |
+| 28733 | p201703 | 1 | 2024-01-25 10:50:51 | NORMAL | date | [types: [DATEV2]; keys: [2017-03-01]; ..types: [DATEV2]; keys: [2017-04-01]; ) | user_id | 16 | 1 | HDD
+| 9999-12-31 23:59:59 | | | 0.000 | false | tag.location.default: 1 | true |
++-------------+---------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------
++---------------------+---------------------+--------------------------+----------+------------+-------------------------+-----------+
+```
+
+### 7.3 파티션 수정 {#73-modify-partitions}
+
+`ALTER TABLE ADD PARTITION`을 사용하면 테이블에 새 파티션을 추가할 수 있습니다.
+
+```sql
+ALTER TABLE example_range_tbl ADD PARTITION p201704 VALUES LESS THAN("2020-05-01") DISTRIBUTED BY HASH(`user_id`) BUCKETS 5;
+```
+
+다른 파티션 수정 작업은 SQL 매뉴얼의 [ALTER-TABLE-PARTITION](../../sql-manual/sql-statements/table-and-view/table/ALTER-TABLE-PARTITION)을 참조하세요.
+
+### 7.4 파티션 검색 {#74-partition-lookup}
+
+`partitions` 테이블 함수와 `information_schema.partitions` 시스템 테이블은 클러스터의 파티션 정보를 기록합니다. 파티션을 자동으로 관리할 때 이를 사용하여 파티션 정보를 추출할 수 있습니다.
+
+#### 지정한 값이 속한 파티션 찾기 {#find-the-partition-that-a-given-value-belongs-to}
+
+Auto Partition 테이블에서 값에 해당하는 파티션을 찾습니다.
+
+```sql
+mysql> select * from partitions("catalog"="internal", "database"="optest", "table"="DAILY_TRADE_VALUE") where PartitionName = auto_partition_name('range', 'year', '2008-02-03');
++-------------+-----------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+-----------+------------+-------------------------+-----------+--------------------+--------------+
+| PartitionId | PartitionName | VisibleVersion | VisibleVersionTime | State | PartitionKey | Range | DistributionKey | Buckets | ReplicationNum | StorageMedium | CooldownTime | RemoteStoragePolicy | LastConsistencyCheckTime | DataSize | IsInMemory | ReplicaAllocation | IsMutable | SyncWithBaseTables | UnsyncTables |
++-------------+-----------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+-----------+------------+-------------------------+-----------+--------------------+--------------+
+| 127095 | p20080101000000 | 2 | 2024-11-14 17:29:02 | NORMAL | TRADE_DATE | [types: [DATEV2]; keys: [2008-01-01]; ..types: [DATEV2]; keys: [2009-01-01]; ) | TRADE_DATE | 10 | 1 | HDD | 9999-12-31 23:59:59 | | \N | 985.000 B | 0 | tag.location.default: 1 | 1 | 1 | \N |
++-------------+-----------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+-----------+------------+-------------------------+-----------+--------------------+--------------+
+1 row in set (0.30 sec)
+```
+
+List 파티션 테이블에서 해당 파티션을 찾습니다.
+
+```sql
+mysql> select * from information_schema.partitions where TABLE_SCHEMA='optest' and TABLE_NAME='list_table1' and PARTITION_NAME=auto_partition_name('list', null);
++---------------+--------------+-------------+----------------+-------------------+----------------------------+-------------------------------+------------------+---------------------+----------------------+-------------------------+-----------------------+------------+----------------+-------------+-----------------+--------------+-----------+-------------+---------------------+---------------------+----------+-------------------+-----------+-----------------+
+| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME | PARTITION_NAME | SUBPARTITION_NAME | PARTITION_ORDINAL_POSITION | SUBPARTITION_ORDINAL_POSITION | PARTITION_METHOD | SUBPARTITION_METHOD | PARTITION_EXPRESSION | SUBPARTITION_EXPRESSION | PARTITION_DESCRIPTION | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | MAX_DATA_LENGTH | INDEX_LENGTH | DATA_FREE | CREATE_TIME | UPDATE_TIME | CHECK_TIME | CHECKSUM | PARTITION_COMMENT | NODEGROUP | TABLESPACE_NAME |
++---------------+--------------+-------------+----------------+-------------------+----------------------------+-------------------------------+------------------+---------------------+----------------------+-------------------------+-----------------------+------------+----------------+-------------+-----------------+--------------+-----------+-------------+---------------------+---------------------+----------+-------------------+-----------+-----------------+
+| internal | optest | list_table1 | pX | NULL | 0 | 0 | LIST | NULL | str | NULL | (NULL) | 1 | 1266 | 1266 | 0 | 0 | 0 | 0 | 2024-11-14 19:58:45 | 0000-00-00 00:00:00 | 0 | | | |
++---------------+--------------+-------------+----------------+-------------------+----------------------------+-------------------------------+------------------+---------------------+----------------------+-------------------------+-----------------------+------------+----------------+-------------+-----------------+--------------+-----------+-------------+---------------------+---------------------+----------+-------------------+-----------+-----------------+
+1 row in set (0.24 sec)
+```
+
+#### 지정한 시작값을 갖는 파티션 찾기 {#find-partitions-with-a-given-starting-point}
+
+```sql
+mysql> select * from information_schema.partitions where TABLE_NAME='DAILY_TRADE_VALUE' and PARTITION_DESCRIPTION like "[('2012-01-01'),%";
++---------------+--------------+-------------------+-----------------+-------------------+----------------------------+-------------------------------+------------------+---------------------+----------------------+-------------------------+----------------------------------+------------+----------------+-------------+-----------------+--------------+-----------+-------------+---------------------+---------------------+----------+-------------------+-----------+-----------------+
+| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME | PARTITION_NAME | SUBPARTITION_NAME | PARTITION_ORDINAL_POSITION | SUBPARTITION_ORDINAL_POSITION | PARTITION_METHOD | SUBPARTITION_METHOD | PARTITION_EXPRESSION | SUBPARTITION_EXPRESSION | PARTITION_DESCRIPTION | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | MAX_DATA_LENGTH | INDEX_LENGTH | DATA_FREE | CREATE_TIME | UPDATE_TIME | CHECK_TIME | CHECKSUM | PARTITION_COMMENT | NODEGROUP | TABLESPACE_NAME |
++---------------+--------------+-------------------+-----------------+-------------------+----------------------------+-------------------------------+------------------+---------------------+----------------------+-------------------------+----------------------------------+------------+----------------+-------------+-----------------+--------------+-----------+-------------+---------------------+---------------------+----------+-------------------+-----------+-----------------+
+| internal | optest | DAILY_TRADE_VALUE | p20120101000000 | NULL | 0 | 0 | RANGE | NULL | TRADE_DATE | NULL | [('2012-01-01'), ('2013-01-01')) | 1 | 985 | 985 | 0 | 0 | 0 | 0 | 2024-11-14 17:29:02 | 0000-00-00 00:00:00 | 0 | | | |
++---------------+--------------+-------------------+-----------------+-------------------+----------------------------+-------------------------------+------------------+---------------------+----------------------+-------------------------+----------------------------------+------------+----------------+-------------+-----------------+--------------+-----------+-------------+---------------------+---------------------+----------+-------------------+-----------+-----------------+
+1 row in set (0.65 sec)
+```
+
+## 8. 추가 자료 {#8-further-reading}
+
+- [수동 파티셔닝](./manual-partitioning)
+- [동적 파티셔닝](./dynamic-partitioning)
+- [자동 파티셔닝](./auto-partitioning)
+- [데이터 버키팅](./data-bucketing)
+- [일반적인 문제](./common-issues)
+- [CREATE TABLE 구문](../../sql-manual/sql-statements/table-and-view/table/CREATE-TABLE)
+- [ALTER TABLE PARTITION](../../sql-manual/sql-statements/table-and-view/table/ALTER-TABLE-PARTITION)
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-partitioning/common-issues.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-partitioning/common-issues.md
new file mode 100644
index 00000000000..47b4c440d15
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-partitioning/common-issues.md
@@ -0,0 +1,100 @@
+---
+{
+ "title": "테이블 생성 시 자주 발생하는 문제",
+ "language": "ko",
+ "description": "Apache Doris 테이블 생성 문제 해결 가이드: 구문 오류, Failed to create partition 시간 초과, Too many open files, 명령 실행 후 응답이 없는 현상 등 여러 상황의 원인과 해결 방법을 안내합니다.",
+ "keywords": [
+ "Doris 테이블 생성 실패",
+ "Failed to create partition",
+ "Too many open files",
+ "tablet_create_timeout_second",
+ "테이블 생성 시간 초과",
+ "테이블 생성 구문 오류"
+ ]
+}
+---
+
+<!-- Knowledge type: Troubleshooting -->
+<!-- Applicable scenario: Table creation failure troubleshooting / Timeout tuning -->
+
+이 문서는 테이블 생성 중 발생할 수 있는 대표적인 상황별로 원인을 분석하고 해결 방법을 안내합니다.
+
+## 시나리오 1: CREATE TABLE 문의 구문 오류 {#scenario-1-syntax-errors-in-the-create-table-statement}
+
+긴 CREATE TABLE 문에서 구문 오류가 발생하면 오류 메시지가 불완전할 수 있습니다. 일반적인 원인은 다음과 같습니다.
+
+| 원인 | 확인 및 수정 방법 |
+| --- | --- |
+| 구문 구조 오류 | `HELP CREATE TABLE;`을 자세히 읽고 해당 구문 구조가 올바른지 확인하세요 |
+| 예약어 사용 | 사용자 지정 이름이 예약어와 충돌하면 해당 이름을 백틱 `` ` ``으로 감싸세요. 모든 사용자 지정 이름을 백틱으로 감싸는 것이 좋습니다 |
+| 중국어 문자 또는 전각 문자 | utf-8로 인코딩되지 않은 중국어 문자나 숨겨진 전각 문자(예: 전각 공백 또는 전각 문장 부호)는 구문 오류를 일으킬 수 있습니다. "보이지 않는 문자 표시" 기능이 있는 텍스트 편집기로 확인하세요 |
+
+## 시나리오 2: 테이블 생성 시 `Failed to create partition [xxx]. Timeout` 오류 발생 {#scenario-2-table-creation-reports-failed-to-create-partition-xxx-timeout}
+
+Doris는 Partition을 하나씩 생성하여 테이블을 만듭니다. Partition 생성에 실패하면 위 오류가 보고됩니다.
+
+CREATE TABLE 문에 Partition을 명시적으로 정의하지 않아도 Doris는 테이블에 변경할 수 없는 기본 Partition을 생성합니다. 따라서 테이블 생성 중 문제가 발생하면 이 경우에도 `Failed to create partition` 오류가 보고됩니다.
+
+이 오류는 일반적으로 BE에서 데이터 샤드(Tablet)를 생성하는 중 문제가 발생할 때 나타납니다.
+
+### 확인 절차 {#investigation-steps}
+
+1. **실패한 Backend와 Tablet 확인**
+
+ `fe.log`에서 해당 시점의 `Failed to create partition` 로그를 검색하세요. 로그에는 `{10001-10010}`과 같은 숫자 쌍이 나열되어 있습니다.
+
+ - 첫 번째 숫자(`10001`): Backend ID
+ - 두 번째 숫자(`10010`): Tablet ID
+
+ 위 예시는 Tablet ID `10010` 생성이 ID가 `10001`인 Backend에서 실패했음을 나타냅니다.
+
+2. **BE 로그에서 오류 메시지 확인**
+
+ 해당 Backend의 `be.INFO` 로그에서 해당 시간대의 Tablet ID 관련 로그를 검색하여 구체적인 오류 메시지를 찾으세요.
+
+3. **일반적인 오류 유형에 따라 문제 해결**
+
+### Tablet 생성 실패의 일반적인 원인 {#common-causes-of-tablet-creation-failure}
+
+| 오류 증상 | 가능한 원인 | 권장 조치 |
+| --- | --- | --- |
+| BE가 관련 작업을 수신하지 못함(`be.INFO`에서 Tablet ID 관련 로그를 찾을 수 없음) 또는 BE가 Tablet을 성공적으로 생성했지만 보고하지 못함 | FE와 BE 간 연결 문제 | [설치 및 배포](../../install/deploy-manually/integrated-storage-compute-deploy-manually)를 참고하여 FE와 BE 간 네트워크 연결을 확인하세요 |
+| 메모리 사전 할당 실패 | 테이블의 단일 행 바이트 길이가 100 KB를 초과함 | 테이블 스키마를 조정하여 단일 행 데이터의 길이를 줄이세요 |
+| `Too many open files` | 열린 파일 핸들 수가 Linux 시스템 제한을 초과함 | Linux 시스템의 파일 핸들 제한을 수정하세요 |
+
+### 테이블 생성 제한 시간 조정 {#adjust-the-table-creation-timeout}
+
+데이터 샤드 생성 시 시간 초과만 발생하는 경우, `fe.conf`의 다음 두 매개변수를 통해 제한 시간을 늘릴 수 있습니다.
+
+| 매개변수 | 기본값 | 설명 |
+| --- | --- | --- |
+| `tablet_create_timeout_second` | 1초 | 단일 Tablet 생성 제한 시간 |
+| `max_create_table_timeout_second` | 60초 | 전체 테이블 생성 작업의 최대 제한 시간 |
+
+전체 제한 시간은 다음과 같이 계산됩니다.
+
+```text
+min(tablet_create_timeout_second * replication_num, max_create_table_timeout_second)
+```
+
+매개변수에 대한 자세한 설명은 [FE 설정](../../admin-manual/config/fe-config)을 참고하세요.
+
+## 시나리오 3: CREATE TABLE 명령이 오랫동안 반환되지 않음 {#scenario-3-the-create-table-command-does-not-return-for-a-long-time}
+
+Doris의 CREATE TABLE 명령은 동기식입니다. 현재 제한 시간은 비교적 단순한 방식으로 설정됩니다.
+
+```text
+timeout = tablet num * replication num (seconds)
+```
+
+관련 증상과 권장 사항은 다음과 같습니다.
+
+- 데이터 샤드를 많이 생성하고 그중 일부가 실패하면 긴 제한 시간이 지난 후에야 오류가 반환될 수 있습니다.
+- 정상적인 상황에서는 CREATE TABLE 문이 몇 초에서 수십 초 이내에 반환됩니다.
+- 일 분이 지나도 반환되지 않으면 작업을 바로 취소하고 FE 또는 BE 로그에서 관련 오류를 확인하세요.
+
+## 추가 도움말 {#further-help}
+
+데이터 파티셔닝에 대한 자세한 내용은 다음을 참고하세요.
+
+- [CREATE TABLE](../../sql-manual/sql-statements/table-and-view/table/CREATE-TABLE) 명령 매뉴얼 참고
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-partitioning/data-bucketing.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-partitioning/data-bucketing.md
new file mode 100644
index 00000000000..80e39e74421
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-partitioning/data-bucketing.md
@@ -0,0 +1,283 @@
+---
+{
+ "title": "데이터 버킷팅",
+ "language": "ko",
+ "description": "Doris 데이터 버킷팅 가이드: Hash 버킷팅과 Random 버킷팅 중 적절한 방식을 선택하고, 버킷 키와 버킷 수를 결정하여 쿼리 성능을 높이고 데이터 편향을 방지하는 방법을 설명합니다.",
+ "keywords": [
+ "Doris 데이터 버킷팅",
+ "Hash 버킷팅",
+ "Random 버킷팅",
+ "버킷 키 선택",
+ "버킷 수",
+ "tablet",
+ "데이터 편향"
+ ]
+}
+---
+
+<!-- Knowledge type: Architecture decision / Configuration parameter -->
+<!-- Applicable scenarios: Table design / Performance tuning / Data skew handling -->
+
+업무 요구 사항에 따라 파티션을 여러 데이터 버킷으로 더 나눌 수 있습니다. 각 버킷은 물리적 데이터 샤드(Tablet)로 저장됩니다. 적절한 버킷팅 전략을 사용하면 쿼리 시 스캔하는 데이터양을 효과적으로 줄이고, 쿼리 성능과 동시 처리 능력을 높일 수 있습니다.
+
+이 문서는 테이블 생성 시의 의사 결정 순서에 따라 구성되어 있습니다. 먼저 버킷팅 방식을 선택하고, 버킷 키를 선택한 다음, 버킷 수와 이후 유지 관리 방식을 결정합니다.
+
+## 빠른 의사 결정 {#quick-decision}
+
+테이블을 생성할 때 다음 순서로 버킷팅을 설계할 수 있습니다.
+
+| 단계 | 결정 항목 | 주요 고려 사항 |
+|------|------|----------|
+| 1 | 버킷팅 방식 선택 | 자주 사용하는 필터 컬럼의 유무, 데이터 분포의 균등성, 테이블 모델 |
+| 2 | 버킷 키 선택(Hash 버킷팅만 해당) | 쿼리 필터 조건, 컬럼 카디널리티, 쿼리 동시성 및 처리량 특성 |
+| 3 | 버킷 수 결정 | Tablet당 데이터 크기, BE 수, 디스크 수 |
+| 4 | 버킷 유지 관리 전략 수립 | 데이터 증가 추세, 동적 파티셔닝 사용 여부 |
+
+## 1. 버킷팅 방식 선택 {#1-choose-the-bucketing-method}
+
+Doris는 **Hash 버킷팅**과 **Random 버킷팅**의 두 가지 버킷팅 방식을 지원합니다. 주요 차이점은 다음과 같습니다.
+
+| 비교 항목 | Hash 버킷팅 | Random 버킷팅 |
+|--------|----------|------------|
+| 데이터 분산 방식 | 버킷 키의 Hash 값에 따라 분할 | 무작위로 균등하게 분산 |
+| 버킷 키 필요 여부 | 필요 | 불필요 |
+| 버킷 프루닝 지원 여부 | 지원 | 미지원 |
+| 적용 가능한 테이블 모델 | DUPLICATE / UNIQUE / AGGREGATE | DUPLICATE만 지원 |
+| 데이터 편향 위험 | 버킷 키 선택에 따라 달라짐 | 낮음 |
+| 적합한 시나리오 | 특정 컬럼으로 자주 필터링하는 포인트 쿼리 | 임의의 차원에 대한 분석, 편향이 발생하기 쉬운 데이터 |
+
+### 1. Hash 버킷팅 {#1-hash-bucketing}
+
+테이블을 생성하거나 새 파티션을 추가할 때 하나 이상의 컬럼을 버킷 키로 선택하고 버킷 수를 명시적으로 지정해야 합니다. 동일한 파티션 내에서 시스템은 버킷 키와 버킷 수를 기반으로 Hash를 계산하고, Hash 값이 같은 행을 같은 버킷에 할당합니다.
+
+예를 들어 아래 그림에서는 `p250102` 파티션을 `region` 컬럼에 따라 3개의 버킷으로 나누고, Hash 값이 같은 행을 같은 버킷에 배치합니다.
+
+
+
+**권장 시나리오:**
+
+- 업무에서 특정 필드를 자주 필터링하는 경우, 해당 필드를 버킷 키로 사용하고 버킷 프루닝을 활용하여 쿼리 효율을 높일 수 있습니다.
+- 테이블의 데이터가 비교적 고르게 분포되어 편향이 발생할 가능성이 낮은 경우입니다.
+
+**예시:** Hash 버킷팅을 사용하는 테이블을 생성합니다. 자세한 구문은 [CREATE TABLE](../../sql-manual/sql-statements/table-and-view/table/CREATE-TABLE.md)을 참조하세요.
+
+아래 예시에서는 테이블 이름에 `demo` 데이터베이스를 명시합니다. 클러스터에 해당 데이터베이스가 없으면 먼저 생성하세요.
+
+```sql
+CREATE DATABASE IF NOT EXISTS demo;
+```
+
+```sql
+CREATE TABLE demo.hash_bucket_tbl(
+ oid BIGINT,
+ dt DATE,
+ region VARCHAR(10),
+ amount INT
+)
+DUPLICATE KEY(oid)
+PARTITION BY RANGE(dt) (
+ PARTITION p250101 VALUES LESS THAN("2025-01-01"),
+ PARTITION p250102 VALUES LESS THAN("2025-01-02")
+)
+DISTRIBUTED BY HASH(region) BUCKETS 8;
+```
+
+이 예시에서 `DISTRIBUTED BY HASH(region)`은 Hash 버킷팅을 사용하도록 지정하고 `region` 컬럼을 버킷 키로 선택합니다. `BUCKETS 8`은 8개의 버킷을 생성하도록 지정합니다.
+
+### 2. Random 버킷팅 {#2-random-bucketing}
+
+Random 버킷팅은 특정 필드의 Hash 값에 의존하지 않고 각 파티션 내의 버킷에 데이터를 무작위로 분산합니다. 이 방식은 데이터를 고르게 분산하고, 부적절한 버킷 키 선택으로 인한 데이터 편향을 방지합니다.
+
+데이터를 적재할 때 하나의 데이터 적재 작업에 포함된 각 배치는 임의의 Tablet에 기록되므로 데이터가 고르게 분산됩니다. 예를 들어 아래 그림에서는 8개의 데이터 배치를 `p250102` 파티션의 3개 버킷에 무작위로 할당합니다.
+
+
+
+Random 버킷팅을 사용할 때는 단일 Tablet 데이터 적재 모드를 활성화하여(`load_to_single_tablet`을 `true`로 설정) 단일 배치의 데이터를 하나의 데이터 샤드에만 기록할 수 있습니다. 이를 통해 다음과 같은 효과를 얻을 수 있습니다.
+
+- 대규모 데이터 적재의 동시성과 처리량을 높입니다.
+- 데이터 적재 및 Compaction 작업으로 발생하는 쓰기 증폭을 줄입니다.
+- 클러스터 안정성을 높입니다.
+
+**권장 시나리오:**
+
+- 업무에 고정된 필터 또는 조인 컬럼이 없고, 임의의 차원에 대해 분석하는 경우입니다.
+- 자주 쿼리하는 컬럼이나 컬럼 조합의 데이터 분포가 매우 불균등하여 데이터 편향을 방지해야 하는 경우입니다.
+
+**적합하지 않은 시나리오:**
+
+- 포인트 쿼리 시나리오: Random 버킷팅은 버킷 키를 기반으로 프루닝할 수 없으므로 조건에 맞는 파티션의 모든 데이터를 스캔합니다.
+- UNIQUE 및 AGGREGATE 테이블: DUPLICATE 테이블만 Random 버킷팅을 지원합니다.
+
+**예시:** Random 버킷팅을 사용하는 테이블을 생성합니다. 자세한 구문은 [CREATE TABLE](../../sql-manual/sql-statements/table-and-view/table/CREATE-TABLE.md)을 참조하세요.
+
+```sql
+CREATE TABLE demo.random_bucket_tbl(
+ oid BIGINT,
+ dt DATE,
+ region VARCHAR(10),
+ amount INT
+)
+DUPLICATE KEY(oid)
+PARTITION BY RANGE(dt) (
+ PARTITION p250101 VALUES LESS THAN("2025-01-01"),
+ PARTITION p250102 VALUES LESS THAN("2025-01-02")
+)
+DISTRIBUTED BY RANDOM BUCKETS 8;
+```
+
+이 예시에서 `DISTRIBUTED BY RANDOM`은 Random 버킷팅을 사용하도록 지정하며, 버킷 키를 선택할 필요가 없습니다. `BUCKETS 8`은 8개의 버킷을 생성하도록 지정합니다.
+
+## 2. 버킷 키 선택 {#2-select-the-bucket-key}
+
+:::tip 팁
+
+Hash 버킷팅에서만 버킷 키를 선택해야 합니다. Random 버킷팅에서는 필요하지 않습니다.
+
+:::
+
+버킷 키는 하나 이상의 컬럼으로 구성할 수 있습니다. 테이블 모델별 버킷 키 제한 사항은 다음과 같습니다.
+
+| 테이블 모델 | 버킷 키로 사용할 수 있는 컬럼 |
+|--------|----------|
+| DUPLICATE | 모든 Key 컬럼 또는 Value 컬럼 |
+| AGGREGATE / UNIQUE | Key 컬럼이어야 함(올바른 데이터 집계를 보장하기 위함) |
+
+### 선택 원칙 {#selection-principles}
+
+업무 쿼리 특성에 따라 다음 원칙을 참고하여 버킷 키를 선택할 수 있습니다.
+
+| 원칙 | 설명 | 이점 |
+|------|------|------|
+| 쿼리 필터 조건 활용 | 쿼리에서 필터로 자주 사용하는 컬럼을 버킷 키로 선택 | 버킷 프루닝을 지원하고 스캔하는 데이터양을 줄임 |
+| 카디널리티가 높은 컬럼 활용 | 고유한 값이 많은 컬럼을 버킷 키로 선택 | 데이터를 고르게 분산하고 편향을 방지함 |
+| 동시성이 높은 포인트 쿼리 시나리오 | 단일 컬럼 또는 적은 수의 컬럼을 버킷 키로 선택 | 쿼리 하나가 버킷 하나만 스캔하므로 쿼리 간 IO 간섭이 줄어듦 |
+| 높은 처리량이 필요한 쿼리 시나리오 | 여러 컬럼을 버킷 키로 선택 | 데이터가 더 고르게 분산되며, 쿼리 조건이 동등 조건과 완전히 일치하지 않을 때 전체 처리량이 향상됨 |
+
+## 3. 버킷 수 결정 {#3-determine-the-number-of-buckets}
+
+Doris에서 각 버킷은 물리적 파일(Tablet)로 저장됩니다. 테이블의 전체 Tablet 수는 다음과 같습니다.
+
+```text
+Total Tablets = partition_num × bucket_num
+```
+
+:::caution 주의
+
+파티션의 버킷 수는 한 번 지정하면 변경할 수 없습니다. 버킷 수를 결정할 때는 향후 머신 확장을 미리 고려하세요.
+
+:::
+
+Doris는 2.0 버전부터 머신 리소스와 클러스터 정보를 기반으로 파티션의 버킷 수를 자동으로 설정하는 기능을 지원합니다. 업무에서 요구하는 추정 정밀도에 따라 수동 또는 자동 방식을 선택할 수 있습니다.
+
+### 1. 버킷 수 수동 설정 {#1-manually-set-the-number-of-buckets}
+
+`DISTRIBUTED` 절을 통해 버킷 수를 지정합니다.
+
+```sql
+-- Set hash bucket num to 8
+DISTRIBUTED BY HASH(region) BUCKETS 8
+
+-- Set random bucket num to 8
+DISTRIBUTED BY RANDOM BUCKETS 8
+```
+
+#### 결정 원칙 {#decision-principles}
+
+버킷 수를 결정할 때는 다음 두 가지 원칙을 따르세요. 두 원칙이 상충하는 경우 **크기 원칙을 우선하세요**.
+
+1. **크기 원칙**: 각 Tablet의 압축된 데이터 크기(인덱스 제외)는 **1 GB에서 20 GB** 사이로 유지하는 것이 좋으며, Unique Key 테이블의 경우 **10 GB**를 넘지 않는 것이 좋습니다.
+ - Tablet이 너무 작으면 집계 효과가 떨어지고 메타데이터 관리 오버헤드가 증가합니다.
+ - Tablet이 너무 크면 복제본 마이그레이션과 복구가 어려워지고, 실패한 Schema Change를 재시도하는 비용이 증가합니다.
+ - `SHOW TABLETS FROM your_table`을 사용하여 실제 Tablet 크기를 확인할 수 있습니다.
+
+2. **수량 원칙**: 확장을 고려하지 않는 경우, 테이블의 Tablet 수는 클러스터의 전체 디스크 수보다 약간 많게 설정하는 것이 좋습니다.
+
+또한 다음 사항에 유의하세요.
+
+- 데이터를 고르게 분산하려면 버킷 수를 BE 수의 정수 배수로 설정해야 합니다.
+- 단일 파티션의 버킷 수는 일반적으로 **128**을 넘지 않아야 합니다. 더 많은 버킷이 필요하면 먼저 테이블을 파티셔닝하세요.
+
+#### 권장 설정 예시 {#recommended-configuration-examples}
+
+클러스터에 BE 머신이 10대 있고 각 머신에 디스크가 하나씩 있다고 가정합니다. 아래 표를 참고하여 버킷 수를 설정할 수 있습니다.
+
+| 압축된 파티션 데이터 크기 | 권장 버킷 수 |
+|-----------------|-----------------|
+| < 1 GB | 1개 버킷 |
+| 1 - 10 GB | 10개 버킷 |
+| 10 - 200 GB | 10 - 20개 버킷 |
+| > 200 GB | 먼저 테이블을 파티셔닝 |
+
+:::tip 팁
+
+`SHOW DATA` 명령으로 테이블의 데이터 크기를 확인할 수 있습니다. 테이블의 실제 데이터 크기를 구하려면 결과를 복제본 수로 나누어야 합니다.
+
+:::
+
+### 2. 버킷 수 자동 설정 {#2-automatically-set-the-number-of-buckets}
+
+자동 버킷 수 추정 기능은 최근 일정 기간의 파티션 크기를 기반으로 향후 파티션 크기를 예측하고, 그에 따라 버킷 수를 결정합니다.
+
+```sql
+-- Set hash bucket auto
+DISTRIBUTED BY HASH(region) BUCKETS AUTO
+properties("estimate_partition_size" = "20G")
+
+-- Set random bucket auto
+DISTRIBUTED BY RANDOM BUCKETS AUTO
+properties("estimate_partition_size" = "20G")
+```
+
+`estimate_partition_size` 속성은 파티션 크기의 초기 추정값을 조정하는 데 사용됩니다.
+
+- 이 매개변수는 선택 사항입니다. 지정하지 않으면 기본값은 `10GB`입니다.
+- 이 매개변수는 초기 추정값에만 영향을 미치며, 이후 시스템이 과거 파티션 데이터에서 추정하는 향후 파티션 크기와는 무관합니다.
+
+계산된 버킷 수는 FE 설정인 `autobucket_min_buckets`와 `autobucket_max_buckets` 사이로 제한됩니다.
+
+| FE 설정 | 기본값 | 설명 |
+|---|---|---|
+| `autobucket_min_buckets` | 3 | 자동 버킷팅 결과의 하한값. **기본값이 `1`에서 `3`으로 변경되었으며, 4.0.8(4.0 시리즈) 및 4.1.4(4.1 시리즈)부터 적용됩니다** |
+| `autobucket_max_buckets` | 128 | 자동 버킷팅 결과의 상한값 |
+
+:::caution 동작 변경 (4.0.8 / 4.1.4)
+
+`autobucket_min_buckets`의 기본값이 `1`에서 `3`으로 변경되었으며, 4.0.8(4.0 시리즈) 및 4.1.4(4.1 시리즈)부터 적용됩니다. 이전에는 작은 파티션의 버킷 수가 하나로 계산되어 병렬성과 데이터 분산이 부족해질 수 있었습니다. 변경 후에는 자동 버킷팅으로 생성되는 버킷 수가 3개 미만이 되지 않습니다.
+
+이 변경은 업그레이드 **이후에 생성되는** 파티션에만 영향을 미치며, 기존 파티션의 버킷 수는 변경되지 않습니다. 이전 동작을 유지하려면 `autobucket_min_buckets`를 명시적으로 `1`로 다시 설정하세요.
+
+:::
+
+## 4. 데이터 버킷팅 유지 관리 {#4-maintain-data-bucketing}
+
+:::tip 팁
+
+현재 Doris는 새로 추가되는 파티션의 버킷 수 변경만 지원합니다. 다음 작업은 지원하지 않습니다.
+
+1. 버킷팅 유형 변경은 지원하지 않습니다.
+2. 버킷 키 변경은 지원하지 않습니다.
+3. 이미 생성된 버킷의 수 변경은 지원하지 않습니다.
+
+:::
+
+테이블을 생성할 때는 `DISTRIBUTED` 절을 통해 각 파티션의 버킷 수를 일괄적으로 지정합니다. 데이터 증가나 감소에 대응하려면 파티션을 동적으로 추가할 때 새 파티션의 버킷 수를 개별적으로 지정할 수 있습니다.
+
+다음 예시는 `ALTER TABLE` 명령을 통해 새로 추가되는 파티션의 버킷 수를 변경하는 방법을 보여 줍니다.
+
+```sql
+-- Modify hash bucket table
+ALTER TABLE demo.hash_bucket_tbl
+ADD PARTITION p250103 VALUES LESS THAN("2025-01-03")
+DISTRIBUTED BY HASH(region) BUCKETS 16;
+
+-- Modify random bucket table
+ALTER TABLE demo.random_bucket_tbl
+ADD PARTITION p250103 VALUES LESS THAN("2025-01-03")
+DISTRIBUTED BY RANDOM BUCKETS 16;
+
+-- Modify dynamic partition table
+ALTER TABLE demo.dynamic_partition_tbl
+SET ("dynamic_partition.buckets"="16");
+```
+
+버킷 수를 변경한 후에는 `SHOW PARTITION` 명령으로 결과를 확인할 수 있습니다.
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-partitioning/dynamic-partitioning.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-partitioning/dynamic-partitioning.md
new file mode 100644
index 00000000000..d67eb40c51a
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-partitioning/dynamic-partitioning.md
@@ -0,0 +1,231 @@
+---
+{
+ "title": "동적 파티셔닝",
+ "sidebar_label": "동적 파티셔닝",
+ "language": "ko",
+ "description": "동적 파티셔닝은 일정에 따라 파티션을 생성하고 삭제하여 테이블의 파티션 수명 주기 관리(TTL)를 제공합니다. 로그 및 시계열 데이터처럼 만료된 데이터를 자동으로 정리해야 하는 시나리오에 적합합니다."
+}
+---
+
+:::info 파티션 관리 방식 선택
+동적 파티셔닝은 일정에 따라 파티션을 생성하고 삭제합니다. 데이터가 들어올 때 필요에 따라 파티션을 생성해야 한다면 [자동 파티셔닝](./auto-partitioning)을 사용하세요. 일정 기간을 유지할지, 일정 개수의 과거 파티션을 유지할지에 따라 보존 방식을 선택하세요.
+:::
+
+<!-- Knowledge type: Feature introduction + Operating procedure + Configuration parameters -->
+<!-- Applicable scenarios: Log management / Time-series data / Data lifecycle management -->
+
+동적 파티셔닝은 설정된 규칙에 따라 파티션을 순차적으로 추가하고 삭제하여 테이블의 파티션 수명 주기 관리(TTL)를 제공하고 데이터 저장 공간의 부담을 줄입니다. 로그 관리 및 시계열 데이터 관리와 같은 시나리오에서는 만료된 데이터를 순차적으로 삭제하는 데 동적 파티셔닝을 주로 사용합니다.
+
+## 적용 시나리오 {#applicable-scenarios}
+
+| 시나리오 | 설명 |
+| --------------------------- | --------------------------------------------------------------------------------- |
+| 로그 데이터 관리 | 일 또는 시간 단위로 최근 N일의 로그를 보존하고 만료된 파티션을 자동으로 삭제합니다 |
+| 시계열 데이터 관리 | 모니터링, IoT 등의 시나리오에서 시간 축을 따라 파티션을 자동으로 관리합니다 |
+| 데이터 수명 주기 관리 | TTL을 사용하여 데이터 보존 범위를 제어하고 저장 비용을 줄입니다 |
+| 향후 파티션 미리 생성 | 향후 N일의 파티션을 미리 생성하여 파티션 누락으로 인한 쓰기 실패를 방지합니다 |
+
+다음 그림은 동적 파티셔닝을 사용한 수명 주기 관리 예제입니다. 이 예제에서는 다음 규칙을 지정합니다.
+
+- 스케줄링 단위 `dynamic_partition.time_unit`은 `DAY`로, 파티션을 일 단위로 구성합니다.
+- 시작 오프셋 `dynamic_partition.start`는 `-1`로 설정하여 하루 전 파티션을 보존합니다.
+- 종료 오프셋 `dynamic_partition.end`는 `2`로 설정하여 향후 이틀의 파티션을 보존합니다.
+
+이 규칙에 따라 시간이 지나도 하루 전 파티션, 당일 파티션, 향후 이틀의 파티션까지 항상 네 개의 파티션이 유지됩니다.
+
+
+
+## 제한 사항 {#limitations}
+
+동적 파티셔닝을 사용할 때는 다음 제한 사항이 적용됩니다.
+
+- 동적 파티셔닝은 `DATE`, `DATETIME` 또는 `TIMESTAMP_NS` 컬럼에 대한 Range 파티셔닝만 지원합니다.
+- 동적 파티셔닝은 단일 파티션 키만 지원합니다.
+
+## 동적 파티션 테이블 생성 {#creating-a-dynamic-partitioned-table}
+
+<!-- Knowledge type: Operating procedure -->
+
+테이블 생성 시 `dynamic_partition` 속성을 지정하여 동적 파티션 테이블을 생성할 수 있습니다.
+
+```sql
+CREATE TABLE test_dynamic_partition(
+ order_id BIGINT,
+ create_dt DATE,
+ username VARCHAR(20)
+)
+DUPLICATE KEY(order_id)
+PARTITION BY RANGE(create_dt) ()
+DISTRIBUTED BY HASH(order_id) BUCKETS 10
+PROPERTIES(
+ "dynamic_partition.enable" = "true",
+ "dynamic_partition.time_unit" = "DAY",
+ "dynamic_partition.start" = "-1",
+ "dynamic_partition.end" = "2",
+ "dynamic_partition.prefix" = "p",
+ "dynamic_partition.create_history_partition" = "true"
+);
+```
+
+`dynamic_partition` 매개변수에 대한 자세한 내용은 [동적 파티션 속성](#dynamic-partition-properties)을 참조하세요.
+
+## 동적 파티션 관리 {#managing-dynamic-partitions}
+
+### 동적 파티션 속성 수정 {#modifying-dynamic-partition-properties}
+
+:::info 팁
+`ALTER TABLE` 문으로 동적 파티션을 수정해도 즉시 적용되지는 않습니다. Doris는 `dynamic_partition_check_interval_seconds`에 지정된 간격으로 동적 파티션을 확인하고 필요한 파티션 생성 및 삭제 작업을 수행합니다.
+:::
+
+다음 예제에서는 `ALTER TABLE` 문을 사용하여 일반 파티션 테이블을 동적 파티션 테이블로 변환합니다.
+
+```sql
+CREATE TABLE test_partition(
+ order_id BIGINT,
+ create_dt DATE,
+ username VARCHAR(20)
+)
+DUPLICATE KEY(order_id)
+PARTITION BY RANGE(create_dt) ()
+DISTRIBUTED BY HASH(order_id) BUCKETS 10;
+
+ALTER TABLE test_partition SET (
+ "dynamic_partition.enable" = "true",
+ "dynamic_partition.time_unit" = "DAY",
+ "dynamic_partition.start" = "-1",
+ "dynamic_partition.end" = "2",
+ "dynamic_partition.prefix" = "p",
+ "dynamic_partition.create_history_partition" = "true"
+);
+```
+
+### 동적 파티션 스케줄링 상태 확인 {#viewing-dynamic-partition-scheduling-status}
+
+[SHOW-DYNAMIC-PARTITION](../../sql-manual/sql-statements/table-and-view/table/SHOW-DYNAMIC-PARTITION-TABLES)을 사용하면 현재 데이터베이스에 있는 모든 동적 파티션 테이블의 스케줄링 상태를 확인할 수 있습니다.
+
+```sql
+SHOW DYNAMIC PARTITION TABLES;
++-----------+--------+----------+-------------+------+--------+---------+-----------+----------------+---------------------+--------+------------------------+----------------------+-------------------------+
+| TableName | Enable | TimeUnit | Start | End | Prefix | Buckets | StartOf | LastUpdateTime | LastSchedulerTime | State | LastCreatePartitionMsg | LastDropPartitionMsg | ReservedHistoryPeriods |
++-----------+--------+----------+-------------+------+--------+---------+-----------+----------------+---------------------+--------+------------------------+----------------------+-------------------------+
+| d3 | true | WEEK | -3 | 3 | p | 1 | MONDAY | N/A | 2020-05-25 14:29:24 | NORMAL | N/A | N/A | [2021-12-01,2021-12-31] |
+| d5 | true | DAY | -7 | 3 | p | 32 | N/A | N/A | 2020-05-25 14:29:24 | NORMAL | N/A | N/A | NULL |
+| d4 | true | WEEK | -3 | 3 | p | 1 | WEDNESDAY | N/A | 2020-05-25 14:29:24 | NORMAL | N/A | N/A | NULL |
+| d6 | true | MONTH | -2147483648 | 2 | p | 8 | 3rd | N/A | 2020-05-25 14:29:24 | NORMAL | N/A | N/A | NULL |
+| d2 | true | DAY | -3 | 3 | p | 32 | N/A | N/A | 2020-05-25 14:29:24 | NORMAL | N/A | N/A | NULL |
+| d7 | true | MONTH | -2147483648 | 5 | p | 8 | 24th | N/A | 2020-05-25 14:29:24 | NORMAL | N/A | N/A | NULL |
++-----------+--------+----------+-------------+------+--------+---------+-----------+----------------+---------------------+--------+------------------------+----------------------+-------------------------+
+7 rows in set (0.02 sec)
+```
+
+### 과거 파티션 관리 {#managing-historical-partitions}
+
+`start` 및 `end` 속성으로 동적 파티션 수를 지정할 때, 모든 파티션을 한 번에 생성하면서 발생하는 긴 대기 시간을 피하기 위해 기본적으로 과거 파티션은 생성하지 않습니다. 현재 시점 이후의 파티션만 생성합니다. 모든 파티션을 한 번에 생성하려면 `create_history_partition` 매개변수를 활성화하세요.
+
+예를 들어 현재 날짜가 2024-10-11이고 `start = -2`, `end = 2`로 지정한 경우:
+
+- `create_history_partition = true`이면 5개의 파티션이 `[10-09, 10-13]` 범위에 대해 즉시 생성됩니다.
+- `create_history_partition = false`이면 3개의 파티션만 `[10-11, 10-13]` 범위에 대해 생성됩니다.
+
+## 동적 파티션 매개변수 {#dynamic-partition-parameters}
+
+### 동적 파티션 속성 {#dynamic-partition-properties}
+
+<!-- Knowledge type: Configuration parameters -->
+
+동적 파티션 규칙 매개변수는 `dynamic_partition` 접두사를 사용합니다. 다음 규칙 매개변수를 사용할 수 있습니다.
+
+| 매개변수 | 필수 여부 | 설명 |
+| ----------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `dynamic_partition.enable` | 아니요 | 동적 파티셔닝 기능의 활성화 여부입니다. `TRUE` 또는 `FALSE`로 설정할 수 있습니다. 다른 필수 동적 파티션 매개변수가 지정되어 있으면 기본값은 `TRUE`입니다. |
+| `dynamic_partition.time_unit` | 예 | 동적 파티셔닝의 스케줄링 단위입니다. `HOUR`, `DAY`, `WEEK`, `MONTH` 또는 `YEAR`로 설정할 수 있으며, 각각 시간, 일, 주, 월 또는 연 단위로 파티션을 생성하거나 삭제함을 의미합니다. |
+| `dynamic_partition.start` | 아니요 | 동적 파티셔닝의 시작 오프셋으로, 음수로 지정합니다. 기본값은 `-2147483648`이며, 과거 파티션을 삭제하지 않음을 의미합니다. `time_unit` 속성에 따라 현재 날짜(주 / 월)를 기준으로 이 오프셋보다 이전 범위의 파티션을 삭제합니다. 이 오프셋과 현재 시점 사이의 과거 파티션이 없을 때 이를 생성할지는 `dynamic_partition.create_history_partition`으로 제어합니다. |
+| `dynamic_partition.end` | 예 | 동적 파티셔닝의 종료 오프셋으로, 양수로 지정합니다. `time_unit` 속성에 따라 현재 날짜(주 / 월)를 기준으로 해당 범위의 파티션을 미리 생성합니다. |
+| `dynamic_partition.prefix` | 예 | 동적으로 생성되는 파티션 이름의 접두사입니다. |
+| `dynamic_partition.buckets` | 아니요 | 동적으로 생성되는 파티션의 버킷 수입니다. 이 매개변수를 설정하면 `DISTRIBUTED`에 지정된 버킷 수를 재정의합니다. |
+| `dynamic_partition.replication_num` | 아니요 | 동적으로 생성되는 파티션의 복제본 수입니다. 지정하지 않으면 테이블 생성 시 지정한 복제본 수를 기본값으로 사용합니다. |
+| `dynamic_partition.create_history_partition` | 아니요 | 기본값은 `false`입니다. `true`로 설정하면 Doris는 아래에 설명된 규칙에 따라 모든 파티션을 자동으로 생성합니다. 동시에 FE 매개변수 `max_dynamic_partition_num`은 한 번에 너무 많은 파티션이 생성되지 않도록 전체 파티션 수를 제한합니다. 생성할 파티션 수가 `max_dynamic_partition_num`을 초과하면 작업이 거부됩니다. `start` 속성을 지정하지 않으면 이 매개변수는 적용되지 않습니다. |
+| `dynamic_partition.history_partition_num` | 아니요 | `create_history_partition`이 `true`일 때 생성할 과거 파티션 수를 지정합니다. 기본값은 `-1`로, 설정되지 않았음을 의미합니다. 이 변수는 `dynamic_partition.start`와 동일한 효과를 가지므로 둘 중 하나만 설정하는 것이 좋습니다. |
+| `dynamic_partition.start_day_of_week` | 아니요 | `time_unit`이 `WEEK`일 때 한 주의 시작 요일을 지정합니다. 유효 범위는 1부터 7까지이며, 1은 월요일, 7은 일요일을 의미합니다. 기본값은 1로, 월요일이 한 주의 시작입니다. |
+| `dynamic_partition.start_day_of_month` | 아니요 | `time_unit`이 `MONTH`일 때 한 달의 시작일을 지정합니다. 유효 범위는 1부터 28까지이며, 1은 매월 1일, 28은 매월 28일을 의미합니다. 기본값은 1로, 매월 1일이 한 달의 시작입니다. 윤년이나 월별 일수 차이로 인한 모호함을 방지하기 위해 29일, 30일, 31일은 시작일로 지원하지 않습니다. |
+| `dynamic_partition.reserved_history_periods` | 아니요 | 보존할 과거 파티션의 시간 범위입니다. `dynamic_partition.time_unit`이 `DAY` / `WEEK` / `MONTH` / `YEAR`인 경우 값을 `[yyyy-MM-dd,yyyy-MM-dd],[...,...]` 형식으로 설정합니다. `dynamic_partition.time_unit`이 `HOUR`인 경우 값을 `[yyyy-MM-dd HH:mm:ss,yyyy-MM-dd HH:mm:ss],[...,...]` 형식으로 설정합니다. 설정하지 않으면 기본값은 `"NULL"`입니다. |
+| `dynamic_partition.time_zone` | 아니요 | 동적 파티셔닝에 사용할 시간대입니다. 기본값은 현재 서버의 시스템 시간대이며, 예를 들어 `Asia/Shanghai`입니다. 시간대 설정에 대한 자세한 내용은 [시간대 관리](../../admin-manual/cluster-management/time-zone)를 참조하세요. |
+
+### FE 구성 매개변수 {#fe-configuration-parameters}
+
+FE 구성 파일 또는 `ADMIN SET FRONTEND CONFIG` 명령을 통해 FE의 동적 파티션 매개변수를 수정할 수 있습니다.
+
+| 매개변수 | 기본값 | 설명 |
+| ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------ |
+| `dynamic_partition_enable` | false | Doris에서 동적 파티셔닝 기능을 활성화할지 여부입니다. 이 매개변수는 동적 파티션 테이블의 파티션 작업에만 영향을 주며, 일반 테이블에는 영향을 주지 않습니다. |
+| `dynamic_partition_check_interval_seconds` | 600 | 동적 파티션 스레드의 실행 주기이며, 단위는 초입니다. |
+| `max_dynamic_partition_num` | 500 | 동적 파티션 테이블 생성 시 한 번에 너무 많은 파티션이 생성되지 않도록 생성 가능한 최대 파티션 수를 제한합니다. |
+
+## 동적 파티셔닝 모범 사례 {#dynamic-partitioning-best-practices}
+
+### 예제 1: 로그 데이터의 순차적 보존 {#example-1-rolling-retention-of-log-data}
+
+일 단위로 파티션을 나누고, 최근 7일과 당일의 데이터만 보존하며, 향후 3일의 파티션을 미리 생성합니다.
+
+```sql
+CREATE TABLE tbl1 (
+ order_id BIGINT,
+ create_dt DATE,
+ username VARCHAR(20)
+)
+PARTITION BY RANGE(create_dt) ()
+DISTRIBUTED BY HASH(create_dt)
+PROPERTIES (
+ "dynamic_partition.enable" = "true",
+ "dynamic_partition.time_unit" = "DAY",
+ "dynamic_partition.start" = "-7",
+ "dynamic_partition.end" = "3",
+ "dynamic_partition.prefix" = "p",
+ "dynamic_partition.buckets" = "32"
+);
+```
+
+### 예제 2: 월 단위 파티셔닝 및 모든 과거 파티션 보존 {#example-2-partitioning-by-month-and-retaining-all-history}
+
+월 단위로 파티션을 나누고, 과거 파티션을 삭제하지 않으며, 향후 2개월의 파티션을 미리 생성하고, 매월 3일을 시작일로 설정합니다.
+
+```sql
+CREATE TABLE tbl1 (
+ order_id BIGINT,
+ create_dt DATE,
+ username VARCHAR(20)
+)
+PARTITION BY RANGE(create_dt) ()
+DISTRIBUTED BY HASH(create_dt)
+PROPERTIES (
+ "dynamic_partition.enable" = "true",
+ "dynamic_partition.time_unit" = "MONTH",
+ "dynamic_partition.end" = "2",
+ "dynamic_partition.prefix" = "p",
+ "dynamic_partition.buckets" = "8",
+ "dynamic_partition.start_day_of_month" = "3"
+);
+```
+
+### 예제 3: 지정된 과거 시간 범위 보존 {#example-3-retaining-specified-historical-time-ranges}
+
+일 단위로 파티션을 나누고, 최근 10일 및 향후 10일의 파티션을 보존하며, 추가로 `[2020-06-01, 2020-06-20]` 및 `[2020-10-31, 2020-11-15]` 기간의 과거 데이터를 보존합니다.
+
+```sql
+CREATE TABLE tbl1 (
+ order_id BIGINT,
+ create_dt DATE,
+ username VARCHAR(20)
+)
+PARTITION BY RANGE(create_dt) ()
+DISTRIBUTED BY HASH(create_dt)
+PROPERTIES (
+ "dynamic_partition.enable" = "true",
+ "dynamic_partition.time_unit" = "DAY",
+ "dynamic_partition.start" = "-10",
+ "dynamic_partition.end" = "10",
+ "dynamic_partition.prefix" = "p",
+ "dynamic_partition.buckets" = "8",
+ "dynamic_partition.reserved_history_periods" = "[2020-06-01,2020-06-20],[2020-10-31,2020-11-15]"
+);
+```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-partitioning/manual-partitioning.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-partitioning/manual-partitioning.md
new file mode 100644
index 00000000000..1d42ebbc80c
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-partitioning/manual-partitioning.md
@@ -0,0 +1,256 @@
+---
+{
+ "title": "수동 파티셔닝",
+ "language": "ko",
+ "description": "Doris의 수동 파티셔닝 가이드: Range 파티셔닝, List 파티셔닝, NULL 파티셔닝의 상세 구문과 사용 사례를 설명하고, 네 가지 Range 파티션 형식(FIXED RANGE, LESS THAN, BATCH RANGE, MULTI RANGE)의 예제를 제공합니다."
+}
+---
+
+<!-- Knowledge type: Operational steps / Configuration parameters -->
+<!-- Applicable scenario: Table design / Data partitioning planning -->
+
+수동 파티셔닝은 사용자가 테이블을 생성할 때 파티션 규칙을 명시적으로 지정하는 파티셔닝 방식입니다. 이 문서에서는 Doris에서 수동 파티셔닝을 사용하는 방법과 함께 Range 파티셔닝, List 파티셔닝, NULL 파티셔닝의 구문, 사용 사례, 모범 사례를 설명합니다.
+
+## 파티션 컬럼 규칙 {#partition-column-rules}
+
+수동 파티셔닝을 사용하기 전에 파티션 컬럼에 적용되는 일반 규칙을 알아두어야 합니다.
+
+- 파티션 컬럼은 하나 이상의 컬럼으로 구성할 수 있으며, 반드시 KEY 컬럼이어야 합니다.
+- 파티션 컬럼의 타입에 관계없이 파티션 값을 작성할 때는 큰따옴표로 묶어야 합니다.
+- 파티션 수에는 이론적인 상한이 없습니다. 다만 기본적으로 테이블당 파티션 수는 4096개로 제한됩니다. 이 제한을 초과하려면 FE 설정 `max_multi_partition_num`과 `max_dynamic_partition_num`을 수정하세요.
+- 파티셔닝을 지정하지 않고 테이블을 생성하면 시스템이 테이블과 이름이 같고 전체 값 범위를 포함하는 단일 파티션을 자동으로 생성합니다. 이 파티션은 사용자에게 표시되지 않으며 수정하거나 삭제할 수 없습니다.
+- 범위가 겹치는 파티션은 생성할 수 없습니다.
+
+## Range 파티셔닝 {#range-partitioning}
+
+Range 파티셔닝은 파티션 컬럼의 값 범위에 따라 데이터를 서로 다른 파티션으로 나눕니다. 파티션 컬럼으로는 일반적으로 시간 컬럼을 사용하므로 이전 데이터와 새 데이터를 쉽게 관리할 수 있습니다.
+
+**지원되는 컬럼 타입:** `DATE`, `DATETIME`, `TIMESTAMP_NS`, `TIMESTAMPTZ`, `TINYINT`, `SMALLINT`, `INT`, `BIGINT`, `LARGEINT`.
+
+Range 파티셔닝은 다양한 상황에 맞게 다음 네 가지 형식을 지원합니다.
+
+| 형식 | 사용 사례 |
+|------|----------|
+| FIXED RANGE | 각 파티션의 상한과 하한을 정밀하게 제어해야 할 때 |
+| LESS THAN | 파티션의 상한만 지정하고 시간순으로 파티션을 추가할 때 |
+| BATCH RANGE | 동일한 간격으로 숫자 또는 시간 파티션을 일괄 생성할 때 |
+| MULTI RANGE | 시간 범위마다 서로 다른 간격을 적용하여 일괄 생성할 때 |
+
+### 1. FIXED RANGE {#1-fixed-range}
+
+파티션에 대해 왼쪽 끝은 포함하고 오른쪽 끝은 제외하는 구간을 정의합니다.
+
+**구문:**
+
+```sql
+PARTITION BY RANGE(col1[, col2, ...])
+(
+ PARTITION partition_name1 VALUES [("k1-lower1", "k2-lower1", "k3-lower1",...), ("k1-upper1", "k2-upper1", "k3-upper1", ...)),
+ PARTITION partition_name2 VALUES [("k1-lower1-2", "k2-lower1-2", ...), ("k1-upper1-2", MAXVALUE, ))
+)
+```
+
+**예제:**
+
+```sql
+PARTITION BY RANGE(`date`)
+(
+ PARTITION `p201701` VALUES [("2017-01-01"), ("2017-02-01")),
+ PARTITION `p201702` VALUES [("2017-02-01"), ("2017-03-01")),
+ PARTITION `p201703` VALUES [("2017-03-01"), ("2017-04-01"))
+)
+```
+
+### 2. LESS THAN {#2-less-than}
+
+파티션의 상한만 정의합니다. 하한은 이전 파티션의 상한에 따라 결정됩니다.
+
+**구문:**
+
+```sql
+PARTITION BY RANGE(col1[, col2, ...])
+(
+ PARTITION partition_name1 VALUES LESS THAN MAXVALUE | ("value1", "value2", ...),
+ PARTITION partition_name2 VALUES LESS THAN MAXVALUE | ("value1", "value2", ...)
+)
+```
+
+**예제:**
+
+```sql
+PARTITION BY RANGE(`date`)
+(
+ PARTITION `p201701` VALUES LESS THAN ("2017-02-01"),
+ PARTITION `p201702` VALUES LESS THAN ("2017-03-01"),
+ PARTITION `p201703` VALUES LESS THAN ("2017-04-01"),
+ PARTITION `p2018` VALUES [("2018-01-01"), ("2019-01-01")),
+ PARTITION `other` VALUES LESS THAN (MAXVALUE)
+)
+```
+
+### 3. BATCH RANGE {#3-batch-range}
+
+숫자 및 시간 타입의 RANGE 파티션을 일괄 생성합니다. 지정된 간격에 따라 각 파티션에 대해 왼쪽 끝은 포함하고 오른쪽 끝은 제외하는 구간을 정의합니다.
+
+**구문:**
+
+```sql
+PARTITION BY RANGE(int_col)
+(
+ FROM (start_num) TO (end_num) INTERVAL interval_value
+)
+
+PARTITION BY RANGE(date_col)
+(
+ FROM ("start_date") TO ("end_date") INTERVAL num YEAR | num MONTH | num WEEK | num DAY | 1 HOUR
+)
+```
+
+**예제:**
+
+```sql
+PARTITION BY RANGE(age)
+(
+ FROM (1) TO (100) INTERVAL 10
+)
+
+PARTITION BY RANGE(`date`)
+(
+ FROM ("2000-11-14") TO ("2021-11-14") INTERVAL 2 YEAR
+)
+```
+
+### 4. MULTI RANGE {#4-multi-range}
+
+왼쪽 끝은 포함하고 오른쪽 끝은 제외하는 구간으로 RANGE 파티션을 일괄 생성하며, 동일한 문 안에서 서로 다른 간격을 지정할 수 있습니다.
+
+**예제:**
+
+```sql
+PARTITION BY RANGE(col)
+(
+ FROM ("2000-11-14") TO ("2021-11-14") INTERVAL 1 YEAR,
+ FROM ("2021-11-14") TO ("2022-11-14") INTERVAL 1 MONTH,
+ FROM ("2022-11-14") TO ("2023-01-03") INTERVAL 1 WEEK,
+ FROM ("2023-01-03") TO ("2023-01-14") INTERVAL 1 DAY,
+ PARTITION p_20230114 VALUES [('2023-01-14'), ('2023-01-15'))
+)
+```
+
+## List 파티셔닝 {#list-partitioning}
+
+List 파티셔닝은 파티션 컬럼에 대해 열거한 값에 따라 데이터를 서로 다른 파티션으로 나눕니다. 행의 값이 해당 파티션에 정의된 열거 값 중 하나와 일치하는 경우에만 그 파티션으로 라우팅됩니다.
+
+**지원되는 컬럼 타입:** `BOOLEAN`, `TINYINT`, `SMALLINT`, `INT`, `BIGINT`, `LARGEINT`, `DATE`, `DATETIME`, `TIMESTAMP_NS`, `TIMESTAMPTZ`, `CHAR`, `VARCHAR`.
+
+**구문 키워드:** `VALUES IN (...)`을 사용하여 각 파티션에 포함되는 열거 값을 지정합니다.
+
+### 단일 컬럼 List 파티셔닝 {#single-column-list-partitioning}
+
+```sql
+PARTITION BY LIST(city)
+(
+ PARTITION `p_cn` VALUES IN ("Beijing", "Shanghai", "Hong Kong"),
+ PARTITION `p_usa` VALUES IN ("New York", "San Francisco"),
+ PARTITION `p_jp` VALUES IN ("Tokyo")
+)
+```
+
+### 다중 컬럼 List 파티셔닝 {#multi-column-list-partitioning}
+
+```sql
+PARTITION BY LIST(id, city)
+(
+ PARTITION p1_city VALUES IN (("1", "Beijing"), ("1", "Shanghai")),
+ PARTITION p2_city VALUES IN (("2", "Beijing"), ("2", "Shanghai")),
+ PARTITION p3_city VALUES IN (("3", "Beijing"), ("3", "Shanghai"))
+)
+```
+
+## NULL 파티셔닝 {#null-partitioning}
+
+기본적으로 파티션 컬럼은 NOT NULL이어야 합니다. NULL을 허용하는 컬럼을 파티션 컬럼으로 사용하려면 다음 세션 변수를 설정하세요.
+
+```sql
+SET allow_partition_column_nullable = true;
+```
+
+파티션 타입별 NULL 값 처리 방식은 다음과 같습니다.
+
+| 파티션 타입 | NULL 값 처리 방식 |
+|----------|-------------|
+| LIST 파티션 | 실제 NULL 파티션 지원 |
+| RANGE 파티션(LESS THAN 사용) | NULL 값은 가장 작은 LESS THAN 파티션에 저장됨 |
+| RANGE 파티션(LESS THAN 미사용) | NULL 값을 삽입할 수 없음 |
+
+### 시나리오 1: LIST 파티션의 NULL 지원 {#scenario-1-list-partition-supports-null}
+
+```sql
+mysql> create table null_list(
+ -> k0 varchar null
+ -> )
+ -> partition by list (k0)
+ -> (
+ -> PARTITION pX values in ((NULL))
+ -> )
+ -> DISTRIBUTED BY HASH(`k0`) BUCKETS 1
+ -> properties("replication_num" = "1");
+Query OK, 0 rows affected (0.11 sec)
+
+mysql> insert into null_list values (null);
+Query OK, 1 row affected (0.19 sec)
+
+mysql> select * from null_list;
++------+
+| k0 |
++------+
+| NULL |
++------+
+1 row in set (0.18 sec)
+```
+
+### 시나리오 2: RANGE 파티션에서 NULL을 가장 작은 LESS THAN 파티션으로 라우팅 {#scenario-2-range-partition-routes-null-to-the-smallest-less-than-partition}
+
+```sql
+mysql> create table null_range(
+ -> k0 int null
+ -> )
+ -> partition by range (k0)
+ -> (
+ -> PARTITION p10 values less than (10),
+ -> PARTITION p100 values less than (100),
+ -> PARTITION pMAX values less than (maxvalue)
+ -> )
+ -> DISTRIBUTED BY HASH(`k0`) BUCKETS 1
+ -> properties("replication_num" = "1");
+Query OK, 0 rows affected (0.12 sec)
+
+mysql> insert into null_range values (null);
+Query OK, 1 row affected (0.19 sec)
+
+mysql> select * from null_range partition(p10);
++------+
+| k0 |
++------+
+| NULL |
++------+
+1 row in set (0.18 sec)
+```
+
+### 시나리오 3: LESS THAN을 사용하지 않는 RANGE 파티션에는 NULL을 삽입할 수 없음 {#scenario-3-range-partition-without-less-than-cannot-accept-null}
+
+```sql
+mysql> create table null_range2(
+ -> k0 int null
+ -> )
+ -> partition by range (k0)
+ -> (
+ -> PARTITION p200 values [("100"), ("200"))
+ -> )
+ -> DISTRIBUTED BY HASH(`k0`) BUCKETS 1
+ -> properties("replication_num" = "1");
+Query OK, 0 rows affected (0.13 sec)
+
+mysql> insert into null_range2 values (null);
+ERROR 5025 (HY000): Insert has filtered data in strict mode, tracking_url=......
+```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-partitioning/overview.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-partitioning/overview.md
new file mode 100644
index 00000000000..1f3e49cfa98
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-partitioning/overview.md
@@ -0,0 +1,95 @@
+---
+{
+ "title": "파티셔닝과 버키팅",
+ "language": "ko",
+ "description": "쿼리 필터, 데이터 분포, 보존 요구 사항에 따라 Doris 테이블의 파티셔닝과 버키팅을 선택합니다."
+}
+---
+
+Doris는 테이블을 두 단계로 구성합니다. 파티션은 컬럼 값을 기준으로 행을 나누고, 버킷은 병렬 처리를 위해 각 파티션을 태블릿으로 나눕니다. 쿼리 필터, 데이터 분포, 보존 요구 사항에 따라 설계를 선택하세요.
+
+## 시계열 데이터 설계의 시작점 {#starting-point-for-time-series-data}
+
+지속적으로 유입되는 시계열 데이터의 경우, 자동 파티셔닝을 사용하면 행이 유입될 때 시간별 파티션을 생성할 수 있습니다. 다음 예제에서는 일별 파티션과 자동 버킷 크기 조정을 사용합니다.
+
+데이터베이스와 테이블을 생성할 권한이 있는 계정으로 MySQL 클라이언트에 연결하세요. 이 예제에서는 BE가 하나인 개발 클러스터에서도 실행할 수 있도록 복제본을 하나만 사용합니다. 프로덕션 환경에서는 적절한 복제본 수를 선택하세요.
+
+```sql
+CREATE DATABASE IF NOT EXISTS partition_demo;
+USE partition_demo;
+
+CREATE TABLE sales (
+ sale_time DATETIME NOT NULL,
+ order_id BIGINT NOT NULL,
+ amount DECIMAL(10, 2)
+)
+DUPLICATE KEY(sale_time, order_id)
+AUTO PARTITION BY RANGE (date_trunc(sale_time, 'day')) ()
+DISTRIBUTED BY HASH(order_id) BUCKETS AUTO
+PROPERTIES (
+ "replication_num" = "1",
+ "estimate_partition_size" = "1G"
+);
+
+INSERT INTO sales VALUES
+ ('2026-10-14 10:00:00', 1, 12.50),
+ ('2026-10-15 11:00:00', 2, 20.00);
+
+SELECT COUNT(*) AS row_count FROM sales;
+```
+
+```text
++-----------+
+| row_count |
++-----------+
+| 2 |
++-----------+
+```
+
+데이터 적재 시 일별 파티션 두 개가 생성됩니다. `BUCKETS AUTO`는 예상 파티션 크기와 클러스터 리소스를 바탕으로 버킷 수를 선택하며, 기존 파티션의 크기는 변경하지 않습니다. 작은 파티션이 너무 많이 생성되지 않도록 파티션 간격을 선택하세요. 작은 참조 테이블이나 시간 기반 필터링 또는 보존 정책이 필요하지 않은 테이블은 단일 파티션을 사용할 수 있습니다.
+
+## 설계 선택 {#choose-your-design}
+
+| 설계 항목 | 기본 선택 | 다른 옵션을 선택할 때 |
+| --- | --- | --- |
+| 파티셔닝 | 시간 또는 목록 파티션을 필요할 때 생성하는 [자동 파티셔닝](./auto-partitioning) | 사용자 지정 범위, 숫자 범위 또는 그룹화된 LIST 값이 필요하면 [수동 파티셔닝](./manual-partitioning)을 사용하세요. 일정에 따른 생성과 이동 시간 윈도우가 필요하면 [동적 파티셔닝](./dynamic-partitioning)을 사용하세요. |
+| 버키팅 방식 | 동등 조건 필터에 적합하고 데이터를 고르게 분산하는 컬럼을 기준으로 해시 버키팅 | 랜덤 버키팅은 DUPLICATE 테이블의 데이터 쏠림을 줄일 수 있지만, 버킷 프루닝은 지원하지 않습니다. [데이터 버키팅](./data-bucketing)을 참조하세요. |
+| 버킷 수 | 대표적인 `BUCKETS AUTO` 설정과 `estimate_partition_size` 값 | 명시적인 제어가 필요하면 고정된 개수를 사용하세요. 태블릿 크기와 쿼리 병렬성을 고려하면서 태블릿 관리 오버헤드와 균형을 맞추세요. |
+
+## 오래된 파티션 만료 처리 {#expire-old-partitions}
+
+각 보존 모드는 서로 다른 정책을 나타냅니다.
+
+| 파티션 모드 | 속성 | 보존 규칙 |
+| --- | --- | --- |
+| [동적 파티셔닝](./dynamic-partitioning) | `dynamic_partition.start`(예: `-7`) | 설정된 시간 단위와 시간대를 사용하여 현재 시간을 기준으로 하는 시간 윈도우 |
+| [자동 파티셔닝](./auto-partitioning)(RANGE) | `partition.retention_count`(예: `3`) | 파티션 값을 기준으로 가장 최근의 **과거** 파티션 N개를 유지하며, 현재 및 미래 파티션도 유지 |
+
+파티션 수만으로는 경과 시간을 보장할 수 없습니다. 데이터가 드물게 유입되거나 오래된 데이터만 있는 경우, 가장 최근의 과거 파티션 N개가 N일보다 훨씬 오래되었을 수 있습니다. 데이터가 일정 기간이 지나면 반드시 만료되어야 하는 경우에는 시간 윈도우를 선택하세요.
+
+예제 테이블에 다음 정책을 적용하면 현재 및 미래 파티션과 함께 가장 최근의 과거 파티션 세 개를 유지합니다.
+
+```sql
+ALTER TABLE partition_demo.sales SET ("partition.retention_count" = "3");
+```
+
+이후 FE 스케줄러가 보존 개수를 초과하는 과거 파티션을 삭제합니다. 이 속성은 AUTO RANGE 테이블에만 적용되며, 동적 파티셔닝이 활성화된 상태에서는 함께 사용할 수 없습니다. 스케줄링 동작과 Doris 4.1.4의 변경 사항을 포함한 버전별 제한 사항은 [자동 파티셔닝: 수명 주기 관리](./auto-partitioning#lifecycle-management)를 참조하세요.
+
+보존 정책을 적용하면 데이터가 **삭제**됩니다. 콜드 데이터를 유지하면서 더 저렴한 스토리지로 이동하려면 [계층형 스토리지](../tiered-storage/overview)를 사용하세요.
+
+## 작동 방식 {#how-it-works}
+
+```text
+Table → Partition (by column value) → Bucket (hash or random) → Tablet (shard on a BE node)
+```
+
+파티션은 쿼리 프루닝과 데이터 수명 주기 관리를 지원합니다. 버킷은 병렬 읽기와 쓰기를 제공합니다. 태블릿, 복제본, 노드 배치 및 운영 명령은 [파티셔닝과 버키팅의 작동 방식](./basic-concepts)을 참조하세요.
+
+## 다음 단계 {#next-steps}
+
+- [자동 파티셔닝](./auto-partitioning): 필요할 때 파티션 생성.
+- [동적 파티셔닝](./dynamic-partitioning): 일정에 따른 생성과 이동 시간 윈도우.
+- [수동 파티셔닝](./manual-partitioning): 명시적인 범위와 목록 파티션.
+- [데이터 버키팅](./data-bucketing): 방식, 키 및 버킷 수 선택.
+- [파티셔닝과 버키팅의 작동 방식](./basic-concepts): 데이터 분산 모델.
+- [일반적인 문제](./common-issues): 파티션 및 버킷 설계 문제 해결.
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-type.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-type.md
new file mode 100644
index 00000000000..6bfbbf1e839
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/data-type.md
@@ -0,0 +1,72 @@
+---
+{
+ "title": "데이터 타입",
+ "language": "ko",
+ "description": "Apache Doris에서 지원하는 데이터 타입 목록은 다음과 같습니다:"
+}
+---
+
+Apache Doris에서 지원하는 데이터 타입 목록은 다음과 같습니다:
+
+### [숫자 타입](../sql-manual/basic-element/sql-data-types/data-type-overview#numeric-types) {#numeric-types}
+
+
+| 타입 이름 | 저장 크기(바이트) | 설명 |
+| -------------- | --------- | ------------------------------------------------------------ |
+| [BOOLEAN](../sql-manual/basic-element/sql-data-types/numeric/BOOLEAN) | 1 | 불리언 값입니다. 0은 false를, 1은 true를 나타냅니다. |
+| [TINYINT](../sql-manual/basic-element/sql-data-types/numeric/TINYINT) | 1 | 부호 있는 정수이며, 범위는 [-128, 127]입니다. |
+| [SMALLINT](../sql-manual/basic-element/sql-data-types/numeric/SMALLINT) | 2 | 부호 있는 정수이며, 범위는 [-32768, 32767]입니다. |
+| [INT](../sql-manual/basic-element/sql-data-types/numeric/INT) | 4 | 부호 있는 정수이며, 범위는 [-2147483648, 2147483647]입니다. |
+| [BIGINT](../sql-manual/basic-element/sql-data-types/numeric/BIGINT) | 8 | 부호 있는 정수이며, 범위는 [-9223372036854775808, 9223372036854775807]입니다. |
+| [LARGEINT](../sql-manual/basic-element/sql-data-types/numeric/LARGEINT) | 16 | 부호 있는 정수이며, 범위는 [-2^127 + 1 ~ 2^127 - 1]입니다. |
+| [FLOAT](../sql-manual/basic-element/sql-data-types/numeric/FLOATING-POINT) | 4 | 부동 소수점 수이며, 범위는 [-3.4*10^38 ~ 3.4*10^38]입니다. |
+| [DOUBLE](../sql-manual/basic-element/sql-data-types/numeric/FLOATING-POINT) | 8 | 부동 소수점 수이며, 범위는 [-1.79*10^308 ~ 1.79*10^308]입니다. |
+| [DECIMAL](../sql-manual/basic-element/sql-data-types/numeric/DECIMAL) | 4/8/16/32 | 고정밀 고정 소수점 수입니다. 형식: DECIMAL(P[,S]). P는 전체 유효 자릿수(precision)를, S는 소수점 이하 자릿수(scale)를 나타냅니다. P의 범위는 [1, MAX_P]입니다. `enable_decimal256`=false이면 MAX_P=38이고, `enable_decimal256`=true이면 MAX_P=76입니다. S의 범위는 [0, P]입니다.<br>`enable_decimal256`의 기본값은 false입니다. true로 설정하면 결과의 정밀도가 높아지지만 성능 오버헤드가 발생합니다.<br>저장 크기:<ul><li>0 < precision <= 9이면 4바이트를 차지합니다.</li><li>9 < precision <= 18이면 8바이트를 차지합니다.</li><li>1 [...]
+
+### [날짜 타입](../sql-manual/basic-element/sql-data-types/data-type-overview#date-types) {#date-types}
+
+| 타입 이름 | 저장 크기(바이트) | 설명 |
+| --------------------- | ---------------- | ------------------------------------------------------------------------------------------ |
+| [DATE](../sql-manual/basic-element/sql-data-types/date-time/DATE) | 4 | 날짜 타입입니다. 현재 값의 범위는 ['0000-01-01', '9999-12-31']이며, 기본 출력 형식은 'yyyy-MM-dd'입니다. |
+| [DATETIME](../sql-manual/basic-element/sql-data-types/date-time/DATETIME) | 8 | 날짜 및 시간 타입입니다. 형식: DATETIME([P]). 선택적 매개변수 P는 시간 정밀도를 나타내며, 값의 범위는 [0, 6]으로 소수점 이하 최대 6자리(마이크로초)까지 지원합니다. 설정하지 않으면 기본값은 0입니다.<br />값의 범위는 ['0000-01-01 00:00:00[.000000]', '9999-12-31 23:59:59[.999999]']입니다. 출력 형식은 'yyyy-MM-dd HH:mm:ss.SSSSSS'입니다. |
+| [TIMESTAMP_NS](../sql-manual/basic-element/sql-data-types/date-time/TIMESTAMP-NS) | 8 | 시간대 정보가 없고 나노초 정밀도가 고정된 날짜 및 시간 타입입니다. 범위는 ['1677-09-21 00:12:43.145224192', '2262-04-11 23:47:16.854775807']입니다. 출력 형식은 'yyyy-MM-dd HH:mm:ss.SSSSSSSSS'입니다. |
+
+### [문자열 타입](../sql-manual/basic-element/sql-data-types/data-type-overview#string-types) {#string-types}
+
+| 타입 이름 | 저장 크기(바이트) | 설명 |
+| -------------- | --------- | ------------------------------------------------------------ |
+| [CHAR](../sql-manual/basic-element/sql-data-types/string-type/CHAR) | M | 고정 길이 문자열입니다. M은 고정 길이 문자열의 바이트 길이를 나타냅니다. M의 범위는 1-255입니다. |
+| [VARCHAR](../sql-manual/basic-element/sql-data-types/string-type/VARCHAR) | 가변 | 가변 길이 문자열입니다. M은 가변 길이 문자열의 바이트 길이를 나타냅니다. M의 범위는 1-65533입니다. 가변 길이 문자열은 UTF-8 인코딩으로 저장되므로 일반적으로 영문자 하나는 1바이트를, 한자는 3바이트를 차지합니다. |
+| [STRING](../sql-manual/basic-element/sql-data-types/string-type/STRING) | 가변 | 가변 길이 문자열입니다. 기본적으로 1048576바이트(1MB)를 지원하며, 최대 2147483643바이트(2GB)까지 늘릴 수 있습니다. BE 설정 `string_type_length_soft_limit_bytes`로 조정할 수 있습니다. String 타입은 Value 열에서만 사용할 수 있으며, Key 열이나 파티션/버킷팅 열에는 사용할 수 없습니다. |
+
+### [반정형 타입](../sql-manual/basic-element/sql-data-types/data-type-overview#semi-structured-types) {#semi-structured-types}
+| 타입 이름 | 저장 크기(바이트) | 설명 |
+| -------------- | --------- | ------------------------------------------------------------ |
+| [ARRAY](../sql-manual/basic-element/sql-data-types/semi-structured/ARRAY) | 가변 | T 타입의 원소로 구성된 배열입니다. Key 열로 사용할 수 없습니다. 현재 Duplicate 및 Unique 모델의 테이블에서 지원됩니다. |
+| [MAP](../sql-manual/basic-element/sql-data-types/semi-structured/MAP) | 가변 | K와 V 타입의 원소로 구성된 맵입니다. Key 열로 사용할 수 없습니다. 현재 Duplicate 및 Unique 모델의 테이블에서 지원됩니다. |
+| [STRUCT](../sql-manual/basic-element/sql-data-types/semi-structured/STRUCT) | 가변 | 여러 필드로 구성된 구조체이며, 여러 열의 집합으로 볼 수도 있습니다. Key로 사용할 수 없습니다. 현재 STRUCT는 Duplicate 모델의 테이블에서만 지원됩니다. Struct의 필드 이름과 개수는 고정되어 있으며, 필드는 항상 Nullable입니다.|
+| [JSON](../sql-manual/basic-element/sql-data-types/semi-structured/JSON) | 가변 | 바이너리 JSON 타입입니다. 바이너리 JSON 형식으로 저장되며, JSON 함수로 JSON 내부 필드에 접근합니다. 길이 제한과 설정 방법은 String과 동일합니다. |
+| [VARIANT](../sql-manual/basic-element/sql-data-types/semi-structured/VARIANT) | 가변 | JSON과 같은 반정형 데이터를 위해 설계된 동적 가변 데이터 타입입니다. 모든 JSON을 저장할 수 있으며, 저장 시 JSON의 필드를 자동으로 하위 열로 분리하여 저장 효율과 쿼리 분석 성능을 높입니다. 길이 제한과 설정 방법은 String과 동일합니다. Variant 타입은 Value 열에서만 사용할 수 있으며, Key 열이나 파티션/버킷팅 열에는 사용할 수 없습니다.|
+
+### [집계 타입](../sql-manual/basic-element/sql-data-types/data-type-overview#aggregation-types) {#aggregate-types}
+
+| 타입 이름 | 저장 크기(바이트) | 설명 |
+| -------------- | --------- | ------------------------------------------------------------ |
+| [HLL](../sql-manual/basic-element/sql-data-types/aggregate/HLL) | 가변 | HLL은 근사 방식으로 중복을 제거합니다. 데이터 양이 많을 때 Count Distinct보다 성능이 좋습니다. HLL의 오차는 일반적으로 약 1%이며, 때로는 2%에 이르기도 합니다. HLL은 Key 열로 사용할 수 없으며, 테이블 생성 시 집계 타입을 HLL_UNION으로 지정해야 합니다. 사용자가 길이와 기본값을 지정할 필요는 없습니다. 길이는 시스템이 데이터의 집계 정도에 따라 내부적으로 제어합니다. HLL 열은 해당 `hll_union_agg`, `hll_raw_agg`, `hll_cardinality`, `hll_hash` 함수를 통해서만 쿼리하거나 사용할 수 있습니다.|
+| [BITMAP](../sql-manual/basic-element/sql-data-types/aggregate/BITMAP) | 가변 | Bitmap 타입의 열은 Aggregate 테이블, Unique 테이블 또는 Duplicate 테이블에서 사용할 수 있습니다. Unique 테이블이나 Duplicate 테이블에서는 Key가 아닌 열로 사용해야 합니다. Aggregate 테이블에서도 Key가 아닌 열로 사용해야 하며, 테이블 생성 시 집계 타입을 BITMAP_UNION으로 지정해야 합니다. 사용자가 길이와 기본값을 지정할 필요는 없습니다. 길이는 시스템이 데이터의 집계 정도에 따라 내부적으로 제어합니다. BITMAP 열은 해당 `bitmap_union_count`, `bitmap_union`, `bitmap_hash`, `bitmap_hash64` 등의 함수를 통해서만 쿼리하거나 사용할 수 있습니다. |
+| [QUANTILE_STATE](../sql-manual/basic-element/sql-data-types/aggregate/QUANTILE-STATE) | 가변 | QUANTILE_STATE는 근사 분위수 값을 계산하는 데 사용하는 타입입니다. 데이터 적재 중에 동일한 Key에 대한 서로 다른 Value를 사전 집계합니다. 값의 개수가 2048을 넘지 않으면 모든 데이터를 상세히 기록합니다. 값의 개수가 2048을 넘으면 TDigest 알고리즘을 사용하여 데이터를 집계(클러스터링)하고, 클러스터링 후의 중심점을 저장합니다. QUANTILE_STATE는 Key 열로 사용할 수 없으며, 테이블 생성 시 집계 타입을 QUANTILE_UNION으로 지정해야 합니다. 사용자가 길이와 기본값을 지정할 필요는 없습니다. 길이는 시스템이 데이터의 집계 정도에 따라 내부적으로 제어합니다. QUANTILE_STATE 열은 해당 `QUANTILE_PERCENT`, `QUANT [...]
+| [AGG_STATE](../sql-manual/basic-element/sql-data-types/aggregate/AGG-STATE) | 가변 | 집계 함수입니다. state/merge/union 함수 조합자와 함께만 사용할 수 있습니다. AGG_STATE는 Key 열로 사용할 수 없으며, 테이블 생성 시 집계 함수의 시그니처도 함께 선언해야 합니다. 사용자가 길이와 기본값을 지정할 필요는 없습니다. 저장되는 데이터의 실제 크기는 함수 구현에 따라 달라집니다. |
+
+### [IP 타입](../sql-manual/basic-element/sql-data-types/data-type-overview#ip-types) {#ip-types}
+| 타입 이름 | 저장 크기(바이트) | 설명 |
+| -------------- | --------- | ------------------------------------------------------------ |
+| [IPv4](../sql-manual/basic-element/sql-data-types/ip/IPV4) | 4바이트 | IPv4 주소를 4바이트의 바이너리 데이터로 저장하며, `ipv4_*` 계열 함수와 함께 사용합니다. |
+| [IPv6](../sql-manual/basic-element/sql-data-types/ip/IPV6) | 16바이트 | IPv6 주소를 16바이트의 바이너리 데이터로 저장하며, `ipv6_*` 계열 함수와 함께 사용합니다. |
+
+### [UUID](../sql-manual/basic-element/sql-data-types/uuid.md) {#uuid}
+
+| 타입 이름 | 저장 크기(바이트) | 설명 |
+| --- | --- | --- |
+| [UUID](../sql-manual/basic-element/sql-data-types/uuid.md) | 16 | 네이티브 128비트 식별자이며, 소문자 정규 형식의 텍스트로 표시됩니다. |
+
+`SHOW DATA TYPES;` 문으로 Apache Doris에서 지원하는 모든 데이터 타입을 확인할 수도 있습니다.
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/bloomfilter.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/bloomfilter.md
new file mode 100644
index 00000000000..f55a99e84c1
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/bloomfilter.md
@@ -0,0 +1,135 @@
+---
+{
+ "title": "BloomFilter 인덱스",
+ "language": "ko",
+ "description": "BloomFilter 인덱스는 BloomFilter 알고리즘을 기반으로 하는 Doris의 스킵 인덱스입니다. 조건을 충족하지 않는 데이터 블록을 건너뛰어 I/O 오버헤드를 줄이고 동등 조건 쿼리(= 및 IN)를 가속합니다."
+}
+---
+
+<!-- Knowledge type: Feature introduction + Usage guide -->
+<!-- Applicable scenario: Accelerating equality queries on high-cardinality columns -->
+
+BloomFilter 인덱스는 BloomFilter 알고리즘을 기반으로 하는 **스킵 인덱스**입니다. 쿼리 값이 데이터 블록에 존재할 가능성을 빠르게 판단하고, 동등 조건을 충족하지 않는 데이터 블록을 건너뛰어 I/O 오버헤드를 줄이고 쿼리를 가속합니다.
+
+### BloomFilter 알고리즘 원리 {#bloomfilter-algorithm-principles}
+
+BloomFilter는 Bloom이 1970년에 제안한, 여러 해시 함수의 매핑을 기반으로 하는 빠른 조회 알고리즘입니다. 핵심 특징은 다음과 같습니다.
+
+- **높은 공간 효율성**: 긴 이진 비트 배열과 해시 함수 집합으로 하나의 집합을 표현할 수 있습니다.
+- **쿼리 결과**: 집합에 특정 원소가 존재하는지 조회하면 BloomFilter는 다음 두 가지 결과 중 하나만 반환합니다.
+ - **존재할 가능성 있음**(해시 충돌이 발생할 수 있으므로 거짓 양성일 수 있음)
+ - **확실히 존재하지 않음**(신뢰할 수 있는 결과)
+
+동작 과정은 다음과 같습니다.
+
+
+
+1. 이진 비트 배열의 모든 비트를 영으로 초기화합니다.
+2. 원소를 삽입할 때는 여러 해시 함수로 원소를 해싱하여 여러 오프셋을 계산하고, 비트 배열의 해당 위치를 1로 설정합니다.
+3. 원소를 조회할 때도 같은 방식으로 오프셋을 계산합니다. 해당 위치 중 하나라도 0이면 원소는 확실히 존재하지 않습니다. 모든 위치가 1이면 원소가 존재할 가능성이 있습니다.
+
+다음 그림은 m=18, k=3인 BloomFilter 예제입니다(m은 비트 배열의 크기, k는 해시 함수의 수). 집합에 있는 세 원소 x, y, z는 서로 다른 3개의 해시 함수를 통해 비트 배열에 매핑됩니다. 원소 w를 조회할 때, 대응하는 비트 중 적어도 하나가 0이므로 w는 확실히 집합에 없습니다.
+
+
+
+해시 충돌이 발생할 수 있으므로 BloomFilter에는 "거짓 양성" 문제가 있습니다. 따라서 **BloomFilter 기반 인덱스는 조건을 충족하지 않는 것이 확실한 데이터만 건너뛸 수 있으며, 조건을 충족하는 데이터의 위치를 정확하게 찾을 수는 없습니다**.
+
+### Doris에서의 구현 {#implementation-in-doris}
+
+Doris의 BloomFilter 인덱스는 **데이터 블록(페이지)** 단위로 생성되며, 각 데이터 블록마다 하나의 BloomFilter가 있습니다.
+
+- **쓰기 시**: 데이터 블록의 각 값을 해싱하여 해당 데이터 블록의 BloomFilter에 저장합니다.
+- **쿼리 시**: 동등 조건의 값을 기준으로 각 데이터 블록의 BloomFilter에 해당 값이 포함되어 있는지 확인합니다. 포함되어 있지 않으면 해당 데이터 블록을 건너뛰어 I/O를 줄이고 쿼리를 가속합니다.
+
+## 사용 사례 {#use-cases}
+
+BloomFilter 인덱스는 동등 조건 쿼리(`=` 및 `IN` 포함)를 가속할 수 있으며, **카디널리티가 높은 열**(예: `userid`와 같이 고유한 ID를 저장하는 열)에 특히 적합합니다.
+
+### 적용 시나리오 {#applicable-scenarios}
+
+| 시나리오 | 설명 |
+|------|------|
+| 동등 조건 쿼리 | `WHERE column = value` |
+| IN 쿼리 | `WHERE column IN (v1, v2, ...)` |
+| 카디널리티가 높은 열 | 사용자 ID나 주문 번호처럼 서로 다른 값이 많고 중복률이 낮은 열 |
+
+### 제한 사항 {#limitations}
+
+- **쿼리 유형 제한**: `=` 및 `IN` 쿼리에만 효과가 있습니다. `!=`, `NOT IN`, `>`, `<` 등의 쿼리에는 효과가 없습니다.
+- **데이터 타입 제한**: `Tinyint`, `Float`, `Double` 타입의 열에는 BloomFilter 인덱스를 생성할 수 없습니다.
+- **카디널리티 제한**: 카디널리티가 낮은 열에서는 쿼리 가속 효과가 제한적입니다. 예를 들어, "성별" 열에는 값이 두 가지뿐이므로 거의 모든 데이터 블록에 모든 값이 포함됩니다. 이 경우 BloomFilter가 데이터를 걸러낼 수 없어 인덱스의 의미가 없어집니다.
+- **버전 제한**: 4.1.2 버전부터 `CHAR` 타입 열의 BloomFilter 인덱스는 더 이상 적용되지 않습니다.
+
+## 인덱스 관리 {#managing-indexes}
+
+### 테이블 생성 시 BloomFilter 인덱스 생성 {#creating-a-bloomfilter-index-when-creating-a-table}
+
+과거의 설계 방식으로 인해 BloomFilter 인덱스를 정의하는 구문은 역색인 등의 인덱스에 사용하는 일반적인 `INDEX` 구문과 다릅니다. BloomFilter 인덱스는 테이블의 `PROPERTIES` 속성에 있는 `bloom_filter_columns`로 지정하며, 하나 이상의 열을 한 번에 지정할 수 있습니다.
+
+```sql
+PROPERTIES (
+ "bloom_filter_columns" = "column_name1,column_name2"
+);
+```
+
+### BloomFilter 인덱스 조회 {#viewing-a-bloomfilter-index}
+
+`SHOW CREATE TABLE`을 사용하여 테이블에 생성된 BloomFilter 인덱스를 조회합니다.
+
+```sql
+SHOW CREATE TABLE table_name;
+```
+
+### BloomFilter 인덱스 수정 {#modifying-a-bloomfilter-index}
+
+`ALTER TABLE`을 사용하여 테이블의 `bloom_filter_columns` 속성을 수정하면 BloomFilter 인덱스 열을 추가하거나 제거할 수 있습니다.
+
+**column_name3에 BloomFilter 인덱스 추가**:
+
+```sql
+ALTER TABLE table_name SET ("bloom_filter_columns" = "column_name1,column_name2,column_name3");
+```
+
+**column_name1의 BloomFilter 인덱스 제거**:
+
+```sql
+ALTER TABLE table_name SET ("bloom_filter_columns" = "column_name2,column_name3");
+```
+
+## 인덱스 사용 {#using-the-index}
+
+BloomFilter 인덱스는 `WHERE` 조건의 동등 조건 쿼리를 가속하는 데 사용됩니다. 별도의 구문 없이 **조건이 충족되면 자동으로 적용됩니다**.
+
+### Query Profile로 인덱스 효과 분석 {#analyzing-index-effectiveness-with-query-profile}
+
+Query Profile의 다음 지표를 사용하여 BloomFilter 인덱스의 쿼리 가속 효과를 분석할 수 있습니다.
+
+| 지표 | 의미 |
+|------|------|
+| `RowsBloomFilterFiltered` | BloomFilter 인덱스가 걸러낸 행 수입니다. 다른 Rows 지표와 비교하여 필터링 효과를 분석할 수 있습니다. |
+| `BlockConditionsFilteredBloomFilterTime` | BloomFilter 인덱스 필터링에 소요된 시간입니다. |
+
+## 사용 예제 {#usage-example}
+
+다음 예제는 Doris에서 BloomFilter 인덱스를 생성하는 방법을 보여줍니다.
+
+CREATE TABLE 문의 `PROPERTIES`에서 `"bloom_filter_columns" = "k1,k2,k3"`로 BloomFilter 인덱스를 생성할 열 이름을 지정합니다. 예를 들어, 다음 예제에서는 `saler_id`와 `category_id` 열에 BloomFilter 인덱스를 생성합니다.
+
+```sql
+CREATE TABLE IF NOT EXISTS sale_detail_bloom (
+ sale_date date NOT NULL COMMENT "Sale time",
+ customer_id int NOT NULL COMMENT "Customer ID",
+ saler_id int NOT NULL COMMENT "Salesperson",
+ sku_id int NOT NULL COMMENT "Product ID",
+ category_id int NOT NULL COMMENT "Product category",
+ sale_count int NOT NULL COMMENT "Sales quantity",
+ sale_price DECIMAL(12,2) NOT NULL COMMENT "Unit price",
+ sale_amt DECIMAL(20,2) COMMENT "Total sales amount"
+)
+DUPLICATE KEY(sale_date, customer_id, saler_id, sku_id, category_id)
+DISTRIBUTED BY HASH(saler_id) BUCKETS 10
+PROPERTIES (
+ "replication_num" = "1",
+ "bloom_filter_columns" = "saler_id,category_id"
+);
+```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/index-overview.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/index-overview.md
new file mode 100644
index 00000000000..cdbfafe4567
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/index-overview.md
@@ -0,0 +1,141 @@
+---
+{
+ "title": "인덱스 개요",
+ "language": "ko",
+ "description": "Apache Doris 인덱스 선택 가이드: 다양한 쿼리 시나리오의 속도를 높이는 포인트 쿼리 인덱스, 건너뛰기 인덱스, 역색인, BloomFilter, NGram BloomFilter 및 기타 인덱스를 소개합니다."
+}
+---
+
+Apache Doris는 여러 유형의 인덱스로 쿼리 속도를 높입니다. 이 페이지에서는 인덱스 추가가 필요한지, 어떤 인덱스를 선택해야 하는지 판단할 수 있도록 안내하고 각 인덱스의 상세 문서 링크를 제공합니다.
+
+## 시작하기 {#start-here}
+
+모든 테이블에는 Doris가 자동으로 생성하고 유지 관리하는 두 가지 인덱스가 기본으로 제공됩니다.
+
+- 정렬 키에 생성되는 **[접두사 인덱스](./prefix-index.md)**는 선두 Key 컬럼에 대한 필터링 속도를 높입니다. 이 인덱스를 활용하려면 가장 자주 필터링하는 컬럼을 선두 Key 컬럼으로 지정하세요.
+- 모든 컬럼에 생성되는 **ZoneMap 인덱스**는 범위 필터나 동등 조건 필터에 해당하지 않는 데이터 블록을 건너뜁니다.
+
+이 두 인덱스로 쿼리 패턴을 처리하기 어려울 때만 인덱스를 수동으로 추가하세요.
+
+| 쿼리 패턴 | 권장 인덱스 | 필요한 경우 |
+| --- | --- | --- |
+| 가장 자주 사용하는 컬럼으로 필터링 | 해당 컬럼을 선두 Key 컬럼으로 지정(접두사 인덱스) | 항상 가장 먼저 설계 |
+| Key가 아닌 컬럼에 대한 동등 조건 또는 범위 필터 | [역색인](./inverted-index/overview.md) | 자주 필요 |
+| 텍스트에 대한 `LIKE` 부분 문자열 매칭 | [NGram BloomFilter 인덱스](./ngram-bloomfilter-index.md) | 경우에 따라 필요 |
+| 유연성보다 인덱스 크기가 중요한 동등 조건 필터 | [BloomFilter 인덱스](./bloomfilter.md) | 드물게 필요하며, 일반적으로 역색인을 권장 |
+| 전문 검색: 키워드, 구문 또는 여러 필드 검색 | [역색인](./inverted-index/overview.md) | 텍스트를 검색할 때 |
+| 벡터 유사도(Top-K 최근접 이웃) | [벡터 인덱스(ANN)](./vector-index/overview.md) | RAG, 의미 검색, 추천 및 미디어 검색에 사용 |
+
+쿼리가 예상보다 느리다면 QueryProfile에서 각 인덱스가 데이터를 얼마나 걸러냈는지, 시간이 얼마나 걸렸는지 확인하세요. 자세한 내용은 각 인덱스의 문서를 참고하세요.
+
+## 각 인덱스의 동작 방식 {#how-each-index-works}
+
+Apache Doris는 다양한 쿼리 시나리오에 맞춰 **포인트 쿼리 인덱스**, **건너뛰기 인덱스**, **전문 검색 인덱스**, **벡터 인덱스**의 네 가지 범주를 제공합니다.
+
+### 시나리오 1: 조건에 일치하는 행이 적은 경우(포인트 쿼리 인덱스) {#scenario-1-few-rows-match-the-condition-point-query-indexes}
+
+**적용 시나리오**: 기본 키로 조회하거나 사용자 ID로 상세 레코드를 가져오는 등 소량의 데이터를 정확하게 찾는 경우에 적합합니다.
+
+**가속 원리**: WHERE 조건을 만족하는 행의 위치를 인덱스로 직접 찾아 해당 행만 읽으므로, 행을 하나씩 스캔할 필요가 없습니다.
+
+
+
+Apache Doris는 두 가지 포인트 쿼리 인덱스를 제공합니다.
+
+- **[접두사 인덱스](./prefix-index.md)**: Doris는 데이터를 정렬 키 순서로 저장하고 1024행마다 희소 접두사 인덱스를 생성합니다. 각 인덱스 항목에는 해당 그룹의 첫 번째 행에 있는 정렬 컬럼 값이 저장됩니다. 쿼리에서 정렬 컬럼으로 필터링하면 Doris는 해당 그룹으로 바로 이동하여 그 지점부터 스캔합니다.
+- **[역색인](./inverted-index/overview.md)**: Doris는 각 값을 그 값이 포함된 행에 매핑하는 역색인 테이블을 생성합니다. 동등 조건 쿼리에서는 일치하는 행을 찾아 해당 행만 읽으므로 전체 스캔을 피하고 I/O를 줄일 수 있습니다. 역색인은 범위 필터와 텍스트 키워드 검색의 속도도 높입니다. 이 경우 알고리즘은 더 복잡하지만 기본 원리는 같습니다.
+
+:::note
+BITMAP 인덱스는 역색인으로 대체되었습니다.
+:::
+
+### 시나리오 2: 조건에 일치하는 행이 많은 경우(건너뛰기 인덱스) {#scenario-2-many-rows-match-the-condition-skip-indexes}
+
+**적용 시나리오**: 시간 범위 집계나 차원 필터링처럼 대량의 데이터를 필터링해야 하는 분석 쿼리에 적합합니다.
+
+**가속 원리**: 인덱스로 WHERE 조건을 **만족하지 않는** 데이터 블록을 식별하여 건너뛰고, 조건을 만족할 가능성이 있는 블록만 읽습니다. 그런 다음 행별로 필터링하여 최종 결과를 얻습니다.
+
+
+
+Apache Doris는 세 가지 건너뛰기 인덱스를 제공합니다.
+
+- **ZoneMap 인덱스**: Doris는 각 데이터 파일(Segment)과 데이터 블록(Page)에 대해 컬럼별 통계(min, max, NULL 존재 여부)를 자동으로 유지 관리합니다. 동등 조건, 범위 및 IS NULL 필터에서는 이 통계를 사용하여 파일이나 블록에 일치하는 행이 있을 수 있는지 판단합니다. 일치하는 행이 있을 수 없다면 해당 파일이나 블록을 건너뛰어 I/O를 줄입니다.
+- **[BloomFilter 인덱스](./bloomfilter.md)**: Doris는 매우 적은 저장 공간으로 값의 존재 여부를 확인할 수 있는 구조인 BloomFilter에 컬럼 값을 저장합니다. 동등 조건 쿼리에서 해당 값이 필터에 없으면 해당 파일이나 블록을 건너뛰어 I/O를 줄입니다.
+- **[NGram BloomFilter 인덱스](./ngram-bloomfilter-index.md)**: 텍스트 `LIKE` 쿼리의 속도를 높입니다. BloomFilter 인덱스와 같은 방식으로 동작하지만, 전체 값 대신 텍스트의 NGram 토큰을 저장합니다. `LIKE` 쿼리를 실행할 때 Doris는 패턴을 같은 방식으로 토큰화하고 각 토큰이 필터에 있는지 확인합니다. 토큰이 하나라도 없으면 해당 파일이나 블록은 조건에 일치할 수 없으므로 건너뜁니다.
+
+### 시나리오 3: 텍스트 전문 검색(역색인) {#scenario-3-full-text-search-on-text-inverted-index}
+
+**적용 시나리오**: 로그 분석, 콘텐츠 검색, 지원 티켓 분석 등 텍스트 필드에서 키워드, 구문 또는 패턴 매칭으로 데이터를 찾아야 하는 경우에 적합합니다.
+
+**가속 원리**: 토크나이저가 텍스트를 검색어 단위로 분리하고, 각 검색어를 해당 행 번호에 매핑하는 역색인 테이블을 생성합니다. 쿼리 시에는 검색할 텍스트를 같은 방식으로 토큰화하고, 각 검색어가 포함된 행 번호 집합을 역색인 테이블에서 가져와 AND/OR/NOT 관계에 따라 결합한 다음 일치하는 행을 직접 읽습니다. 따라서 원본 텍스트를 행별로 스캔하고 정규 표현식으로 매칭할 필요가 없습니다.
+
+
+
+자세한 사용 방법은 [역색인](./inverted-index/overview.md)을 참고하세요. Apache Doris 역색인은 다음 기능을 지원합니다.
+
+- **키워드 검색**: `MATCH_ANY`(단어 중 하나라도 일치)와 `MATCH_ALL`(모든 단어가 일치)을 지원합니다.
+- **구문 쿼리**: `MATCH_PHRASE`는 단어 간 허용 거리인 `slop`을 설정할 수 있으며, 순서를 구분하는 구문 매칭을 지원합니다. `MATCH_PHRASE_PREFIX`는 구문 매칭과 마지막 단어의 접두사 매칭을 함께 지원합니다. `MATCH_REGEXP`는 토큰화된 검색어에 대한 정규 표현식 매칭을 지원합니다.
+- **다국어 토큰화**: `english`, `chinese`, `unicode`, `icu`, `basic`, `ik` 등의 내장 토크나이저로 중국어, 영어, 혼합 텍스트 및 다국어 시나리오를 지원합니다.
+- **여러 컬럼을 결합한 검색**: `multi_match` 함수를 사용하여 여러 필드에 걸쳐 OR/AND/구문/접두사 검색을 수행합니다.
+- **일반 필터와의 결합**: 동등 조건, 범위, `IN` 등의 조건 및 다른 인덱스와 AND/OR/NOT으로 자유롭게 결합할 수 있으며, 동일한 역색인을 재사용하여 쿼리를 처리합니다.
+
+### 시나리오 4: 벡터 유사도 검색(벡터 인덱스) {#scenario-4-vector-similarity-search-vector-index}
+
+**적용 시나리오**: 벡터 유사도로 Top-K 최근접 이웃을 찾거나 거리 임계값으로 필터링해야 하는 RAG(검색 증강 생성), 의미 검색, 추천 시스템, 이미지/오디오/비디오 검색에 적합합니다.
+
+**가속 원리**: 기존 방식은 쿼리 벡터와 모든 레코드 간의 거리를 계산하므로 데이터 양에 비례하여 비용이 증가합니다. 벡터 인덱스(ANN, Approximate Nearest Neighbor)는 벡터 집합에 그래프(HNSW 등) 또는 클러스터링(IVF 등) 구조를 미리 구축하여 검색 공간을 소수의 후보 벡터로 제한합니다. 제어 가능한 수준의 정확도 손실을 감수하는 대신 열 배 수준의 속도 향상을 얻습니다.
+
+
+
+자세한 사용 방법은 [벡터 인덱스](./vector-index/overview.md)를 참고하세요. Apache Doris는 버전 4.0부터 ANN 인덱스를 지원합니다. 주요 기능은 다음과 같습니다.
+
+- **다양한 인덱스 알고리즘**: `hnsw`, `ivf`, `ivf_on_disk`를 지원하며, 각각 메모리 내 처리로 높은 QPS가 필요한 시나리오, 메모리가 제한된 시나리오, 초대규모 디스크 기반 시나리오에 적합합니다.
+- **다양한 거리 척도**: `l2_distance`(유클리드 거리)와 `inner_product`(내적)를 지원합니다. 벡터에 L2 정규화를 적용하면 Cosine 유사도와 동등한 계산을 구현할 수 있습니다.
+- **TopN / 범위 / 결합 쿼리**: `l2_distance_approximate`와 `inner_product_approximate`로 ANN TopN을 구현할 수 있습니다. 거리 임계값에 기반한 범위 검색도 지원하며, 동일한 SQL 문에서 TopN과 Range 조건을 결합할 수 있습니다.
+- **스칼라 필터를 활용한 하이브리드 검색**: 역색인 등의 보조 인덱스와 함께 동작합니다. 구조화된 조건(예: `MATCH_ANY 'music'`)으로 후보 집합을 먼저 필터링한 다음 해당 후보 집합에서 ANN TopN을 실행하여, 필터 조건이 적용된 벡터 검색을 수행할 수 있습니다.
+- **벡터 양자화**: `flat`, `sq8`, `sq4`, `pq` 등의 양자화 방식을 지원하여 재현율과 메모리 및 디스크 사용량 간의 균형을 유연하게 조정할 수 있습니다.
+
+## 인덱스 관리 방식 {#index-management-methods}
+
+Apache Doris 인덱스는 사용자의 수동 관리가 필요한지에 따라 두 가지로 나뉩니다.
+
+| 관리 방식 | 인덱스 유형 | 설명 |
+|---------|---------|------|
+| 자동 유지 관리 | 접두사 인덱스, ZoneMap 인덱스 | Apache Doris에 내장된 스마트 인덱스로, 사용자가 관리할 필요가 없음 |
+| 수동 생성 | [역색인](./inverted-index/overview.md), [BloomFilter 인덱스](./bloomfilter.md), [NGram BloomFilter 인덱스](./ngram-bloomfilter-index.md), [벡터 인덱스](./vector-index/overview.md) | 사용자가 쿼리 시나리오에 맞춰 선택하고 직접 생성하거나 삭제 |
+
+## 인덱스 특성 비교 {#comparison-of-index-characteristics}
+
+다음 표는 인덱스를 빠르게 선택할 수 있도록 각 유형의 장점과 제약 사항을 정리한 것입니다.
+
+| 범주 | 인덱스 | 장점 | 제약 사항 |
+|------|------|------|------|
+| 포인트 쿼리 인덱스 | [접두사 인덱스](./prefix-index.md) | 성능이 가장 뛰어난 내장 인덱스 | 테이블당 접두사 인덱스 집합을 하나만 구성할 수 있음 |
+| 포인트 쿼리 / 전문 검색 | [역색인](./inverted-index/overview.md) | 토큰화와 키워드 매칭을 지원하고, 모든 컬럼에 생성할 수 있으며, 여러 조건의 결합을 지원하고 함수 수준의 가속 지원이 지속적으로 확대됨 | 인덱스 저장 공간이 원본 데이터와 비슷할 정도로 큼 |
+| 건너뛰기 인덱스 | ZoneMap 인덱스 | 저장 공간을 적게 차지하는 내장 인덱스 | 지원하는 쿼리 유형이 적으며, 동등 조건과 범위만 지원 |
+| 건너뛰기 인덱스 | [BloomFilter 인덱스](./bloomfilter.md) | ZoneMap보다 세밀하며, 저장 공간 사용량이 적당함 | 지원하는 쿼리 유형이 적으며, 동등 조건만 지원 |
+| 건너뛰기 인덱스 | [NGram BloomFilter 인덱스](./ngram-bloomfilter-index.md) | LIKE 쿼리를 가속하며, 저장 공간 사용량이 적당함 | 지원하는 쿼리 유형이 적으며, LIKE 가속만 지원 |
+| 벡터 인덱스 | [ANN 인덱스](./vector-index/overview.md) | 벡터 유사도 TopN / 범위 / 결합 검색을 지원하고 스칼라 필터와 연계할 수 있음. 다양한 양자화 방식으로 재현율과 리소스 사용량 간의 균형을 조정할 수 있음 | NOT NULL인 `Array<Float>` 컬럼에만 적용 가능. DUPLICATE KEY 테이블 모델과 merge-on-write가 활성화된 UNIQUE KEY 테이블 모델을 지원(버전 4.1.4부터 지원) |
+
+## 연산자 및 함수에 대한 인덱스 지원 {#index-support-for-operators-and-functions}
+
+다음 표는 일반적인 연산자와 함수에 대한 각 인덱스 유형의 가속 지원 여부를 보여줍니다.
+
+| 연산자 / 함수 | 접두사 인덱스 | 역색인 | ZoneMap 인덱스 | BloomFilter 인덱스 | NGram BloomFilter 인덱스 |
+|--------------|---------|---------|--------------|-----------------|-----------------------|
+| `=` | 지원 | 지원 | 지원 | 지원 | 미지원 |
+| `!=` | 지원 | 지원 | 미지원 | 미지원 | 미지원 |
+| `IN` | 지원 | 지원 | 지원 | 지원 | 미지원 |
+| `NOT IN` | 지원 | 지원 | 미지원 | 미지원 | 미지원 |
+| `>`, `>=`, `<`, `<=`, `BETWEEN` | 지원 | 지원 | 지원 | 미지원 | 미지원 |
+| `IS NULL` | 지원 | 지원 | 지원 | 미지원 | 미지원 |
+| `IS NOT NULL` | 지원 | 지원 | 미지원 | 미지원 | 미지원 |
+| `LIKE` | 미지원 | 미지원 | 미지원 | 미지원 | 지원 |
+| `MATCH`, `MATCH_*` | 미지원 | 지원 | 미지원 | 미지원 | 미지원 |
+| `array_contains` | 미지원 | 지원 | 미지원 | 미지원 | 미지원 |
+| `array_overlaps` | 미지원 | 지원 | 미지원 | 미지원 | 미지원 |
+| `is_ip_address_in_range` | 미지원 | 지원 | 미지원 | 미지원 | 미지원 |
+
+## 인덱스 설계 원칙 {#index-design-principles}
+
+데이터베이스 테이블의 인덱스 설계와 튜닝은 데이터 특성 및 쿼리 패턴과 밀접하게 연관되어 있으므로, 실제 시나리오에 맞춰 테스트하고 조정해야 합니다. 모든 상황에 통하는 해결책은 없지만, Apache Doris는 인덱스 사용의 어려움을 계속 줄여 나가고 있습니다. 인덱스를 설계할 때는 [시작하기](#start-here)의 선택 기준표를 참고하여 인덱스를 선택하고 테스트하세요.
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/inverted-index/custom-analyzer.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/inverted-index/custom-analyzer.md
new file mode 100644
index 00000000000..f705926fec7
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/inverted-index/custom-analyzer.md
@@ -0,0 +1,637 @@
+---
+{
+ "title": "사용자 정의 분석기",
+ "language": "ko",
+ "description": "Doris 사용자 정의 분석기는 문자 필터, 토크나이저, 토큰 필터를 결합하여 텍스트 분할 전략을 유연하게 제어하고, 역색인의 검색 관련성과 정확도를 높입니다.",
+ "keywords": [
+ "사용자 정의 분석기",
+ "역색인 토크나이저",
+ "tokenizer",
+ "token_filter",
+ "char_filter",
+ "edge_ngram",
+ "word_delimiter",
+ "USING ANALYZER",
+ "다중 분석기 인덱스",
+ "ik_smart",
+ "ik_max_word",
+ "max_ngram_diff"
+ ]
+}
+---
+
+<!-- Knowledge type: Feature overview + Configuration parameters + Operating procedures -->
+<!-- Applicable scenarios: Inverted index text tokenization customization / Multilingual search / Auto-completion / Exact match -->
+
+사용자 정의 분석기는 **문자 필터(char_filter)**, **토크나이저**, **토큰 필터(token_filter)**를 결합하여 비즈니스 요구 사항에 맞게 텍스트를 검색 가능한 검색어로 분할하는 방식을 정밀하게 정의할 수 있도록 합니다. 기본 제공 분석기의 한계를 보완하며, 검색 관련성과 데이터 분석의 정확도에 직접적인 영향을 줍니다.
+
+
+
+### 활용 시나리오 {#applicable-scenarios}
+
+| 시나리오 | 권장 조합 |
+| --- | --- |
+| 여러 언어가 섞인 텍스트 검색 | `icu` 토크나이저 + `icu_normalizer` 필터 |
+| 전화번호 / 코드 접두사 매칭 | `edge_ngram` 토크나이저 |
+| 복잡한 영어 텍스트 분할(카멜 표기법, 하이픈 등) | `standard` 토크나이저 + `word_delimiter` 필터 |
+| 자동 완성 / 입력 제안 | `edge_ngram` 토크나이저 + `lowercase` 필터 |
+| 정확히 일치하는 값 검색(원래 검색어 유지) | `keyword` 토크나이저 + `lowercase` / `asciifolding` 필터 |
+
+---
+
+## 핵심 구성 요소 {#core-components}
+
+사용자 정의 분석기는 네 종류의 객체로 구성되며, 원본 텍스트에 순서대로 적용됩니다.
+
+```
+Original text ──► [char_filter] ──► [tokenizer] ──► [token_filter] ──► Terms
+```
+
+| 구성 요소 | 용도 | 개수 |
+| --- | --- | --- |
+| `char_filter` | 토큰화 전에 문자를 전처리(치환, 정규화 등) | 0 ~ N |
+| `tokenizer` | 텍스트를 검색어로 분할 | 1 |
+| `token_filter` | 생성된 검색어를 처리(소문자 변환, ASCII 폴딩 등) | 0 ~ N |
+| `analyzer` | 위 구성 요소를 조합하여 완전한 토큰화 파이프라인 구성 | 1 |
+
+---
+
+## 사용자 정의 분석기 생성 {#creating-a-custom-analyzer}
+
+### 1. 문자 필터(char_filter) {#1-character-filter-char_filter}
+
+```sql
+CREATE INVERTED INDEX CHAR_FILTER IF NOT EXISTS x_char_filter
+PROPERTIES (
+ "type" = "char_replace"
+ -- See below for other parameters
+);
+```
+
+지원되는 문자 필터 유형:
+
+- **`char_replace`**: 토큰화 전에 지정한 문자를 대상 문자로 치환합니다.
+ - `char_filter_pattern`: 치환할 문자 목록
+ - `char_filter_replacement`: 치환에 사용할 문자(기본값: 공백)
+
+- **`icu_normalizer`**: ICU 정규화를 사용하여 텍스트를 전처리합니다.
+ - `name`: 정규화 형식(기본값 `nfkc_cf`). 선택 가능한 값: `nfc`, `nfkc`, `nfkc_cf`, `nfd`, `nfkd`
+ - `mode`: 정규화 모드(기본값 `compose`). 선택 가능한 값: `compose`, `decompose`
+ - `unicode_set_filter`: 정규화할 문자 집합 지정(예: `[a-z]`)
+
+### 2. 토크나이저 {#2-tokenizer}
+
+```sql
+CREATE INVERTED INDEX TOKENIZER IF NOT EXISTS x_tokenizer
+PROPERTIES (
+ "type" = "standard"
+);
+```
+
+지원되는 토크나이저 유형:
+
+| 유형 | 설명 | 주요 매개변수 |
+| --- | --- | --- |
+| `standard` | Unicode 텍스트 분할 규칙을 따르는 표준 토큰화로, 대부분의 언어에 적합 | 없음 |
+| `ngram` | N-gram 단위로 분할 | `min_gram`, `max_gram`, `max_ngram_diff`, `token_chars` |
+| `edge_ngram` | 단어의 시작 부분부터 N-gram 생성 | `min_gram`, `max_gram`, `token_chars` |
+| `keyword` | 전체 텍스트를 단일 검색어로 출력하며, 주로 token_filter와 함께 사용 | 없음 |
+| `char_group` | 지정된 문자를 기준으로 분할 | `tokenize_on_chars` |
+| `basic` | 영어 / 숫자 / 중국어 / Unicode의 간단한 토큰화 | `extra_chars` |
+| `icu` | 여러 언어의 복잡한 문자 체계를 지원하는 ICU 국제화 토큰화 | 없음 |
+| `ik_smart` | 완전한 단어를 우선하는 IK 스마트 중국어 토큰화. 4.1.5부터 사용자 정의 분석기에서 사용 가능 | 없음 |
+| `ik_max_word` | 서로 겹칠 수 있는 검색어를 더 많이 생성하는 IK 세분화 중국어 토큰화. 4.1.5부터 사용자 정의 분석기에서 사용 가능 | 없음 |
+
+매개변수 설명:
+
+- `min_gram`: 최소 길이(기본값 1)
+- `max_gram`: 최대 길이(기본값 2)
+- `token_chars`: 유지할 문자 범주(기본값: 모두 유지). 선택 가능한 값: `letter`, `digit`, `whitespace`, `punctuation`, `symbol`
+- `tokenize_on_chars`: 문자 목록 또는 범주. 지원되는 범주: `whitespace`, `letter`, `digit`, `punctuation`, `symbol`, `cjk`
+- `extra_chars`: 분할 기준으로 사용할 추가 ASCII 문자(예: `[]().`)
+
+#### Ngram 범위 제한(4.1.5부터) {#ngram-range-limits-since-415}
+
+4.1.5부터 `ngram` 토크나이저는 `max_ngram_diff`를 지원하여, 최대 gram 길이와 최소 gram 길이의 차이를 `1`로 제한하던 기존 제약을 완화할 수 있습니다. `ngram` 토크나이저에 `mode` 속성을 지정하지 않은 일반적인 경우, 생성 시 다음 조건을 검증합니다.
+
+| 매개변수 | 기본값 | 제약 조건 |
+| --- | --- | --- |
+| `min_gram` | `1` | `max_gram` 이하의 양의 정수이며, 최댓값은 `1024`입니다(새 `ngram` 토크나이저 기준). |
+| `max_gram` | `2` | `min_gram` 이상의 양의 정수이며, 최댓값은 `1024`입니다(새 `ngram` 토크나이저 기준). |
+| `max_ngram_diff` | `1` | `0`부터 `255`까지의 정수이며, `max_gram - min_gram <= max_ngram_diff`를 만족해야 합니다. 값이 `0`이면 고정 길이 N-gram만 허용됩니다. |
+
+예를 들어 `min_gram=1`과 `max_gram=8`을 사용하려면 `max_ngram_diff`가 `7` 이상이어야 합니다. 이를 생략하면 `The difference between max_gram and min_gram in NGram Tokenizer must be less than or equal to: [ 1 ] but was [7]` 오류와 함께 생성이 실패합니다. 전체 사용 방법은 [예제 5](#example-5-expand-the-ngram-length-range-since-415)를 참조하세요.
+
+이러한 제한과 `max_ngram_diff`는 일반적인 `ngram` 토크나이저 중 `mode` 속성을 지정하지 않은 경우에 적용됩니다. `mode`를 지정한 토크나이저는 별도의 검증을 사용하며 이러한 제한을 무시합니다. `edge_ngram`은 이 매개변수를 허용하지 않습니다. 전화번호 및 자동 완성 예제에서는 각각의 `min_gram` 및 `max_gram` 설정을 그대로 사용합니다. 범위를 넓히면 입력 위치마다 더 많은 검색어가 생성됩니다. 인덱스가 불필요하게 커지지 않도록 검색 요구 사항에 맞게 범위를 설정하세요.
+
+### 3. 토큰 필터 {#3-token-filter}
+
+```sql
+CREATE INVERTED INDEX TOKEN_FILTER IF NOT EXISTS x_token_filter
+PROPERTIES (
+ "type" = "word_delimiter"
+);
+```
+
+지원되는 토큰 필터 유형:
+
+| 유형 | 용도 |
+| --- | --- |
+| `word_delimiter` | 영숫자가 아닌 문자를 기준으로 분할하며, 정규화도 수행 가능 |
+| `ascii_folding` | 비ASCII 문자를 해당하는 ASCII 문자로 매핑 |
+| `lowercase` | 토큰 텍스트를 소문자로 변환 |
+| `icu_normalizer` | ICU 정규화를 사용하여 토큰 처리 |
+
+#### word_delimiter 세부 사항 {#word_delimiter-details}
+
+기본 동작:
+
+1. 영숫자가 아닌 문자를 구분자로 사용합니다(예: `Super-Duper`를 `Super`, `Duper`로 분할).
+2. 토큰의 앞뒤에 있는 구분자를 제거합니다(예: `XL---42+'Autocoder'`를 `XL`, `42`, `Autocoder`로 분할).
+3. 대소문자가 바뀌는 지점에서 분할합니다(예: `PowerShot`을 `Power`, `Shot`으로 분할).
+4. 문자와 숫자의 경계에서 분할합니다(예: `XL500`을 `XL`, `500`으로 분할).
+5. 영어 소유격 `'s`를 제거합니다(예: `Neil's`를 `Neil`로 변환).
+
+선택적 매개변수:
+
+| 매개변수 | 기본값 | 설명 |
+| --- | --- | --- |
+| `generate_number_parts` | `true` | 숫자 부분의 출력 여부 |
+| `generate_word_parts` | `true` | 단어 부분의 출력 여부 |
+| `protected_words` | 없음 | 분할하지 않을 보호 단어 |
+| `split_on_case_change` | `true` | 대소문자가 바뀌는 지점에서 분할할지 여부 |
+| `split_on_numerics` | `true` | 문자와 숫자의 경계에서 분할할지 여부 |
+| `stem_english_possessive` | `true` | 영어 소유격 `'s`를 제거할지 여부 |
+| `type_table` | 없음 | 사용자 정의 문자 유형 매핑 테이블 |
+
+`type_table`은 다음 매핑 유형을 지원합니다.
+
+- `ALPHA`(문자)
+- `ALPHANUM`(영숫자)
+- `DIGIT`(숫자)
+- `LOWER`(소문자)
+- `SUBWORD_DELIM`(영숫자가 아닌 구분자)
+- `UPPER`(대문자)
+
+예: `["+ => ALPHA", "- => ALPHA"]`는 `+`와 `-`를 문자로 취급하여 분할 지점으로 사용하지 않도록 합니다.
+
+#### icu_normalizer 매개변수 {#icu_normalizer-parameters}
+
+- `name`: 정규화 형식(기본값 `nfkc_cf`). 선택 가능한 값: `nfc`, `nfkc`, `nfkc_cf`, `nfd`, `nfkd`
+- `unicode_set_filter`: 정규화할 문자 집합 지정
+
+### 4. 분석기 {#4-analyzer}
+
+위 구성 요소를 조합하여 완전한 토큰화 파이프라인을 구성합니다.
+
+```sql
+CREATE INVERTED INDEX ANALYZER IF NOT EXISTS x_analyzer
+PROPERTIES (
+ "tokenizer" = "x_tokenizer", -- A single tokenizer
+ "token_filter" = "x_filter1, x_filter2" -- One or more token_filters, executed in order
+);
+```
+
+---
+
+## 테이블에서 사용자 정의 분석기 사용 {#using-a-custom-analyzer-in-a-table}
+
+`analyzer` 필드를 인덱스의 `PROPERTIES`에 지정하여 생성한 사용자 정의 분석기를 참조합니다.
+
+```sql
+CREATE TABLE tbl (
+ `a` bigint NOT NULL AUTO_INCREMENT(1),
+ `ch` text NULL,
+ INDEX idx_ch (`ch`) USING INVERTED PROPERTIES("analyzer" = "x_custom_analyzer", "support_phrase" = "true")
+)
+table_properties;
+```
+
+참고 사항:
+
+1. 사용자 정의 분석기는 인덱스의 `PROPERTIES`에서 `analyzer`로 설정합니다.
+2. `analyzer`와 함께 사용할 수 있는 속성은 `support_phrase`뿐입니다.
+
+---
+
+## 단일 컬럼에 여러 분석기 인덱스 생성 {#multiple-analyzer-indexes-on-a-single-column}
+
+Doris는 동일한 컬럼에 서로 다른 토크나이저를 사용하는 여러 역색인을 생성할 수 있습니다. 이를 통해 동일한 데이터를 서로 다른 토큰화 전략으로 검색할 수 있습니다.
+
+### 사용 사례 {#use-cases}
+
+- **다국어 지원**: 동일한 텍스트 컬럼에 언어별 토크나이저를 사용합니다.
+- **검색 정밀도와 재현율의 균형**: 정확히 일치하는 값 검색에는 keyword 토크나이저를, 유사 검색에는 standard 토크나이저를 사용합니다.
+- **자동 완성**: 접두사 매칭에는 edge_ngram 토크나이저를, 일반 검색에는 standard 토크나이저를 사용합니다.
+
+### 여러 인덱스 생성 {#creating-multiple-indexes}
+
+```sql
+-- 1. Create tokenizers with different tokenization strategies
+CREATE INVERTED INDEX ANALYZER IF NOT EXISTS std_analyzer
+PROPERTIES ("tokenizer" = "standard", "token_filter" = "lowercase");
+
+CREATE INVERTED INDEX ANALYZER IF NOT EXISTS kw_analyzer
+PROPERTIES ("tokenizer" = "keyword", "token_filter" = "lowercase");
+
+CREATE INVERTED INDEX TOKENIZER IF NOT EXISTS edge_ngram_tokenizer
+PROPERTIES (
+ "type" = "edge_ngram",
+ "min_gram" = "1",
+ "max_gram" = "20",
+ "token_chars" = "letter"
+);
+
+CREATE INVERTED INDEX ANALYZER IF NOT EXISTS ngram_analyzer
+PROPERTIES ("tokenizer" = "edge_ngram_tokenizer", "token_filter" = "lowercase");
+
+-- 2. Create multiple indexes on the same column
+CREATE TABLE articles (
+ id INT,
+ content TEXT,
+ -- Standard tokenizer for tokenized search
+ INDEX idx_content_std (content) USING INVERTED
+ PROPERTIES("analyzer" = "std_analyzer", "support_phrase" = "true"),
+ -- Keyword tokenizer for exact matching
+ INDEX idx_content_kw (content) USING INVERTED
+ PROPERTIES("analyzer" = "kw_analyzer"),
+ -- edge n-gram tokenizer for auto-completion
+ INDEX idx_content_ngram (content) USING INVERTED
+ PROPERTIES("analyzer" = "ngram_analyzer")
+) ENGINE=OLAP
+DUPLICATE KEY(id)
+DISTRIBUTED BY HASH(id) BUCKETS 1
+PROPERTIES ("replication_allocation" = "tag.location.default: 1");
+```
+
+### 쿼리 시 분석기 지정 {#specifying-an-analyzer-at-query-time}
+
+`USING ANALYZER` 절을 사용하여 사용할 인덱스를 지정합니다.
+
+```sql
+-- Insert test data
+INSERT INTO articles VALUES
+ (1, 'hello world'),
+ (2, 'hello'),
+ (3, 'world'),
+ (4, 'hello world test');
+
+-- Tokenized search: matches rows containing the term 'hello'
+-- Returns: 1, 2, 4
+SELECT id FROM articles WHERE content MATCH 'hello' USING ANALYZER std_analyzer ORDER BY id;
+
+-- Exact match: matches only the exact 'hello' string
+-- Returns: 2
+SELECT id FROM articles WHERE content MATCH 'hello' USING ANALYZER kw_analyzer ORDER BY id;
+
+-- Use edge n-gram for prefix matching
+-- Returns: 1, 2, 4 (all rows starting with 'hel')
+SELECT id FROM articles WHERE content MATCH 'hel' USING ANALYZER ngram_analyzer ORDER BY id;
+```
+
+기본 제공 토크나이저를 직접 사용할 수도 있습니다.
+
+```sql
+SELECT * FROM articles WHERE content MATCH 'hello' USING ANALYZER standard;
+SELECT * FROM articles WHERE content MATCH 'hello' USING ANALYZER none;
+SELECT * FROM articles WHERE content MATCH 'Hello' USING ANALYZER chinese;
+```
+
+### 기존 테이블에 인덱스 추가 {#adding-an-index-to-an-existing-table}
+
+```sql
+-- Add a new index that uses a different tokenizer
+ALTER TABLE articles ADD INDEX idx_content_chinese (content)
+USING INVERTED PROPERTIES("parser" = "chinese");
+
+-- Wait for the schema change to complete
+SHOW ALTER TABLE COLUMN WHERE TableName='articles';
+```
+
+### 인덱스 빌드 {#building-an-index}
+
+인덱스를 추가한 후에는 기존 데이터에 대한 인덱스를 빌드해야 합니다.
+
+```sql
+-- Build a specific index (non-cloud mode)
+BUILD INDEX idx_content_chinese ON articles;
+
+-- Build all indexes (cloud mode)
+BUILD INDEX ON articles;
+
+-- Check the build progress
+SHOW BUILD INDEX WHERE TableName='articles';
+```
+
+### 주요 참고 사항 {#key-notes}
+
+1. **토크나이저 동일성**: 두 토크나이저의 `tokenizer` 및 `token_filter` 구성이 같으면 동일한 토크나이저로 간주합니다. 동일한 컬럼에 동일한 토크나이저 구성을 공유하는 여러 인덱스를 생성할 수 없습니다.
+2. **인덱스 선택 동작**:
+ - `USING ANALYZER`를 지정하면 해당 토크나이저의 인덱스가 존재하고 빌드가 완료된 경우 그 인덱스를 사용합니다.
+ - 인덱스가 빌드되지 않았다면 쿼리는 인덱스를 사용하지 않는 실행 경로로 전환됩니다(결과는 정확하지만 성능은 느려집니다).
+ - `USING ANALYZER`를 지정하지 않으면 사용 가능한 인덱스 중 하나가 사용될 수 있습니다.
+3. **성능 고려 사항**:
+ - 인덱스를 추가할 때마다 저장 공간과 쓰기 오버헤드가 증가합니다.
+ - 실제 쿼리 패턴에 맞게 토크나이저를 선택하세요.
+ - 쿼리 패턴을 예측할 수 있다면 인덱스 수를 줄이는 방안을 고려하세요.
+
+---
+
+## 관리 및 유지보수 {#management-and-maintenance}
+
+### 조회 {#view}
+
+```sql
+SHOW INVERTED INDEX TOKENIZER;
+SHOW INVERTED INDEX TOKEN_FILTER;
+SHOW INVERTED INDEX ANALYZER;
+```
+
+### 삭제 {#delete}
+
+```sql
+DROP INVERTED INDEX TOKENIZER IF EXISTS x_tokenizer;
+DROP INVERTED INDEX TOKEN_FILTER IF EXISTS x_token_filter;
+DROP INVERTED INDEX ANALYZER IF EXISTS x_analyzer;
+```
+
+---
+
+## 전체 예제 {#complete-examples}
+
+### 예제 1: 전화번호 접두사 매칭 {#example-1-phone-number-prefix-matching}
+
+`edge_ngram`을 사용하여 전화번호의 모든 접두사 조각을 생성하면 입력 중에도 검색할 수 있습니다.
+
+```sql
+CREATE INVERTED INDEX TOKENIZER IF NOT EXISTS edge_ngram_phone_number_tokenizer
+PROPERTIES
+(
+ "type" = "edge_ngram",
+ "min_gram" = "3",
+ "max_gram" = "10",
+ "token_chars" = "digit"
+);
+
+CREATE INVERTED INDEX ANALYZER IF NOT EXISTS edge_ngram_phone_number
+PROPERTIES
+(
+ "tokenizer" = "edge_ngram_phone_number_tokenizer"
+);
+
+CREATE TABLE tbl (
+ `a` bigint NOT NULL AUTO_INCREMENT(1),
+ `ch` text NULL,
+ INDEX idx_ch (`ch`) USING INVERTED PROPERTIES("support_phrase" = "true", "analyzer" = "edge_ngram_phone_number")
+) ENGINE=OLAP
+DUPLICATE KEY(`a`)
+DISTRIBUTED BY RANDOM BUCKETS 1
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 1"
+);
+
+SELECT tokenize('13891972631', '"analyzer"="edge_ngram_phone_number"');
+```
+
+결과:
+
+```json
+[
+ {"token":"138"},
+ {"token":"1389"},
+ {"token":"13891"},
+ {"token":"138919"},
+ {"token":"1389197"},
+ {"token":"13891972"},
+ {"token":"138919726"},
+ {"token":"1389197263"}
+]
+```
+
+### 예제 2: 복잡한 영어 텍스트의 세분화 토큰화 {#example-2-fine-grained-tokenization-for-complex-english-text}
+
+`standard` 토크나이저와 `word_delimiter`를 함께 사용하면 텍스트를 더 세밀하게 토큰화하고 대소문자 정규화와 ASCII 폴딩도 적용할 수 있습니다.
+
+```sql
+CREATE INVERTED INDEX TOKEN_FILTER IF NOT EXISTS word_splitter
+PROPERTIES
+(
+ "type" = "word_delimiter",
+ "split_on_numerics" = "false",
+ "split_on_case_change" = "false"
+);
+
+CREATE INVERTED INDEX ANALYZER IF NOT EXISTS lowercase_delimited
+PROPERTIES
+(
+ "tokenizer" = "standard",
+ "token_filter" = "asciifolding, word_splitter, lowercase"
+);
+
+CREATE TABLE tbl (
+ `a` bigint NOT NULL AUTO_INCREMENT(1),
+ `ch` text NULL,
+ INDEX idx_ch (`ch`) USING INVERTED PROPERTIES("support_phrase" = "true", "analyzer" = "lowercase_delimited")
+) ENGINE=OLAP
+DUPLICATE KEY(`a`)
+DISTRIBUTED BY RANDOM BUCKETS 1
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 1"
+);
+
+SELECT tokenize('The server at IP 192.168.1.15 sent a confirmation to user_123@example.com, requiring a quickResponse before the deadline.', '"analyzer"="lowercase_delimited"');
+```
+
+결과:
+
+```json
+[
+ {"token":"the"},
+ {"token":"server"},
+ {"token":"at"},
+ {"token":"ip"},
+ {"token":"192"},
+ {"token":"168"},
+ {"token":"1"},
+ {"token":"15"},
+ {"token":"sent"},
+ {"token":"a"},
+ {"token":"confirmation"},
+ {"token":"to"},
+ {"token":"user"},
+ {"token":"123"},
+ {"token":"example"},
+ {"token":"com"},
+ {"token":"requiring"},
+ {"token":"a"},
+ {"token":"quickresponse"},
+ {"token":"before"},
+ {"token":"the"},
+ {"token":"deadline"}
+]
+```
+
+### 예제 3: 원래 검색어를 유지하여 정확히 일치하는 값 검색 {#example-3-exact-match-with-original-term-preserved}
+
+`keyword` 토크나이저로 전체 텍스트를 그대로 유지한 다음, `lowercase`와 `asciifolding`을 적용하여 정규화합니다. 이 방식은 대소문자를 구분하지 않고 정확히 일치하는 문자열을 검색할 때 주로 사용합니다.
+
+```sql
+CREATE INVERTED INDEX ANALYZER IF NOT EXISTS keyword_lowercase
+PROPERTIES
+(
+ "tokenizer" = "keyword",
+ "token_filter" = "asciifolding, lowercase"
+);
+
+CREATE TABLE tbl (
+ `a` bigint NOT NULL AUTO_INCREMENT(1),
+ `ch` text NULL,
+ INDEX idx_ch (`ch`) USING INVERTED PROPERTIES("support_phrase" = "true", "analyzer" = "keyword_lowercase")
+) ENGINE=OLAP
+DUPLICATE KEY(`a`)
+DISTRIBUTED BY RANDOM BUCKETS 1
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 1"
+);
+
+SELECT tokenize('hÉllo World', '"analyzer"="keyword_lowercase"');
+```
+
+결과:
+
+```json
+[
+ {"token":"hello world"}
+]
+```
+
+### 예제 4: IK 스마트 및 세분화 중국어 토큰화(4.1.5부터) {#example-4-ik-smart-and-fine-grained-chinese-tokenization-since-415}
+
+4.1.5부터 사용자 정의 분석기는 기본 제공 `ik_smart` 및 `ik_max_word` 토크나이저를 직접 참조할 수 있습니다. 또는 둘 중 하나를 `type`으로 지정한 이름 있는 토크나이저를 사용하여 문자 필터 및 토큰 필터와 결합할 수 있습니다. 두 IK 토크나이저 모두 추가 토크나이저 매개변수는 없습니다. 두 토크나이저는 `ik` 디렉터리의 사전을 사용하며, 이 디렉터리는 BE 구성 `inverted_index_dict_path`로 지정한 경로 아래에 있습니다. 토큰화와 인덱스 생성에 참여하는 모든 BE는 이러한 구성 요소를 지원하고 사전을 읽을 수 있어야 합니다.
+
+아래 예제에서는 직접 참조하는 방법과 이름 있는 토크나이저를 사용하는 방법을 보여 줍니다. 이러한 구성 요소를 생성하려면 전역 `ADMIN` 권한이 필요합니다. 테이블 생성, 데이터 적재, 쿼리에도 대상 데이터베이스와 테이블에 대한 해당 권한이 필요합니다.
+
+```sql
+CREATE INVERTED INDEX ANALYZER IF NOT EXISTS cn_ik_smart
+PROPERTIES ("tokenizer" = "ik_smart");
+
+CREATE INVERTED INDEX TOKENIZER IF NOT EXISTS cn_ik_max_tokenizer
+PROPERTIES ("type" = "ik_max_word");
+
+CREATE INVERTED INDEX ANALYZER IF NOT EXISTS cn_ik_max
+PROPERTIES ("tokenizer" = "cn_ik_max_tokenizer");
+```
+
+생성에 성공하면 `Query OK`가 반환됩니다. 구성 요소가 BE에 동기화된 후 `TOKENIZE`로 출력을 비교하세요. 다음 결과는 기본 제공 사전을 사용한 결과이며, 사전을 변경하면 토큰이 달라질 수 있습니다.
+
+```sql
+SELECT TOKENIZE('中华人民共和国', '"analyzer"="cn_ik_smart"');
+```
+
+```json
+[{"token":"中华人民共和国"}]
+```
+
+```sql
+SELECT TOKENIZE('中华人民共和国', '"analyzer"="cn_ik_max"');
+```
+
+```json
+[
+ {"token":"中华人民共和国"},
+ {"token":"中华人民"},
+ {"token":"中华"},
+ {"token":"华人"},
+ {"token":"人民共和国"},
+ {"token":"人民"},
+ {"token":"共和国"},
+ {"token":"共和"},
+ {"token":"国"}
+]
+```
+
+테이블의 역색인에서 분석기를 사용합니다.
+
+```sql
+CREATE TABLE ik_articles (
+ id INT,
+ content STRING,
+ INDEX idx_content(content) USING INVERTED
+ PROPERTIES("analyzer" = "cn_ik_smart")
+)
+DUPLICATE KEY(id)
+DISTRIBUTED BY HASH(id) BUCKETS 1
+PROPERTIES ("replication_allocation" = "tag.location.default: 1");
+
+INSERT INTO ik_articles VALUES (1, '中华人民共和国');
+
+SELECT id FROM ik_articles
+WHERE content MATCH '中华人民共和国' USING ANALYZER cn_ik_smart
+ORDER BY id;
+```
+
+```text
++----+
+| id |
++----+
+| 1 |
++----+
+```
+
+`ik_smart`는 검색 시 완전한 중국어 단어를 유지해야 할 때 사용하고, `ik_max_word`는 더 많은 하위 단어 매칭이 필요할 때 사용하세요. 추가 토큰 처리가 필요하면 분석기의 `token_filter` 속성으로 토큰 필터를 추가하세요.
+
+### 예제 5: Ngram 길이 범위 확장(4.1.5부터) {#example-5-expand-the-ngram-length-range-since-415}
+
+다음 토크나이저는 길이가 `1`부터 `8`까지인 N-gram을 생성하며, 이를 위해 `max_ngram_diff=7`을 명시적으로 설정합니다.
+
+```sql
+CREATE INVERTED INDEX TOKENIZER IF NOT EXISTS ngram_1_8_tokenizer
+PROPERTIES (
+ "type" = "ngram",
+ "min_gram" = "1",
+ "max_gram" = "8",
+ "max_ngram_diff" = "7"
+);
+
+CREATE INVERTED INDEX ANALYZER IF NOT EXISTS ngram_1_8_analyzer
+PROPERTIES ("tokenizer" = "ngram_1_8_tokenizer");
+```
+
+생성에 성공하고 BE에 동기화된 후 다음을 실행하세요.
+
+```sql
+SELECT TOKENIZE('abcdefgh', '"analyzer"="ngram_1_8_analyzer"');
+```
+
+```json
+[
+ {"token":"a"}, {"token":"ab"}, {"token":"abc"}, {"token":"abcd"},
+ {"token":"abcde"}, {"token":"abcdef"}, {"token":"abcdefg"}, {"token":"abcdefgh"},
+ {"token":"b"}, {"token":"bc"}, {"token":"bcd"}, {"token":"bcde"},
+ {"token":"bcdef"}, {"token":"bcdefg"}, {"token":"bcdefgh"},
+ {"token":"c"}, {"token":"cd"}, {"token":"cde"}, {"token":"cdef"},
+ {"token":"cdefg"}, {"token":"cdefgh"},
+ {"token":"d"}, {"token":"de"}, {"token":"def"}, {"token":"defg"}, {"token":"defgh"},
+ {"token":"e"}, {"token":"ef"}, {"token":"efg"}, {"token":"efgh"},
+ {"token":"f"}, {"token":"fg"}, {"token":"fgh"},
+ {"token":"g"}, {"token":"gh"}, {"token":"h"}
+]
+```
+
+
+---
+
+## 제한 사항 {#limitations}
+
+1. `type`과 매개변수를 `tokenizer` 및 `token_filter`에 지정할 때는 현재 지원되는 토크나이저와 토큰 필터만 사용할 수 있습니다. 그렇지 않으면 테이블 생성이 실패합니다.
+2. `analyzer`는 사용하는 테이블이 없을 때만 삭제할 수 있습니다.
+3. `tokenizer` 또는 `token_filter`는 사용하는 `analyzer`가 없을 때만 삭제할 수 있습니다.
+4. 사용자 정의 분석기 DDL은 실행 후 10초가 지나면 BE에 동기화되며, 이후 데이터 적재 시 오류가 발생하지 않습니다.
+
+---
+
+## 참고 사항 {#notes}
+
+1. 사용자 정의 `analyzer`에 여러 구성 요소를 중첩하면 토큰화 성능이 저하될 수 있습니다.
+2. `select tokenize` 토큰화 함수는 사용자 정의 분석기를 지원하며, 토큰화 결과를 디버깅하는 데 사용할 수 있습니다.
+3. 사전 정의된 `built_in_analyzer`와 사용자 정의 `analyzer` 중 하나만 동일한 인덱스에 존재할 수 있습니다.
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/inverted-index/custom-normalizer.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/inverted-index/custom-normalizer.md
new file mode 100644
index 00000000000..e329d3e9934
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/inverted-index/custom-normalizer.md
@@ -0,0 +1,146 @@
+---
+{
+ "title": "사용자 정의 Normalizer",
+ "language": "ko",
+ "description": "Doris 역색인용 사용자 정의 Normalizer 안내: 전체 텍스트를 하나의 토큰으로 처리하고, 대소문자 변환과 악센트 정규화 등을 통해 키워드 정확 일치 시나리오를 지원합니다."
+}
+---
+
+<!-- Knowledge type: Feature description + Procedure -->
+<!-- Applicable scenario: Keyword exact match / Standardization preprocessing without tokenization -->
+
+사용자 정의 Normalizer는 텍스트에 일관된 전처리를 적용합니다. **텍스트를 분할하지 않고**, 전체 텍스트를 하나의 완전한 토큰으로 처리합니다. 문자 필터(`char_filter`)와 토큰 필터(`token_filter`)를 조합하여 대소문자 변환, 문자 정규화 등의 기능을 지원합니다. 주로 키워드 검색처럼 토큰화는 필요하지 않지만 정규화가 필요한 시나리오에 사용합니다.
+
+**Normalizer와 Analyzer의 차이점**
+
+| 비교 항목 | Normalizer | Analyzer |
+| --- | --- | --- |
+| 텍스트 분할 여부 | 분할하지 않으며, 전체 텍스트를 하나의 토큰으로 처리 | 규칙에 따라 텍스트를 여러 토큰으로 분할 |
+| 일반적인 사용 시나리오 | 키워드 정확 일치(예: 제품 코드, ID) | 전문 검색(예: 문서 본문) |
+| 자주 사용하는 필터 | lowercase, ascii_folding 등 | tokenizer + 다양한 필터 |
+
+## 적용 시나리오 {#applicable-scenarios}
+
+- **키워드 검색**: 제품 코드, 제품명, 사용자 ID 등 토큰화는 필요하지 않지만 형식을 통일해야 하는 필드.
+- **대소문자를 구분하지 않는 매칭**: `ProductA`와 `producta`를 같은 값으로 처리합니다.
+- **악센트 및 특수 문자 정규화**: `Café`를 `cafe`로 정규화하여 기호 차이로 인한 매칭 누락을 방지합니다.
+
+## 사용 절차 {#usage-workflow}
+
+전체 절차는 세 단계로 구성됩니다.
+
+1. (선택 사항) 사용자 정의 `char_filter`와 `token_filter`를 생성합니다.
+2. 위 필터를 조합하는 사용자 정의 Normalizer를 생성합니다.
+3. 테이블 생성 구문의 역색인 속성에서 Normalizer를 참조합니다.
+
+### 1단계: 사용자 정의 필터 생성(선택 사항) {#step-1-create-custom-filters-optional}
+
+기본 제공 필터가 요구 사항을 충족하지 못하면 먼저 사용자 정의 필터를 생성할 수 있습니다.
+
+> `char_filter`와 `token_filter`를 생성하는 방법은 [사용자 정의 Analyzer](./custom-analyzer.md) 문서를 참조하세요.
+
+### 2단계: 사용자 정의 Normalizer 생성 {#step-2-create-a-custom-normalizer}
+
+```sql
+CREATE INVERTED INDEX NORMALIZER IF NOT EXISTS x_normalizer
+PROPERTIES (
+ "char_filter" = "x_char_filter", -- Optional, one or more character filters
+ "token_filter" = "x_filter1, x_filter2" -- Optional, one or more token filters, executed in order
+);
+```
+
+**매개변수 설명**
+
+| 매개변수 | 필수 여부 | 설명 |
+| --- | --- | --- |
+| `char_filter` | 아니요 | 쉼표로 구분한 하나 이상의 문자 필터 이름 |
+| `token_filter` | 아니요 | 선언된 순서대로 실행할 하나 이상의 토큰 필터 이름 |
+
+### 3단계: 테이블 생성 구문에서 Normalizer 참조 {#step-3-reference-the-normalizer-in-the-table-creation-statement}
+
+역색인 속성에서 `normalizer`를 사용하여 적용할 Normalizer를 지정합니다.
+
+```sql
+CREATE TABLE tbl (
+ `id` bigint NOT NULL,
+ `code` text NULL,
+ INDEX idx_code (`code`) USING INVERTED PROPERTIES("normalizer" = "x_custom_normalizer")
+)
+...
+```
+
+:::caution 참고
+`normalizer`와 `analyzer`는 상호 배타적이므로 같은 인덱스에 함께 지정할 수 없습니다.
+:::
+
+## 사용자 정의 Normalizer 관리 {#managing-custom-normalizers}
+
+| 작업 | SQL 구문 |
+| --- | --- |
+| 조회 | `SHOW INVERTED INDEX NORMALIZER;` |
+| 삭제 | `DROP INVERTED INDEX NORMALIZER IF EXISTS x_normalizer;` |
+
+## 전체 예제: 대소문자와 악센트 기호 무시 {#complete-example-ignore-case-and-accent-marks}
+
+**시나리오**: 제품명 필드에서 대소문자를 구분하지 않고 악센트 기호도 무시하는 정확 일치를 지원해야 합니다. 예를 들어 `Café-Products`와 `cafe-products`를 같은 값으로 처리합니다.
+
+**구현 단계**:
+
+1. 악센트 기호를 제거하는 사용자 정의 토큰 필터 `my_ascii_folding`을 생성합니다.
+2. Normalizer `lowercase_ascii_normalizer`를 생성하여 기본 제공 `lowercase` 필터와 이전 단계의 `my_ascii_folding`을 결합합니다.
+3. 테이블을 생성하고 `product_name` 필드에 Normalizer를 적용합니다.
+4. `tokenize` 함수로 정규화 결과를 확인합니다.
+
+**SQL 예제**:
+
+```sql
+-- 1. Create a custom token filter (when specific parameters are needed)
+-- Here, create an ascii_folding filter
+CREATE INVERTED INDEX TOKEN_FILTER IF NOT EXISTS my_ascii_folding
+PROPERTIES
+(
+ "type" = "ascii_folding",
+ "preserve_original" = "false"
+);
+
+-- 2. Create the normalizer
+-- Combine lowercase (built-in) and my_ascii_folding
+CREATE INVERTED INDEX NORMALIZER IF NOT EXISTS lowercase_ascii_normalizer
+PROPERTIES
+(
+ "token_filter" = "lowercase, my_ascii_folding"
+);
+
+-- 3. Use the normalizer when creating a table
+CREATE TABLE product_table (
+ `id` bigint NOT NULL,
+ `product_name` text NULL,
+ INDEX idx_name (`product_name`) USING INVERTED PROPERTIES("normalizer" = "lowercase_ascii_normalizer")
+) ENGINE=OLAP
+DUPLICATE KEY(`id`)
+DISTRIBUTED BY RANDOM BUCKETS 1
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 1"
+);
+
+-- 4. Verification test
+select tokenize('Café-Products', '"normalizer"="lowercase_ascii_normalizer"');
+```
+
+**예상 결과**:
+
+```json
+[
+ {"token":"cafe-products"}
+]
+```
+
+위 결과처럼 `Café-Products`는 분할되지 않고 하나의 토큰으로 처리되며, 소문자 변환과 악센트 제거가 모두 적용됩니다.
+
+## 제한 사항 {#limitations}
+
+1. `char_filter`와 `token_filter`에서 참조하는 이름은 기본 제공 필터이거나 이미 생성된 필터의 이름이어야 합니다.
+2. Normalizer는 이를 사용하는 테이블이 없을 때만 삭제할 수 있습니다.
+3. `char_filter` 또는 `token_filter`는 이를 참조하는 Normalizer가 없을 때만 삭제할 수 있습니다.
+4. 사용자 정의 Normalizer 구문을 실행한 후 BE에 동기화되기까지 약 10초가 걸립니다. 동기화 이후에 적재되는 데이터부터 정상적으로 적용됩니다.
+5. `normalizer`와 `analyzer`는 같은 역색인에 함께 지정할 수 없습니다.
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/inverted-index/overview.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/inverted-index/overview.md
new file mode 100644
index 00000000000..4fcbe13ce8d
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/inverted-index/overview.md
@@ -0,0 +1,251 @@
+---
+{
+ "title": "역색인(텍스트 검색)",
+ "sidebar_label": "개요",
+ "language": "ko",
+ "description": "Doris 텍스트 검색은 역색인을 기반으로 하며 전문 검색, 구문 매칭, 정규식 매칭, 사용자 정의 토큰화, BM25 관련도 점수 산정을 지원합니다. 벡터 검색과 결합하여 RAG와 같은 하이브리드 검색 시나리오에 활용할 수 있습니다."
+}
+---
+
+<!-- Knowledge type: Feature introduction + Quick start -->
+<!-- Applicable scenarios: Keyword search / Phrase matching / RAG hybrid retrieval / Relevance ranking -->
+
+텍스트 검색은 데이터 세트에서 특정 용어나 구문이 포함된 문서를 검색하고 관련도에 따라 결과의 순위를 매깁니다.
+
+| 검색 방식 | 강점 | 적용 시나리오 |
+|----------|------|----------|
+| 텍스트 검색 | "정확하게 찾기": 제어와 설명이 가능한 정확한 매칭으로 키워드 일치와 필터 조건 충족을 확실하게 보장 | 키워드 검색, 구문 매칭, 불리언 필터링 |
+| 벡터 검색 | "폭넓게 찾기": 의미적 유사성을 활용하여 검색 범위를 확장 | 의미 검색, 근사 매칭 |
+
+생성형 AI 애플리케이션, 특히 검색 증강 생성(RAG) 시나리오에서 텍스트 검색과 벡터 검색은 서로를 보완합니다.
+
+- 의미적 포괄성과 어휘적 정밀성 사이의 균형 유지
+- 결과의 정확성과 설명 가능성을 보장하면서 재현율 향상
+- 두 방식을 함께 사용하여 대규모 언어 모델에 더 정확하고 관련성 높은 맥락을 제공하는 신뢰할 수 있는 검색 기반 구축
+
+:::caution 4.1.5부터 V1 역색인 생성 금지
+
+새 인덱스에는 V2 또는 V3를 사용하세요. 기존 V1 테이블은 계속 읽을 수 있지만, 역색인을 추가하거나 `ALTER TABLE`로 기존 테이블의 인덱스 저장 형식을 업그레이드할 수는 없습니다. 대신 테이블을 다시 생성해야 합니다. 적용되는 `inverted_index_storage_format` 설정이 `V1`로 남아 있으면 업그레이드 후 FE를 시작할 수 없습니다. 미리 `fe.conf`와 `fe_custom.conf`를 수정하세요. [4.1.5로 업그레이드](../../../admin-manual/cluster-management/upgrade.md)를 참고하세요.
+
+:::
+
+## Doris 텍스트 검색의 발전 과정 {#evolution-of-text-search-in-doris}
+
+Doris는 2.0.0 버전부터 고성능 전문 검색을 지원하기 위해 역색인을 도입했습니다. 검색 시나리오가 다양해지고 쿼리가 복잡해짐에 따라 이후 릴리스에서도 텍스트 검색 기능을 지속적으로 확장해 왔습니다.
+
+| 단계 | 버전 | 주요 기능 |
+|------|------|----------|
+| 기반 구축 | 2.0+ | 컬럼 단위 역색인 도입. 기본 전문 검색 연산자(`MATCH_ANY`, `MATCH_ALL`)와 다국어 토크나이저를 제공하여 대규모 데이터 세트에서 효율적인 키워드 검색 지원 |
+| 기능 확장 | 2.x~3.x | 연산자 체계를 강화하고 구문 매칭(`MATCH_PHRASE`), 접두사 검색(`MATCH_PHRASE_PREFIX`), 정규식 매칭(`MATCH_REGEXP`) 등의 고급 연산자 추가. 3.1 버전에서 사용자 정의 토큰화 도입 |
+| 기능 고도화 | 4.0+ | BM25 관련도 점수 산정과 통합 쿼리 진입점인 `SEARCH` 함수를 도입하여 텍스트 관련도 순위 및 하이브리드 순위 산정 지원 |
+
+4.0+의 주요 개선 사항은 다음과 같습니다.
+
+- **BM25 관련도 점수 산정**: `score()` 함수는 텍스트 관련도에 따라 결과의 순위를 매기며, 벡터 유사도 점수와 결합하여 하이브리드 순위를 산정할 수 있습니다.
+- **SEARCH 함수**: 여러 컬럼에 걸친 쿼리와 불리언 논리 조합을 지원하는 통합 쿼리 DSL을 제공합니다. 복잡한 쿼리 구성을 간소화하고 쿼리 성능도 더욱 향상시킵니다.
+
+---
+
+## Doris 텍스트 검색의 핵심 기능 {#core-text-search-features-in-doris}
+
+### 1. 다양한 텍스트 연산자 {#1-rich-text-operators}
+
+Doris는 다양한 검색 패턴을 지원하는 전문 검색 연산자를 제공하여 기본적인 키워드 매칭부터 복잡한 구문 쿼리까지 폭넓은 요구 사항을 충족합니다.
+
+현재 버전에서 지원하는 주요 연산자는 다음과 같습니다.
+
+| 연산자 | 설명 | 일반적인 시나리오 |
+|------|------|----------|
+| `MATCH_ANY` / `MATCH_ALL` | 하나 이상의 용어 매칭(OR) 및 모든 용어 매칭(AND) | 일반적인 키워드 검색 |
+| `MATCH_PHRASE` | 정확한 구문 매칭. 사용자 정의 slop과 순서 제어 지원 | 단어 간 근접성 쿼리 |
+| `MATCH_PHRASE_PREFIX` | 구문 접두사 매칭 | 자동 완성, 점진적 검색 |
+| `MATCH_REGEXP` | 정규식 기반 매칭 | 패턴 기반 텍스트 검색 |
+
+이 연산자들은 개별적으로 사용하거나 `SEARCH()` 함수를 통해 조합하여 복잡한 논리 쿼리를 구성할 수 있습니다. 예를 들면 다음과 같습니다.
+
+```sql
+-- Exact phrase search
+SELECT * FROM docs WHERE content MATCH_PHRASE 'inverted index';
+
+-- Prefix search
+SELECT * FROM docs WHERE content MATCH_PHRASE_PREFIX 'data ware';
+```
+
+[모든 연산자 보기](./search-operators.md)
+
+---
+
+### 2. 사용자 정의 토큰화(3.1+) {#2-custom-tokenization-31}
+
+텍스트 검색에서 토큰화 방식은 검색의 정밀도와 재현율을 직접 결정합니다. Doris는 3.1 버전부터 **사용자 정의 분석기**를 지원하므로 비즈니스 요구 사항에 맞게 토큰화 파이프라인을 유연하게 정의할 수 있습니다.
+
+사용자 정의 토큰화는 다음 세 가지 유형의 구성 요소를 조합하여 텍스트를 세밀하게 제어합니다.
+
+- **문자 필터(char_filter)**: 토큰화 전에 기호를 대체하거나 제거하거나 정규화합니다.
+- **토크나이저(tokenizer)**: 토큰화 알고리즘을 선택합니다. `standard`, `ngram`, `edge_ngram`, `keyword`, `icu` 등의 유형을 지원하여 다양한 언어와 구조의 텍스트를 처리합니다.
+- **토큰 필터(token_filter)**: `lowercase`, `word_delimiter`, `ascii_folding` 등의 필터로 토큰화 결과를 정규화하고 다듬습니다.
+
+```sql
+-- Example: Define a custom analyzer
+CREATE INVERTED INDEX ANALYZER IF NOT EXISTS keyword_lowercase
+PROPERTIES (
+ "tokenizer" = "keyword",
+ "token_filter" = "asciifolding, lowercase"
+);
+
+-- Use the custom analyzer when creating a table
+CREATE TABLE docs (
+ id BIGINT,
+ content TEXT,
+ INDEX idx_content (content) USING INVERTED PROPERTIES(
+ "analyzer" = "keyword_lowercase",
+ "support_phrase" = "true"
+ )
+);
+```
+
+[사용자 정의 토큰화 알아보기](./custom-analyzer.md)
+
+---
+
+### 3. BM25 관련도 점수 산정(4.0+) {#3-bm25-relevance-scoring-40}
+
+Doris는 텍스트 관련도를 계산하는 **BM25 (Best Matching 25)** 알고리즘을 구현하여 전문 검색에 순위 및 점수 산정 기능을 제공합니다.
+
+BM25의 핵심 특징은 다음과 같습니다.
+
+- 용어 빈도(TF), 역문서 빈도(IDF), 문서 길이를 기반으로 하는 확률 모델
+- 짧은 텍스트와 긴 텍스트 모두에 안정적으로 적용
+- `k1`과 `b` 매개변수로 가중치 전략 조정 가능
+
+```sql
+SELECT id, title, score() AS relevance
+FROM docs
+WHERE content MATCH_ANY 'real-time OLAP analytics'
+ORDER BY relevance DESC
+LIMIT 10;
+```
+
+[점수 산정 방식 자세히 알아보기](./scoring.md)
+
+---
+
+### 4. SEARCH 함수: 통합 쿼리 진입점(4.0+) {#4-search-function-unified-query-entry-point-40}
+
+`SEARCH()` 함수는 텍스트 검색을 위한 통합 구문 진입점을 제공합니다. 여러 컬럼 검색과 불리언 논리 조합을 지원하여 복잡한 쿼리를 더 간결하게 표현할 수 있습니다.
+
+```sql
+SELECT id, title, score() AS relevance
+FROM docs
+WHERE SEARCH('title:Machine AND tags:ANY(database sql)')
+ORDER BY relevance DESC
+LIMIT 20;
+```
+
+[SEARCH 함수 전체 가이드](./search-function.md)
+
+---
+
+## 빠른 시작 {#quick-start}
+
+### 1단계: 역색인이 있는 테이블 생성 {#step-1-create-a-table-with-inverted-indexes}
+
+```sql
+CREATE TABLE docs (
+ id BIGINT,
+ title STRING,
+ content STRING,
+ category STRING,
+ tags ARRAY<STRING>,
+ created_at DATETIME,
+ -- Text search indexes
+ INDEX idx_title(title) USING INVERTED PROPERTIES ("parser" = "chinese"),
+ INDEX idx_content(content) USING INVERTED PROPERTIES ("parser" = "chinese", "support_phrase" = "true"),
+ INDEX idx_category(category) USING INVERTED,
+ INDEX idx_tags(tags) USING INVERTED
+)
+DUPLICATE KEY(id)
+DISTRIBUTED BY HASH(id) BUCKETS 10;
+```
+
+### 2단계: 텍스트 쿼리 실행 {#step-2-run-text-queries}
+
+```sql
+-- Simple keyword search
+SELECT * FROM docs WHERE content MATCH_ANY 'apache doris';
+
+-- Phrase search
+SELECT * FROM docs WHERE content MATCH_PHRASE 'full-text search';
+
+-- Boolean query with SEARCH
+SELECT * FROM docs
+WHERE SEARCH('title:apache AND (category:database OR tags:ANY(sql nosql))');
+
+-- Relevance-based ranking
+SELECT id, title, score() AS relevance
+FROM docs
+WHERE content MATCH_ANY 'real-time analytics OLAP'
+ORDER BY relevance DESC
+LIMIT 10;
+```
+
+## 하이브리드 검색: 텍스트 + 벡터 {#hybrid-search-text--vector}
+
+RAG 애플리케이션에서는 텍스트 검색과 벡터 유사도를 결합하여 더 포괄적인 검색을 수행할 수 있습니다.
+
+```sql
+-- Hybrid retrieval: semantic similarity + keyword filtering
+SELECT id, title, score() AS text_relevance
+FROM docs
+WHERE
+ -- Vector filter for semantic similarity
+ cosine_distance(embedding, [0.1, 0.2, ...]) < 0.3
+ -- Text filter for keyword constraints
+ AND SEARCH('title:search AND content:engine AND category:technology')
+ORDER BY text_relevance DESC
+LIMIT 10;
+```
+
+## 역색인 관리 {#managing-inverted-indexes}
+
+### 인덱스 생성 {#create-an-index}
+
+```sql
+-- Create at table creation time
+CREATE TABLE t (
+ content STRING,
+ INDEX idx(content) USING INVERTED PROPERTIES ("parser" = "chinese")
+);
+
+-- Create on an existing table
+CREATE INDEX idx_content ON docs(content) USING INVERTED PROPERTIES ("parser" = "chinese");
+
+-- Build the index for existing data
+BUILD INDEX idx_content ON docs;
+```
+
+### 인덱스 삭제 {#drop-an-index}
+
+```sql
+DROP INDEX idx_content ON docs;
+```
+
+### 인덱스 조회 {#view-indexes}
+
+```sql
+SHOW CREATE TABLE docs;
+SHOW INDEX FROM docs;
+```
+
+## 추가 자료 {#further-reading}
+
+### 핵심 문서 {#core-documentation}
+
+- [텍스트 검색 연산자](./search-operators.md): 전체 연산자 레퍼런스 및 쿼리 가속
+- [SEARCH 함수](./search-function.md): 통합 쿼리 DSL 구문 및 예제
+- [관련도 점수 산정](./scoring.md): 관련도 순위 산정 알고리즘 및 사용법
+
+### 고급 주제 {#advanced-topics}
+
+- [사용자 정의 분석기](./custom-analyzer.md): 도메인별 토크나이저 및 필터 구성
+- [벡터 검색](../vector-index/overview.md): 임베딩 벡터를 활용한 의미적 유사성 검색
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/inverted-index/scoring.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/inverted-index/scoring.md
new file mode 100644
index 00000000000..5ef484e58b6
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/inverted-index/scoring.md
@@ -0,0 +1,156 @@
+---
+{
+ "title": "관련도 점수 산정",
+ "language": "ko",
+ "description": "Doris 전문 검색은 BM25 알고리즘으로 쿼리 결과의 관련도 점수를 계산합니다. 단어 빈도, 역문서 빈도, 레코드 길이를 종합하여 관련성이 가장 높은 콘텐츠가 먼저 반환되도록 결과의 순위를 매깁니다."
+}
+---
+
+<!-- Knowledge type: Feature / Query usage -->
+<!-- Applicable scenarios: Full-text search result ranking / Search relevance optimization -->
+
+전문 검색 쿼리(예: `MATCH_ANY`, `MATCH_ALL`, `MATCH_PHRASE` 등)를 실행할 때는 관련성이 가장 높은 레코드가 먼저 반환되도록 결과를 "일치도"에 따라 정렬해야 하는 경우가 많습니다. Doris는 **관련도 점수 산정** 기능을 제공합니다. 쿼리 조건에 따라 각 행에 수치 점수를 부여하며, 점수가 높을수록 관련성이 높다는 의미입니다.
+
+Doris는 현재 관련도 점수 산정의 기본 구현으로 **BM25 (Best Matching 25)** 알고리즘을 사용합니다.
+
+**주요 활용 사례:**
+
+- 검색 엔진 애플리케이션: 키워드를 기준으로 관련성이 가장 높은 문서 목록 반환
+- 로그 분석: 관련도순으로 정렬하여 키워드와 가장 잘 일치하는 로그를 빠르게 탐색
+- 콘텐츠 추천: 텍스트 유사도를 기준으로 우선적으로 제공할 콘텐츠 선별
+- 지식 베이스 검색: 질문과의 관련도순으로 정렬된 답변 후보 반환
+
+## 빠른 시작 {#quick-start}
+
+다음 예제는 쿼리에서 관련도 점수 산정을 활성화하고 점수순으로 정렬하는 방법을 보여 줍니다.
+
+```sql
+SELECT *,
+ score() AS relevance
+FROM search_demo
+WHERE content MATCH_ANY 'text search test'
+ORDER BY relevance DESC
+LIMIT 10;
+```
+
+쿼리를 실행하면 Doris는 BM25 알고리즘으로 각 행의 점수를 계산하고 관련성이 가장 높은 상위 10개 레코드를 반환합니다.
+
+```text
++------+-----------------------------------+---------+--------------+-----------+
+| id | content | author | publish_date | relevance |
++------+-----------------------------------+---------+--------------+-----------+
+| 1 | Full text search engine test demo | Alice | 2024-01-01 | 2.915228 |
+| 7 | Text processing techniques | Grace | 2024-01-07 | 1.341931 |
+| 5 | Performance test framework | Eve | 2024-01-05 | 1.341931 |
+| 3 | Advanced search algorithms | Charlie | 2024-01-03 | 1.341931 |
++------+-----------------------------------+---------+--------------+-----------+
+```
+
+## 활성화 조건 {#activation-conditions}
+
+점수 계산이 적용되려면 쿼리가 다음 세 가지 조건을 모두 충족해야 합니다.
+
+1. `SELECT` 절에서 `score()` 함수를 명시적으로 호출해야 합니다.
+2. `WHERE` 절에 하나 이상의 `MATCH_*` 조건이 포함되어야 합니다.
+3. 쿼리가 Top-N 쿼리여야 하며, `ORDER BY`가 `score()` 결과를 기준으로 해야 합니다.
+
+### 지원되는 인덱스 유형 {#supported-index-types}
+
+| 인덱스 유형 | 점수 산정 지원 | 설명 |
+| -------------------------------- | ----------------- | ---------------------------------------------------------- |
+| 토큰화된 역색인 | 예 | BM25 관련도 점수를 계산할 수 있음 |
+| 토큰화되지 않은 역색인 | 아니요 | 정확히 일치하는 검색만 지원하며 점수는 계산하지 않음 |
+
+### 지원되는 쿼리 유형 {#supported-query-types}
+
+- `MATCH_ANY`
+- `MATCH_ALL`
+- `MATCH_PHRASE`
+- `MATCH_PHRASE_PREFIX`
+- `SEARCH`
+
+## BM25 알고리즘 {#bm25-algorithm}
+
+BM25는 확률 모델에 기반한 텍스트 관련도 알고리즘입니다. **단어 빈도(TF)**, **역문서 빈도(IDF)**, **레코드 길이**라는 세 가지 요소를 함께 고려하여 일치 결과에 가중치를 적용해 점수를 계산합니다. 기존 TF-IDF 모델에 비해 BM25는 더 안정적이고 유연하게 조정할 수 있으며, 긴 텍스트와 짧은 텍스트 간의 점수 차이를 효과적으로 조절합니다.
+
+### 핵심 수식 {#core-formula}
+
+```text
+score = IDF × (tf × (k1 + 1)) / (tf + k1 × (1 - b + b × |d| / avgdl))
+```
+
+수식에 사용된 변수의 정의는 다음과 같습니다.
+
+| 변수 | 의미 |
+| ----------- | ---------------------------------------------------- |
+| `tf` | 현재 행에서 쿼리 단어가 등장하는 횟수 |
+| `IDF` | 단어가 얼마나 드문지를 나타내는 역문서 빈도 |
+| `\|d\|` | 현재 행의 길이(토큰화 후 토큰 수) |
+| `avgdl` | 테이블에 있는 모든 행의 평균 길이 |
+| `k1`, `b` | 알고리즘 조정 매개변수 |
+
+### 매개변수 {#parameters}
+
+| 매개변수 | 기본값 | 설명 |
+| --------- | ------- | ------------------------------------------------------ |
+| `k1` | 1.2 | 단어 빈도가 점수에 미치는 영향의 크기 조절 |
+| `b` | 0.75 | 레코드 길이 정규화의 강도 조절 |
+| `boost` | 1.0 | 쿼리 수준의 가중치 계수 |
+
+### 보조 통계 {#auxiliary-statistics}
+
+```text
+IDF = log(1 + (N - n + 0.5) / (n + 0.5))
+avgdl = total_terms / total_rows
+```
+
+각 변수의 의미는 다음과 같습니다.
+
+- `N`: 테이블의 전체 행 수
+- `n`: 쿼리 단어를 포함하는 행 수
+
+쿼리에 여러 단어가 포함된 경우, **최종 점수는 각 단어의 점수를 합한 값입니다**.
+
+### 레코드 길이와 `norms` 속성 {#record-length-and-the-norms-property}
+
+`norms` 인덱스 속성과 `inverted_index_skip_norms_for_variant` BE 설정은 Doris 4.1.5부터 지원됩니다.
+
+`|d|`는 norms에서 가져옵니다. norms는 인덱싱된 필드마다 행당 한 바이트의 공간을 사용하며, 해당 필드에 값이 없는 행도 포함됩니다. 토큰화된 인덱스는 기본적으로 norms를 기록하지만(`"norms" = "true"`), 토큰화되지 않은 인덱스는 기록하지 않습니다. 필터링에만 사용하는 인덱스는 `"norms" = "false"`로 설정하여 공간을 절약할 수 있습니다.
+
+```sql
+INDEX idx_content(content) USING INVERTED PROPERTIES("parser" = "english", "norms" = "false")
+```
+
+VARIANT 하위 경로는 인덱스의 `norms` 속성을 상속하며, `rows × paths` 바이트의 공간을 사용합니다. BE 설정 `inverted_index_skip_norms_for_variant`(기본값 `false`, 런타임에 변경 가능)을 `true`로 설정하면 모든 VARIANT 경로 인덱스에서 norms가 비활성화됩니다. 이 설정은 인덱스 속성보다 우선합니다.
+
+norms를 비활성화해도 `MATCH_*` 필터링에는 영향이 없지만, `score()`가 norms가 없는 세그먼트를 하나라도 읽으면 오류를 반환합니다. 이 설정은 새로 기록되는 세그먼트에 적용됩니다. 기존 세그먼트는 compaction으로 다시 기록될 때까지 그대로 유지됩니다. 이 설정을 변경하기 전에 모든 BE를 해당 설정을 지원하는 버전으로 업그레이드하세요.
+
+## 결과 해석 {#interpreting-the-results}
+
+점수 산정 결과를 이해하면 관련도 순위를 더 정확하게 활용할 수 있습니다.
+
+| 특성 | 설명 |
+| -------------- | -------------------------------------------------------------------------------------- |
+| 점수 범위 | 상한이 정해져 있지 않은 양수이며, 일반적으로 절댓값보다 상대적인 크기가 중요함 |
+| 여러 단어를 포함한 쿼리 | 여러 단어가 포함되면 전체 점수는 각 단어의 점수를 합한 값임 |
+| 길이의 영향 | 일치하는 단어가 같을 때는 짧은 레코드가 조금 더 높은 점수를 받음 |
+| 일치하는 단어가 없는 경우 | 쿼리 단어가 테이블에 없으면 해당 점수는 0임 |
+
+## 자주 묻는 질문 {#faq}
+
+**Q1: 쿼리에서 점수가 반환되지 않는 이유는 무엇인가요?**
+
+다음 사항을 순서대로 확인하세요.
+
+1. `score()` 함수가 `SELECT`에서 호출되는지 확인합니다.
+2. `WHERE` 절에 `MATCH_*` 조건이 포함되어 있는지 확인합니다.
+3. `ORDER BY`가 `score()`를 기준으로 하는지 확인합니다.
+4. 인덱스가 토큰화된 역색인인지 확인합니다.
+
+**Q2: BM25와 TF-IDF의 차이점은 무엇인가요?**
+
+BM25는 TF-IDF를 기반으로 **단어 빈도 포화**와 **길이 정규화**라는 두 가지 개선 사항을 도입했습니다. 이를 통해 긴 텍스트와 짧은 텍스트의 점수가 더 균형을 이루고 안정성이 높아집니다.
+
+**Q3: 서로 다른 쿼리의 점수를 비교할 수 있나요?**
+
+권장하지 않습니다. BM25 점수는 쿼리에 사용된 단어와 테이블의 데이터 분포에 따라 달라집니다. 서로 다른 쿼리 간에는 절댓값을 비교할 수 없습니다. **동일한 쿼리의 결과 집합 내에서만 상대적인 크기를 비교하세요.**
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/inverted-index/search-function.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/inverted-index/search-function.md
new file mode 100644
index 00000000000..ffa4f773ce4
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/inverted-index/search-function.md
@@ -0,0 +1,497 @@
+---
+{
+ "title": "SEARCH 함수",
+ "language": "ko",
+ "description": "SEARCH 함수는 Apache Doris 4.0에서 제공하는 통합 전문 검색 진입점입니다. 간결한 DSL 표현식으로 쿼리 조건을 기술하고 역색인을 기반으로 검색어, 구문, 불리언, 와일드카드 및 정규 표현식 검색을 효율적으로 실행합니다."
+}
+---
+
+<!-- Knowledge type: Function reference / Procedure -->
+<!-- Use cases: Full-text search / Inverted index query / DSL expression authoring -->
+
+`SEARCH` 함수는 Apache Doris 버전 4.0부터 제공되는 통합 전문 검색 쿼리 진입점입니다. 간결한 DSL(도메인 특화 언어)로 쿼리 조건을 기술하고 역색인을 기반으로 효율적으로 실행합니다.
+
+`SEARCH`는 불리언 값을 반환하는 술어 함수입니다. `WHERE` 절에서 필터 조건으로 사용할 수 있습니다. 텍스트 매칭 규칙을 기술하는 SEARCH DSL 문자열을 받아 매칭 가능한 조건을 역색인으로 푸시다운하여 실행합니다.
+
+**대표적인 사용 사례:**
+
+- 텍스트 필드에서 검색어, 구문 및 불리언 조합 검색 수행
+- 여러 컬럼에 걸친 조합 검색 실행
+- 와일드카드나 정규 표현식을 사용한 패턴 매칭
+- VARIANT 하위 컬럼에서 구조화된 텍스트 검색 수행
+- Lucene/Elasticsearch의 query_string 구문 스타일과의 호환성 유지
+
+## 구문 {#syntax}
+
+### 기본 호출 형식 {#basic-invocation-forms}
+
+```sql
+SEARCH('<search_expression>')
+SEARCH('<search_expression>', '<default_field>')
+SEARCH('<search_expression>', '<default_field>', '<default_operator>')
+```
+
+**매개변수 설명:**
+
+| 매개변수 | 필수 여부 | 설명 |
+| --- | --- | --- |
+| `<search_expression>` | 필수 | SEARCH DSL 쿼리 표현식(문자열 리터럴) |
+| `<default_field>` | 선택 | DSL의 검색어에 필드가 명시되지 않았을 때 자동으로 적용할 컬럼 이름 |
+| `<default_operator>` | 선택 | 여러 검색어로 이루어진 표현식에 사용할 기본 불리언 연산자. `and` 또는 `or`만 허용되며 대소문자를 구분하지 않음. 기본값은 `or` |
+
+**사용 시 참고 사항:**
+
+- **위치**: `WHERE` 절에서 행 필터링에 참여하는 술어로 사용
+- **반환 타입**: BOOLEAN(매칭되면 TRUE)
+
+`default_field`를 지정하면 Doris는 필드가 지정되지 않은 검색어나 함수를 해당 필드에 적용되도록 자동 확장합니다. 예를 들면 다음과 같습니다.
+
+- `SEARCH('foo bar', 'tags', 'and')`는 `SEARCH('tags:ALL(foo bar)')`와 동일합니다
+- `SEARCH('foo bar', 'tags')`는 `tags:ANY(foo bar)`로 확장됩니다
+
+DSL에 명시적으로 지정된 불리언 연산은 우선순위가 가장 높으며 기본 연산자보다 우선 적용됩니다.
+
+### 옵션 매개변수(JSON 형식) {#options-parameter-json-format}
+
+두 번째 매개변수에 JSON 문자열을 지정하여 고급 설정을 적용할 수도 있습니다.
+
+```sql
+SEARCH('<search_expression>', '<options_json>')
+```
+
+**지원 옵션:**
+
+| 옵션 | 타입 | 설명 |
+| --- | --- | --- |
+| `default_field` | 문자열 | 필드가 명시되지 않은 검색어에 사용할 기본 컬럼 이름 |
+| `default_operator` | 문자열 | 여러 검색어로 이루어진 표현식에 사용할 기본 연산자(`and` 또는 `or`) |
+| `mode` | 문자열 | `standard`(기본값) 또는 `lucene` |
+| `minimum_should_match` | 정수 | 매칭되어야 하는 SHOULD 절의 최소 개수(Lucene 모드에서만 사용) |
+| `fields` | 문자열 배열 | 필드가 명시되지 않은 검색어에 적용할 대상 컬럼을 선택적으로 지정. 비어 있지 않은 `default_field`와 함께 사용할 수 없음 |
+| `type` | 문자열 | 다중 필드 확장 방식을 선택적으로 지정: `best_fields`(기본값) 또는 `cross_fields`. 점수 계산이나 정렬 알고리즘을 선택하는 옵션은 아님 |
+
+**예제:**
+
+```sql
+SELECT * FROM docs
+WHERE SEARCH('apple banana',
+ '{"default_field":"title","default_operator":"and","mode":"lucene"}');
+```
+
+### NULL과 삼치 논리 {#null-and-three-valued-logic}
+
+`SEARCH()`는 SQL 삼치 논리를 따릅니다.
+
+- 매칭에 참여하는 모든 컬럼 값이 NULL이면 결과는 UNKNOWN입니다(`WHERE`에서 제외됨)
+- 다른 하위 표현식과 결합하면 불리언 단락 평가 규칙을 따릅니다. 예를 들면 다음과 같습니다.
+ - `TRUE OR NULL = TRUE`
+ - `FALSE OR NULL = NULL`
+ - `NOT NULL = NULL`
+
+이 동작은 텍스트 검색 연산자와 일치합니다.
+
+## 시나리오별 SEARCH 사용법 {#using-search-by-scenario}
+
+### 시나리오 1: 단일 검색어 매칭 {#scenario-1-single-term-match}
+
+**사용 사례:** 필드에 특정 검색어가 포함된 문서를 검색합니다.
+
+- **구문:** `column:term`
+- **의미:** 컬럼을 토큰화한 결과에서 검색어를 매칭합니다. 대소문자 구분 여부는 인덱스 속성 `lower_case`에 따라 달라집니다
+- **인덱스 권장 사항:** 컬럼에 적절한 `parser`/`analyzer`를 사용하는 역색인을 생성합니다
+
+```sql
+SELECT id, title FROM search_test_basic WHERE SEARCH('title:Machine');
+SELECT id, title FROM search_test_basic WHERE SEARCH('title:Python');
+SELECT id, title FROM search_test_basic WHERE SEARCH('category:Technology');
+```
+
+### 시나리오 2: 여러 검색어의 OR 매칭(ANY) {#scenario-2-multi-term-or-match-any}
+
+**사용 사례:** 후보 목록의 검색어 중 하나라도 매칭되면 일치하는 것으로 간주합니다. 태그 매칭이나 여러 키워드를 조합한 검색에 사용할 수 있습니다.
+
+- **구문:** `column:ANY(term1 term2 ...)`
+- **의미:** 컬럼을 토큰화한 결과에 목록의 검색어 중 하나라도 포함되어야 합니다(OR 의미). 순서는 상관없으며 중복 검색어는 무시됩니다
+- **인덱스 권장 사항:** 컬럼에 토큰화 역색인을 생성합니다(예: `english`/`chinese`/`unicode`)
+
+```sql
+SELECT id, title FROM search_test_basic WHERE SEARCH('tags:ANY(python javascript)');
+SELECT id, title FROM search_test_basic WHERE SEARCH('tags:ANY(machine learning tutorial)');
+
+-- Edge case: a single-value ANY is equivalent to a term query
+SELECT id, title FROM search_test_basic WHERE SEARCH('tags:ANY(python)');
+```
+
+### 시나리오 3: 여러 검색어의 AND 매칭(ALL) {#scenario-3-multi-term-and-match-all}
+
+**사용 사례:** 여러 검색어가 모두 매칭되어야 합니다. 엄격한 주제 필터링 등에 사용할 수 있습니다.
+
+- **구문:** `column:ALL(term1 term2 ...)`
+- **의미:** 컬럼을 토큰화한 결과에 목록의 모든 검색어가 함께 포함되어야 합니다(AND 의미). 순서는 상관없으며 중복 검색어는 무시됩니다
+- **인덱스 권장 사항:** 컬럼에 토큰화 역색인을 생성합니다(예: `english`/`chinese`/`unicode`)
+
+```sql
+SELECT id, title FROM search_test_basic WHERE SEARCH('tags:ALL(machine learning)');
+SELECT id, title FROM search_test_basic WHERE SEARCH('tags:ALL(programming tutorial)');
+
+-- Edge case: a single-value ALL is equivalent to a term query
+SELECT id, title FROM search_test_basic WHERE SEARCH('tags:ALL(python)');
+```
+
+### 시나리오 4: 불리언 조합 쿼리 {#scenario-4-boolean-combination-query}
+
+**사용 사례:** 여러 조건을 AND/OR/NOT으로 결합해야 할 때 사용합니다. 예를 들어 "A를 포함하고 B를 포함하지 않아야 함"과 같은 조건입니다.
+
+- **구문:** `(expr) AND/OR/NOT (expr)`
+- **의미:** SEARCH 내부의 하위 표현식을 `AND`, `OR`, `NOT`으로 결합합니다
+- **인덱스 권장 사항:** 인덱스 푸시다운을 활용할 수 있도록 매칭 가능한 조건은 가급적 SEARCH 내부에 배치합니다. 추가 필터링에는 다른 WHERE 조건을 사용합니다
+
+```sql
+SELECT id, title FROM search_test_basic
+WHERE SEARCH('title:Machine AND category:Technology');
+
+SELECT id, title FROM search_test_basic
+WHERE SEARCH('title:Python OR title:Data');
+
+SELECT id, title FROM search_test_basic
+WHERE SEARCH('category:Technology AND NOT title:Machine');
+```
+
+### 시나리오 5: 복잡한 중첩 표현식 {#scenario-5-complex-nested-expressions}
+
+**사용 사례:** 괄호로 불리언 연산의 우선순위를 제어하고 다단계로 중첩된 필터 조건을 구성합니다.
+
+- **구문:** 괄호로 표현식을 그룹화합니다. 예: `(expr1 OR expr2) AND expr3`
+- **의미:** 괄호로 불리언 연산의 우선순위를 제어합니다. 다단계 중첩을 지원합니다
+- **인덱스 권장 사항:** 불리언 조합 쿼리와 동일합니다
+
+```sql
+SELECT id, title FROM search_test_basic
+WHERE SEARCH('(title:Machine OR title:Python) AND category:Technology');
+
+SELECT id, title FROM search_test_basic
+WHERE SEARCH('tags:ANY(python javascript) AND (category:Technology OR category:Programming)');
+```
+
+### 시나리오 6: Lucene/Elasticsearch 구문 호환성 {#scenario-6-luceneelasticsearch-syntax-compatibility}
+
+**사용 사례:** Elasticsearch에서 마이그레이션하거나 Lucene query_string 의미 체계에 따라 표현식을 작성할 때 사용합니다.
+
+Lucene 모드는 Elasticsearch/Lucene의 query_string 동작을 에뮬레이션합니다. 불리언 연산자는 전통적인 불리언 대수 규칙 대신 왼쪽에서 오른쪽으로 적용되는 수정자로 동작합니다.
+
+**표준 모드와의 주요 차이점:**
+
+- AND/OR/NOT은 인접한 검색어에 영향을 주는 수정자입니다
+- 연산자 우선순위는 왼쪽에서 오른쪽으로 적용됩니다
+- 내부적으로 MUST/SHOULD/MUST_NOT을 사용합니다(Lucene의 Occur 열거형과 유사)
+- NOT만으로 구성된 쿼리는 빈 결과를 반환합니다(긍정 절이 필요함)
+
+**Lucene 모드 활성화:**
+
+```sql
+-- Basic Lucene mode
+SELECT * FROM docs
+WHERE SEARCH('apple AND banana',
+ '{"default_field":"title","mode":"lucene"}');
+
+-- Use minimum_should_match
+SELECT * FROM docs
+WHERE SEARCH('apple AND banana OR cherry',
+ '{"default_field":"title","mode":"lucene","minimum_should_match":1}');
+```
+
+**동작 비교:**
+
+| 쿼리 | 표준 모드 | Lucene 모드 |
+| --- | --- | --- |
+| `a AND b` | a ∩ b | +a +b (둘 다 MUST) |
+| `a OR b` | a ∪ b | a b (둘 다 SHOULD, min=1) |
+| `NOT a` | ¬a | a를 제외한 모든 문서와 매칭(`-a`) |
+| `a AND NOT b` | a ∩ ¬b | +a -b (a는 MUST, b는 MUST_NOT) |
+| `a AND b OR c` | (a ∩ b) ∪ c | +a b c (a만 MUST) |
+
+> **참고:** Lucene 모드에서 `a AND b OR c`는 왼쪽에서 오른쪽으로 파싱됩니다. OR 연산자는 `b`를 MUST에서 SHOULD로 변경합니다. SHOULD 절의 매칭을 필수로 지정하려면 `minimum_should_match`를 사용하세요.
+
+### 시나리오 7: 구문 쿼리 {#scenario-7-phrase-query}
+
+**사용 사례:** 연속적이고 순서가 있는 구문을 검색합니다. 예를 들어 "machine learning"이 해당 순서로 나타나도록 요구할 수 있습니다.
+
+- **구문:** `column:"quoted phrase"`
+- **의미:** 컬럼의 분석기에 따라 연속적이고 순서가 있는 검색어를 매칭합니다. 전체 구문을 큰따옴표로 감싸야 합니다
+- **인덱스 권장 사항:** 대상 컬럼은 위치 정보를 포함하는 토큰화 역색인을 사용해야 합니다(`parser`로 설정)
+
+```sql
+SELECT id, title FROM search_test_basic
+WHERE SEARCH('content:"machine learning"');
+```
+
+### 시나리오 8: 여러 컬럼에 걸친 조합 검색 {#scenario-8-combined-search-across-multiple-columns}
+
+**사용 사례:** 하나의 쿼리로 여러 필드를 검색합니다. 예를 들어 제목, 태그 또는 작성자가 매칭되는 행을 반환할 수 있습니다.
+
+- **구문:** `column1:term OR column2:ANY(...) OR ...`
+- **의미:** 하나의 표현식에서 여러 컬럼을 매칭합니다. 각 컬럼에는 해당 컬럼의 인덱스/토크나이저 설정이 적용됩니다
+- **인덱스 권장 사항:** 검색에 참여하는 각 컬럼에 적절한 역색인을 생성합니다
+
+```sql
+SELECT id, title FROM search_test_basic
+WHERE SEARCH('title:Python OR tags:ANY(database mysql) OR author:Alice');
+
+SELECT id, title FROM search_test_basic
+WHERE SEARCH('tags:ALL(tutorial) AND category:Technology');
+```
+
+### 시나리오 9: 와일드카드 쿼리 {#scenario-9-wildcard-query}
+
+**사용 사례:** 접두사, 접미사 또는 포함 여부를 기준으로 매칭합니다. 예를 들어 "Chris"로 시작하는 모든 이름을 검색할 수 있습니다.
+
+- **구문:** `column:prefix*`, `column:*mid*`, `column:?ingle`
+- **의미:** `*`는 임의 길이의 문자열과 매칭하고, `?`는 단일 문자와 매칭합니다
+- **인덱스 권장 사항:** 비토큰화 인덱스에 적합합니다. 토큰화 인덱스에서도 `lower_case`를 활성화하면 대소문자를 구분하지 않는 매칭에 사용할 수 있습니다
+
+```sql
+SELECT id, title FROM search_test_basic
+WHERE SEARCH('firstname:Chris*');
+
+-- Combine with the default field parameter
+SELECT id, firstname FROM people
+WHERE SEARCH('Chris*', 'firstname');
+```
+
+### 시나리오 10: 정규 표현식 쿼리 {#scenario-10-regular-expression-query}
+
+**사용 사례:** Lucene 스타일의 정규 표현식으로 복잡한 패턴 매칭을 수행합니다.
+
+- **구문:** `column:/regex/`
+- **의미:** 슬래시로 감싼 패턴을 사용하여 Lucene 스타일의 정규 표현식으로 매칭합니다
+- **인덱스 권장 사항:** 비토큰화 역색인만 지원합니다
+
+```sql
+SELECT id, title FROM corpus
+WHERE SEARCH('title:/data.+science/');
+```
+
+### 시나리오 11: 완전 일치 매칭(EXACT) {#scenario-11-strict-equality-match-exact}
+
+**사용 사례:** 컬럼의 원본 값 전체와 정확히 매칭합니다. 대소문자를 구분하며 토큰화하지 않습니다.
+
+- **구문:** `column:EXACT(text)`
+- **의미:** 컬럼 값 전체를 대상으로 정확히 매칭합니다. 대소문자를 구분하며 검색어 일부와는 매칭되지 않습니다
+- **인덱스 권장 사항:** EXACT를 가속화하려면 컬럼에 비토큰화 역색인도 생성합니다(`parser`를 설정하지 않음)
+
+```sql
+SELECT id
+FROM t
+WHERE SEARCH('content:EXACT(machine learning)');
+```
+
+### 시나리오 12: VARIANT 하위 컬럼 쿼리 {#scenario-12-variant-subcolumn-query}
+
+**사용 사례:** 반정형 VARIANT 필드 내의 특정 하위 경로를 검색합니다.
+
+- **구문:** `variant_col.sub.path:term`
+- **의미:** 점으로 구분된 경로를 통해 VARIANT 하위 컬럼에 접근하여 매칭합니다. 매칭 동작은 VARIANT 컬럼의 인덱스/분석기 설정을 따릅니다
+- **지원 기능:** 불리언 조합, `ANY`/`ALL`, 중첩 경로. 존재하지 않는 하위 컬럼은 매칭 결과를 반환하지 않습니다
+
+```sql
+SELECT id
+FROM test_variant_search_subcolumn
+WHERE SEARCH('properties.message:alpha');
+```
+
+## 전체 예제 {#complete-example}
+
+다음 종합 예제에서는 같은 컬럼에 토큰화 인덱스와 비토큰화 인덱스를 모두 생성하고, EXACT, ANY/ALL, 구문 및 와일드카드 쿼리를 조합하는 방법을 보여 줍니다.
+
+### 테이블과 기본 인덱스 생성 {#create-the-table-and-base-indexes}
+
+```sql
+-- Build both tokenized and non-tokenized inverted indexes
+CREATE TABLE t (
+ id INT,
+ content STRING,
+ INDEX idx_untokenized(content) USING INVERTED,
+ INDEX idx_tokenized(content) USING INVERTED PROPERTIES("parser" = "standard")
+);
+```
+
+### EXACT와 토큰화 쿼리 비교 {#comparing-exact-and-tokenized-queries}
+
+```sql
+-- Strict equality match (uses the non-tokenized index)
+SELECT id, content
+FROM t
+WHERE SEARCH('content:EXACT(machine learning)')
+ORDER BY id;
+
+-- EXACT does not match partial terms
+SELECT id, content
+FROM t
+WHERE SEARCH('content:EXACT(machine)')
+ORDER BY id;
+
+-- ANY/ALL use the tokenized index
+SELECT id, content FROM t WHERE SEARCH('content:ANY(machine learning)') ORDER BY id;
+SELECT id, content FROM t WHERE SEARCH('content:ALL(machine learning)') ORDER BY id;
+
+-- Compare EXACT and ANY
+SELECT id, content FROM t WHERE SEARCH('content:EXACT(deep learning)') ORDER BY id;
+SELECT id, content FROM t WHERE SEARCH('content:ANY(deep learning)') ORDER BY id;
+```
+
+### 조건 조합과 간소화된 형식 {#combined-conditions-and-simplified-forms}
+
+```sql
+-- Combined conditions
+SELECT id, content
+FROM t
+WHERE SEARCH('content:EXACT(machine learning) OR content:ANY(intelligence)')
+ORDER BY id;
+
+-- Simplified form using a default field and default operator
+SELECT id, tags
+FROM tag_dataset
+WHERE SEARCH('deep learning', 'tags', 'and'); -- Automatically expands to tags:ALL(deep learning)
+
+-- Use a phrase and a wildcard together
+SELECT id, content FROM t
+WHERE SEARCH('content:"deep learning" OR content:AI*')
+ORDER BY id;
+```
+
+### VARIANT 컬럼 검색 예제 {#variant-column-search-example}
+
+```sql
+-- A VARIANT column with an inverted index
+CREATE TABLE test_variant_search_subcolumn (
+ id BIGINT,
+ properties VARIANT<PROPERTIES("variant_max_subcolumns_count"="0")>,
+ INDEX idx_properties (properties) USING INVERTED PROPERTIES (
+ "parser" = "unicode",
+ "lower_case" = "true",
+ "support_phrase" = "true"
+ )
+);
+
+-- Single-term query
+SELECT id
+FROM test_variant_search_subcolumn
+WHERE SEARCH('properties.message:alpha')
+ORDER BY id;
+
+-- AND / ALL queries
+SELECT id
+FROM test_variant_search_subcolumn
+WHERE SEARCH('properties.message:alpha AND properties.message:beta')
+ORDER BY id;
+
+SELECT id
+FROM test_variant_search_subcolumn
+WHERE SEARCH('properties.message:ALL(alpha beta)')
+ORDER BY id;
+
+-- OR query across different subcolumns
+SELECT id
+FROM test_variant_search_subcolumn
+WHERE SEARCH('properties.message:hello OR properties.category:beta')
+ORDER BY id;
+```
+
+## 이스케이프 문자 {#escape-characters}
+
+DSL에서 특수 문자를 이스케이프하려면 백슬래시(`\`)를 사용합니다.
+
+| 이스케이프 | 설명 | 예제 |
+| --- | --- | --- |
+| `\ ` | 리터럴 공백(검색어 연결) | `title:First\ Value`는 "First Value"와 매칭 |
+| `\(` `\)` | 리터럴 괄호 | `title:hello\(world\)`는 "hello(world)"와 매칭 |
+| `\:` | 리터럴 콜론 | `title:key\:value`는 "key:value"와 매칭 |
+| `\\` | 리터럴 백슬래시 | `title:path\\to\\file`은 "path\to\file"과 매칭 |
+
+**예제:**
+
+```sql
+-- Search for a value containing a space as a single term
+SELECT * FROM docs WHERE SEARCH('title:First\\ Value');
+
+-- Search for a value containing parentheses
+SELECT * FROM docs WHERE SEARCH('title:hello\\(world\\)');
+
+-- Search for a value containing a colon
+SELECT * FROM docs WHERE SEARCH('title:key\\:value');
+```
+
+> **참고:** SQL 문자열에서는 백슬래시를 이중으로 이스케이프해야 합니다. SQL에서 `\\`를 사용하면 DSL에는 단일 `\`가 생성됩니다.
+
+## 현재 제한 사항 {#current-limitations}
+
+- 범위 및 목록 절(예: `field:[a TO b]` 및 `field:IN(...)`)은 여전히 일반 검색어 매칭으로 폴백합니다. 대신 일반 SQL 범위 필터나 `IN` 필터를 사용하세요.
+
+대안으로 표준 연산자나 텍스트 검색 연산자를 사용할 수 있습니다.
+
+```sql
+-- Filter by range using SQL
+SELECT * FROM t WHERE created_at >= '2024-01-01';
+```
+
+
+## 다중 필드 옵션 예제 {#multi-field-options-example}
+
+`fields`와 `type`은 Doris 4.1.0에서 사용할 수 있습니다. `standard` 모드에서 `best_fields`는 전체 쿼리를 각 필드에 복사하고 복사본을 OR로 결합합니다. `cross_fields`는 각 검색어를 여러 필드로 확장합니다. 아래에서 같은 필드와 여러 필드를 구분할 때는 `AND` 또는 `default_operator="and"`를 사용합니다. 기본 OR 연산자에서도 같은 구분이 적용된다고 가정해서는 안 됩니다. `lucene` 모드에서는 절별로 확장하므로, 이러한 표준 모드의 AND 비교는 Lucene의 동작을 설명하지 않습니다.
+
+CREATE, INSERT 및 SELECT 권한이 있는 데이터베이스에서 다음 데이터를 준비하세요.
+
+```sql
+CREATE TABLE search_multifield (
+ id INT,
+ title STRING,
+ content STRING,
+ INDEX title_idx(title) USING INVERTED PROPERTIES ("parser"="unicode", "lower_case"="true"),
+ INDEX content_idx(content) USING INVERTED PROPERTIES ("parser"="unicode", "lower_case"="true")
+)
+DUPLICATE KEY(id)
+DISTRIBUTED BY HASH(id) BUCKETS 1
+PROPERTIES ("replication_num"="1");
+INSERT INTO search_multifield VALUES
+(1, 'Alice', 'Smith'),
+(2, 'Alice Smith', 'other'),
+(3, 'Bob', 'Smith');
+```
+
+```sql
+SELECT id FROM search_multifield
+WHERE SEARCH('Alice Smith',
+ '{"fields":["title","content"],"type":"best_fields","default_operator":"and"}')
+ORDER BY id;
+```
+
+```text
+id
+2
+```
+
+```sql
+SELECT id FROM search_multifield
+WHERE SEARCH('Alice Smith',
+ '{"fields":["title","content"],"type":"cross_fields","default_operator":"and"}')
+ORDER BY id;
+```
+
+```text
+id
+1
+2
+```
+
+부정 절만 포함하는 Lucene 쿼리는 모든 문서와 매칭되는 조건을 추가하고 부정된 검색어를 제외합니다.
+
+```sql
+SELECT id FROM search_multifield
+WHERE SEARCH('NOT title:Alice', '{"mode":"lucene"}')
+ORDER BY id;
+```
+
+```text
+id
+3
+```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/inverted-index/search-operators.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/inverted-index/search-operators.md
new file mode 100644
index 00000000000..34c8e80eab4
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/inverted-index/search-operators.md
@@ -0,0 +1,187 @@
+---
+{
+ "title": "전문 검색 및 쿼리 가속 연산자",
+ "language": "ko",
+ "description": "Apache Doris 역색인에서 지원하는 전문 검색 및 쿼리 가속 연산자 참조 문서입니다. MATCH_ANY/ALL/PHRASE/REGEXP를 포함한 8개의 검색 연산자로 키워드, 구문, 접두사, 정규식 검색을 지원하며, 동등 비교, 범위, 배열 조건을 사용하는 구조화된 쿼리를 가속합니다."
+}
+---
+
+<!-- Knowledge type: Operator reference / Usage examples -->
+<!-- Applicable scenarios: Full-text search query authoring / Inverted index query acceleration -->
+
+이 문서에서는 Apache Doris 역색인에서 지원하는 쿼리 연산자를 두 가지 범주로 나누어 소개합니다.
+
+- **전문 검색 연산자**: 텍스트 필드에서 키워드, 구문, 접두사, 정규식 등의 퍼지 매칭에 사용합니다.
+- **역색인 쿼리 가속**: 구조화된 필드에서 동등 비교, 범위, 집합, 배열 등의 조건으로 정확하게 필터링하는 데 사용합니다.
+
+## 전문 검색 연산자 {#full-text-search-operators}
+
+다음 테이블은 모든 전문 검색 연산자와 대표적인 사용 사례를 보여 줍니다.
+
+| 연산자 | 대표적인 사용 사례 | 매칭 규칙 |
+|------|----------|----------|
+| `MATCH_ANY` | 키워드 "OR" 검색 | 키워드 중 하나라도 일치하면 매칭 |
+| `MATCH_ALL` | 키워드 "AND" 검색 | 모든 키워드가 일치해야 매칭 |
+| `MATCH_PHRASE` | 엄격한 구문 검색 | 검색어가 서로 인접하고 순서도 같아야 함 |
+| `MATCH_PHRASE` (slop 사용) | 오차를 허용하는 구문 검색 | 검색어 사이에 간격 허용 |
+| `MATCH_PHRASE` (엄격한 순서) | 검색어 순서가 고정된 구문 검색 | 허용된 간격 범위 내에서 검색어 순서가 고정됨 |
+| `MATCH_PHRASE_PREFIX` | 입력 제안 / 접두사 자동 완성 | 마지막 검색어를 접두사로 매칭 |
+| `MATCH_REGEXP` | 검색어 단위 정규식 매칭 | 토큰화 결과에 정규식 적용 |
+| `MATCH_PHRASE_EDGE` | 양 끝부분 퍼지 매칭 | 첫 검색어는 접미사 매칭 + 중간 검색어는 정확한 매칭 + 마지막 검색어는 접두사 매칭 |
+
+### 키워드 검색: MATCH_ANY / MATCH_ALL {#keyword-search-match_any--match_all}
+
+여러 키워드가 주어졌을 때 해당 단어가 포함된 문서를 찾는 경우에 적합합니다.
+
+- **MATCH_ANY**: 키워드 중 하나라도 포함된 행을 매칭합니다.
+
+ ```sql
+ SELECT * FROM table_name WHERE content MATCH_ANY 'keyword1 keyword2';
+ ```
+
+- **MATCH_ALL**: 모든 키워드가 동시에 포함된 행을 매칭합니다.
+
+ ```sql
+ SELECT * FROM table_name WHERE content MATCH_ALL 'keyword1 keyword2';
+ ```
+
+### 구문 검색: MATCH_PHRASE 계열 {#phrase-search-match_phrase-family}
+
+키워드가 서로 인접하거나 검색어 순서를 유지해야 하는 정확한 구문 매칭에 적합합니다.
+
+#### 엄격한 구문 매칭 {#strict-phrase-matching}
+
+검색어가 서로 인접하고 순서도 같아야 합니다. 인덱스 가속을 활성화하려면 인덱스 속성에 `"support_phrase" = "true"`를 설정합니다.
+
+```sql
+SELECT * FROM table_name WHERE content MATCH_PHRASE 'keyword1 keyword2';
+```
+
+#### Slop을 사용한 구문 매칭 {#phrase-matching-with-slop}
+
+키워드 사이에 최대 `slop`개의 단어를 허용하며, 검색어 순서는 달라도 됩니다.
+
+```sql
+-- Allow up to 3 words between keyword1 and keyword2
+SELECT * FROM table_name WHERE content MATCH_PHRASE 'keyword1 keyword2 ~3';
+```
+
+#### 엄격한 순서의 구문 매칭 {#strict-order-phrase-matching}
+
+`+`를 slop과 함께 사용하면 검색어 순서가 고정되어야 합니다.
+
+```sql
+SELECT * FROM table_name WHERE content MATCH_PHRASE 'keyword1 keyword2 ~3+';
+```
+
+### 접두사 및 끝부분 매칭 {#prefix-and-edge-matching}
+
+입력 제안이나 접두사/접미사 퍼지 매칭 등에 적합합니다.
+
+#### MATCH_PHRASE_PREFIX {#match_phrase_prefix}
+
+마지막 단어를 접두사로 매칭하는 구문 매칭입니다. 단어가 하나만 주어지면 해당 단어의 접두사 매칭으로 동작합니다.
+
+```sql
+-- The last word matches by prefix
+SELECT * FROM table_name WHERE content MATCH_PHRASE_PREFIX 'keyword1 key';
+
+-- A single word degenerates into a prefix match
+SELECT * FROM table_name WHERE content MATCH_PHRASE_PREFIX 'keyword1';
+```
+
+#### MATCH_PHRASE_EDGE {#match_phrase_edge}
+
+구문의 양 끝부분을 매칭하며, 다음 규칙을 따릅니다.
+
+- 첫 번째 단어는 **접미사**로 매칭합니다.
+- 중간 단어는 **정확한 매칭**을 사용합니다.
+- 마지막 단어는 **접두사**로 매칭합니다.
+- 검색어는 서로 인접해야 합니다.
+
+```sql
+SELECT * FROM table_name WHERE content MATCH_PHRASE_EDGE 'search engine optim';
+```
+
+### 정규식 매칭: MATCH_REGEXP {#regex-matching-match_regexp}
+
+토큰화된 검색어에 정규식 매칭을 수행합니다.
+
+```sql
+SELECT * FROM table_name WHERE content MATCH_REGEXP '^key_word.*';
+```
+
+## USING ANALYZER로 분석기 지정 {#specifying-an-analyzer-with-using-analyzer}
+
+하나의 컬럼에 서로 다른 분석기를 사용하는 역색인이 여러 개 생성되어 있으면, `USING ANALYZER` 절로 쿼리 시 사용할 분석기를 지정할 수 있습니다.
+
+### 구문 {#syntax}
+
+```sql
+SELECT * FROM table_name WHERE column MATCH 'keywords' USING ANALYZER analyzer_name;
+```
+
+### 지원하는 연산자 {#supported-operators}
+
+모든 MATCH 연산자는 `USING ANALYZER` 절을 지원합니다.
+
+- `MATCH` / `MATCH_ANY`
+- `MATCH_ALL`
+- `MATCH_PHRASE`
+- `MATCH_PHRASE_PREFIX`
+- `MATCH_PHRASE_EDGE`
+- `MATCH_REGEXP`
+
+### 내장 분석기 {#built-in-analyzers}
+
+| 이름 | 설명 |
+|------|------|
+| `none` | 토큰화 없이 정확한 매칭 수행 |
+| `standard` | 표준 토큰화 |
+| `chinese` | 중국어 토큰화 |
+
+### 사용 예시 {#usage-examples}
+
+```sql
+-- Use the standard analyzer (tokenizes the text)
+SELECT * FROM articles WHERE content MATCH 'hello world' USING ANALYZER std_analyzer;
+
+-- Use the keyword analyzer (exact match, no tokenization)
+SELECT * FROM articles WHERE content MATCH 'hello world' USING ANALYZER kw_analyzer;
+
+-- Combined with MATCH_PHRASE
+SELECT * FROM articles WHERE content MATCH_PHRASE 'hello world' USING ANALYZER std_analyzer;
+
+-- Use built-in analyzers
+SELECT * FROM articles WHERE content MATCH 'hello' USING ANALYZER standard;
+SELECT * FROM articles WHERE content MATCH 'hello' USING ANALYZER none;
+```
+
+### 참고 사항 {#notes}
+
+- 지정한 분석기의 인덱스가 아직 구축되지 않았다면 쿼리는 자동으로 인덱스를 사용하지 않는 실행 경로로 전환됩니다. 결과는 정확하지만 성능은 느려집니다.
+- 분석기를 지정하지 않으면 시스템은 사용 가능한 인덱스 중 하나를 사용합니다.
+
+## 역색인 쿼리 가속 {#inverted-index-query-acceleration}
+
+역색인은 전문 검색뿐 아니라 구조화된 필드의 정확한 필터링도 가속할 수 있습니다. 지원하는 연산자와 함수는 다음과 같습니다.
+
+| 범주 | 연산자 / 함수 |
+|------|---------------|
+| 동등 비교 및 집합 | `=`, `!=`, `IN`, `NOT IN` |
+| 범위 | `>`, `>=`, `<`, `<=`, `BETWEEN` |
+| NULL 검사 | `IS NULL`, `IS NOT NULL` |
+| 배열 | `array_contains`, `array_overlaps` |
+
+사용 예시:
+
+```sql
+-- Range query
+SELECT * FROM t WHERE price >= 100 AND price < 200;
+
+-- Set query
+SELECT * FROM t WHERE tags IN ('a', 'b', 'c');
+
+-- Array query
+SELECT * FROM t WHERE array_contains(attributes, 'color');
+```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/ngram-bloomfilter-index.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/ngram-bloomfilter-index.md
new file mode 100644
index 00000000000..0fafb34d4e2
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/ngram-bloomfilter-index.md
@@ -0,0 +1,307 @@
+---
+{
+ "title": "NGram BloomFilter 인덱스",
+ "language": "ko",
+ "description": "NGram BloomFilter 인덱스는 N-Gram 토큰화와 BloomFilter를 기반으로 합니다. 조건에 일치하지 않는 데이터 블록을 건너뛰어 문자열 컬럼의 LIKE 퍼지 쿼리를 가속하고, IO를 줄여 쿼리 성능을 크게 향상합니다."
+}
+---
+
+<!-- Knowledge type: Feature description + Operation steps -->
+<!-- Applicable scenario: Acceleration of LIKE fuzzy queries on string columns -->
+
+NGram BloomFilter 인덱스는 문자열 컬럼의 `LIKE '%pattern%'` 퍼지 쿼리를 가속하도록 설계된 **Skip Index**입니다. BloomFilter 인덱스를 기반으로 N-Gram 토큰화를 도입하여, 텍스트를 인접한 문자로 구성된 여러 단어 그룹으로 나눈 후 BloomFilter에 기록합니다. 이를 통해 퍼지 매칭을 위한 빠른 필터링을 지원합니다.
+
+**주요 이점:** 적합한 시나리오에서는 인덱스가 없는 전체 스캔에 비해 NGram BloomFilter 인덱스로 쿼리 속도를 몇 배에서 열 배까지 높일 수 있습니다([사용 예시](#usage-example)의 8배 가속 사례 참조).
+
+## 인덱스 동작 원리 {#index-principle}
+
+
+
+N-Gram 토큰화는 문장이나 텍스트를 인접한 문자로 구성된 여러 단어 그룹으로 나눕니다. 예를 들어, 문자열 `'This is a simple ngram example'`을 `N = 3`으로 토큰화하면 다음 4개의 단어가 생성됩니다.
+
+- `'This is a'`
+- `'is a simple'`
+- `'a simple ngram'`
+- `'simple ngram example'`
+
+NGram BloomFilter 인덱스와 일반 BloomFilter 인덱스의 주요 차이점은 다음과 같습니다.
+
+| 비교 항목 | BloomFilter 인덱스 | NGram BloomFilter 인덱스 |
+| ---------------- | --------------------------- | ---------------------------------------------------------- |
+| 기록 내용 | 원본 컬럼 값 | 원본 텍스트를 N-Gram으로 토큰화하여 얻은 각 단어 그룹 |
+| 가속하는 쿼리 유형 | 동등 조건 쿼리(`=`, `IN`) | `LIKE '%pattern%'` 퍼지 쿼리 |
+| 지원하는 컬럼 유형 | 여러 데이터 타입 | 문자열 컬럼만 지원 |
+
+**쿼리 가속 과정:**
+
+1. `pattern`에 N-Gram 토큰화를 적용합니다. 이 패턴은 `LIKE '%pattern%'`에 지정된 값입니다.
+2. 토큰화된 각 단어 그룹이 BloomFilter에 존재하는지 하나씩 확인합니다.
+3. 단어 그룹이 BloomFilter에 존재하지 않으면 해당 데이터 블록은 LIKE 조건을 충족할 수 없으므로 건너뛸 수 있습니다.
+4. 조건에 일치하지 않는 데이터 블록을 건너뛰어 IO를 줄이고 쿼리를 가속합니다.
+
+## 사용 사례 {#use-cases}
+
+NGram BloomFilter 인덱스는 다음 시나리오에 적합합니다.
+
+- 문자열 컬럼의 `LIKE '%pattern%'` 퍼지 쿼리 가속.
+- `LIKE` 패턴에서 연속된 문자의 수가 인덱스에 정의된 `gram_size` **이상**인 경우.
+
+:::tip 사용 제약 사항
+
+- 문자열 컬럼만 지원하며, `LIKE` 쿼리만 가속할 수 있습니다.
+- NGram BloomFilter 인덱스와 일반 BloomFilter 인덱스는 **상호 배타적**입니다. 동일한 컬럼에는 둘 중 하나만 선택할 수 있습니다.
+- 인덱스 효과를 분석하는 방법은 BloomFilter 인덱스와 동일합니다.
+
+:::
+
+## 인덱스 관리 {#manage-indexes}
+
+### 인덱스 생성 {#create-an-index}
+
+#### 테이블 생성 시 인덱스 생성 {#create-at-table-creation}
+
+테이블 생성 구문에서 `COLUMN` 정의 뒤에 인덱스 정의를 추가합니다.
+
+```sql
+INDEX `idx_column_name` (`column_name`) USING NGRAM_BF
+PROPERTIES("gram_size"="3", "bf_size"="1024")
+COMMENT 'username ngram_bf index'
+```
+
+#### 구문 설명 {#syntax-description}
+
+| 매개변수 | 필수 여부 | 설명 |
+| --------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------- |
+| `idx_column_name` (`column_name`) | 필수 | `column_name`은 인덱스를 생성할 컬럼의 이름으로, 앞에서 정의되어 있어야 합니다. `idx_column_name`은 인덱스 이름으로, 테이블 내에서 고유해야 합니다 |
+| `USING NGRAM_BF` | 필수 | 인덱스 유형을 NGram BloomFilter 인덱스로 지정합니다 |
+| `PROPERTIES` | 선택 | NGram BloomFilter 인덱스의 추가 속성을 지정합니다. 자세한 내용은 아래 표를 참조하세요 |
+| `COMMENT` | 선택 | 인덱스에 대한 설명을 지정합니다 |
+
+:::info 이름 지정 권장 사항
+인덱스 이름에는 `idx_` 접두사를 사용하는 것이 좋습니다. 예: `idx_review_body`.
+:::
+
+#### PROPERTIES 매개변수 {#properties-parameters}
+
+| 속성 | 설명 |
+| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `gram_size` | N-Gram의 N에 해당하며, 연속된 N개의 문자마다 하나의 단어 그룹을 구성하도록 지정합니다. 예를 들어, `'This is a simple ngram example'`은 4개의 단어 그룹으로 나뉩니다. 이때 설정은 `N = 3`입니다. LIKE 쿼리 문자열의 최소 길이로 설정하는 것이 좋지만, 2보다 작게 설정해서는 안 됩니다. |
+| `bf_size` | BloomFilter의 크기로, 단위는 Bits입니다. 각 데이터 블록의 인덱스 크기를 결정합니다. 값이 클수록 더 많은 저장 공간을 사용하지만 해시 충돌 가능성은 줄어듭니다. |
+
+**권장 설정:** 일반적으로 `"gram_size"="3"`과 `"bf_size"="1024"`로 시작한 후 Query Profile을 기반으로 조정하는 것이 좋습니다.
+
+### 인덱스 조회 {#view-indexes}
+
+```sql
+-- Method 1: In the INDEX section of the table schema, USING NGRAM_BF marks an NGram BloomFilter index
+SHOW CREATE TABLE table_name;
+
+-- Method 2: An IndexType of NGRAM_BF marks an NGram BloomFilter index
+SHOW INDEX FROM table_name;
+```
+
+### 인덱스 삭제 {#drop-an-index}
+
+```sql
+ALTER TABLE table_ngrambf DROP INDEX idx_ngrambf;
+```
+
+### 인덱스 수정 {#modify-an-index}
+
+기존 테이블에 NGram BloomFilter 인덱스를 추가하는 방법은 다음 두 가지입니다.
+
+```sql
+-- Method 1: Use CREATE INDEX
+CREATE INDEX idx_column_name2(column_name2) ON table_ngrambf
+USING NGRAM_BF
+PROPERTIES("gram_size"="3", "bf_size"="1024")
+COMMENT 'username ngram_bf index';
+
+-- Method 2: Use ALTER TABLE ADD INDEX
+ALTER TABLE table_ngrambf
+ADD INDEX idx_column_name2(column_name2) USING NGRAM_BF
+PROPERTIES("gram_size"="3", "bf_size"="1024")
+COMMENT 'username ngram_bf index';
+```
+
+## 인덱스 사용 {#use-the-index}
+
+### 함수 푸시다운 활성화 {#enable-function-pushdown}
+
+NGram BloomFilter 인덱스를 사용하기 전에 함수 푸시다운을 활성화합니다(`enable_function_pushdown`의 기본값은 `false`).
+
+```sql
+SET enable_function_pushdown = true;
+```
+
+### 인덱스 가속 적용 {#trigger-index-acceleration}
+
+NGram BloomFilter 인덱스는 `LIKE` 쿼리를 가속하는 데 자동으로 사용됩니다. 예를 들면 다음과 같습니다.
+
+```sql
+SELECT count() FROM table1 WHERE message LIKE '%error%';
+```
+
+### 인덱스 효과 분석 {#index-effectiveness-analysis}
+
+Query Profile의 다음 지표를 사용하여 BloomFilter 인덱스(NGram BloomFilter 포함)의 가속 효과를 분석할 수 있습니다.
+
+| 지표 | 의미 |
+| ------------------------------------------ | ------------------------------------------------------------------------------------------------ |
+| `RowsBloomFilterFiltered` | BloomFilter 인덱스가 걸러낸 행 수입니다. 다른 Rows 지표와 비교하여 필터링 효과를 분석할 수 있습니다 |
+| `BlockConditionsFilteredBloomFilterTime` | BloomFilter 인덱스가 소요한 시간 |
+
+## 사용 예시 {#usage-example}
+
+다음은 Amazon 상품 사용자 리뷰 데이터 세트인 `amazon_reviews`를 예로 들어 NGram BloomFilter 인덱스의 사용 방법과 가속 효과를 보여줍니다.
+
+### 1단계: 테이블 생성 {#step-1-create-the-table}
+
+```sql
+CREATE TABLE `amazon_reviews` (
+ `review_date` int(11) NULL,
+ `marketplace` varchar(20) NULL,
+ `customer_id` bigint(20) NULL,
+ `review_id` varchar(40) NULL,
+ `product_id` varchar(10) NULL,
+ `product_parent` bigint(20) NULL,
+ `product_title` varchar(500) NULL,
+ `product_category` varchar(50) NULL,
+ `star_rating` smallint(6) NULL,
+ `helpful_votes` int(11) NULL,
+ `total_votes` int(11) NULL,
+ `vine` boolean NULL,
+ `verified_purchase` boolean NULL,
+ `review_headline` varchar(500) NULL,
+ `review_body` string NULL
+) ENGINE=OLAP
+DUPLICATE KEY(`review_date`)
+COMMENT 'OLAP'
+DISTRIBUTED BY HASH(`review_date`) BUCKETS 16
+PROPERTIES (
+ "replication_allocation" = "tag.location.default: 1",
+ "compression" = "ZSTD"
+);
+```
+
+### 2단계: 데이터 적재 {#step-2-load-data}
+
+**1. 데이터 세트 다운로드**
+
+`wget`이나 다른 도구를 사용하여 다음 URL에서 데이터 세트를 다운로드합니다.
+
+```
+https://datasets-documentation.s3.eu-west-3.amazonaws.com/amazon_reviews/amazon_reviews_2010.snappy.parquet
+https://datasets-documentation.s3.eu-west-3.amazonaws.com/amazon_reviews/amazon_reviews_2011.snappy.parquet
+https://datasets-documentation.s3.eu-west-3.amazonaws.com/amazon_reviews/amazon_reviews_2012.snappy.parquet
+https://datasets-documentation.s3.eu-west-3.amazonaws.com/amazon_reviews/amazon_reviews_2013.snappy.parquet
+https://datasets-documentation.s3.eu-west-3.amazonaws.com/amazon_reviews/amazon_reviews_2014.snappy.parquet
+https://datasets-documentation.s3.eu-west-3.amazonaws.com/amazon_reviews/amazon_reviews_2015.snappy.parquet
+```
+
+**2. Stream Load를 통한 데이터 적재**
+
+```bash
+curl --location-trusted -u root: -T amazon_reviews_2010.snappy.parquet -H "format:parquet" http://127.0.0.1:8030/api/${DB}/amazon_reviews/_stream_load
+curl --location-trusted -u root: -T amazon_reviews_2011.snappy.parquet -H "format:parquet" http://127.0.0.1:8030/api/${DB}/amazon_reviews/_stream_load
+curl --location-trusted -u root: -T amazon_reviews_2012.snappy.parquet -H "format:parquet" http://127.0.0.1:8030/api/${DB}/amazon_reviews/_stream_load
+curl --location-trusted -u root: -T amazon_reviews_2013.snappy.parquet -H "format:parquet" http://127.0.0.1:8030/api/${DB}/amazon_reviews/_stream_load
+curl --location-trusted -u root: -T amazon_reviews_2014.snappy.parquet -H "format:parquet" http://127.0.0.1:8030/api/${DB}/amazon_reviews/_stream_load
+curl --location-trusted -u root: -T amazon_reviews_2015.snappy.parquet -H "format:parquet" http://127.0.0.1:8030/api/${DB}/amazon_reviews/_stream_load
+```
+
+:::info 파일 크기 제한
+위 파일은 크기가 10 GB를 초과할 수 있습니다. `streaming_load_max_mb` 설정을 `be.conf`에서 조정하여 Stream Load 파일 업로드 크기 제한을 초과하지 않도록 하세요. 다음 명령은 변경 사항을 동적으로 적용합니다(모든 BE에서 실행하세요).
+
+```bash
+curl -X POST http://{be_ip}:{be_http_port}/api/update_config?streaming_load_max_mb=32768
+```
+
+:::
+
+**3. 데이터 적재 확인**
+
+SQL로 `count()`를 실행하여 데이터가 정상적으로 적재되었는지 확인합니다.
+
+```sql
+mysql> SELECT COUNT() FROM amazon_reviews;
++-----------+
+| count(*) |
++-----------+
+| 135589433 |
++-----------+
+```
+
+### 3단계: 성능 비교 {#step-3-performance-comparison}
+
+**시나리오 1: 인덱스 없이 쿼리 실행(7.60초 소요)**
+
+```sql
+SELECT
+ product_id,
+ any_value(product_title),
+ AVG(star_rating) AS rating,
+ COUNT() AS count
+FROM
+ amazon_reviews
+WHERE
+ review_body LIKE '%is super awesome%'
+GROUP BY
+ product_id
+ORDER BY
+ count DESC,
+ rating DESC,
+ product_id
+LIMIT 5;
+```
+
+쿼리 결과:
+
+```
++------------+------------------------------------------+--------------------+-------+
+| product_id | any_value(product_title) | rating | count |
++------------+------------------------------------------+--------------------+-------+
+| B00992CF6W | Minecraft | 4.8235294117647056 | 17 |
+| B009UX2YAC | Subway Surfers | 4.7777777777777777 | 9 |
+| B00DJFIMW6 | Minion Rush: Despicable Me Official Game | 4.875 | 8 |
+| B0086700CM | Temple Run | 5 | 6 |
+| B00KWVZ750 | Angry Birds Epic RPG | 5 | 6 |
++------------+------------------------------------------+--------------------+-------+
+5 rows in set (7.60 sec)
+```
+
+**시나리오 2: NGram BloomFilter 인덱스 추가 후 쿼리 실행(0.93초 소요)**
+
+인덱스를 추가합니다.
+
+```sql
+ALTER TABLE amazon_reviews
+ADD INDEX review_body_ngram_idx(review_body) USING NGRAM_BF
+PROPERTIES("gram_size"="10", "bf_size"="10240");
+```
+
+동일한 쿼리를 다시 실행합니다.
+
+```
++------------+------------------------------------------+--------------------+-------+
+| product_id | any_value(product_title) | rating | count |
++------------+------------------------------------------+--------------------+-------+
+| B00992CF6W | Minecraft | 4.8235294117647056 | 17 |
+| B009UX2YAC | Subway Surfers | 4.7777777777777777 | 9 |
+| B00DJFIMW6 | Minion Rush: Despicable Me Official Game | 4.875 | 8 |
+| B0086700CM | Temple Run | 5 | 6 |
+| B00KWVZ750 | Angry Birds Epic RPG | 5 | 6 |
++------------+------------------------------------------+--------------------+-------+
+5 rows in set (0.93 sec)
+```
+
+**성능 비교:**
+
+| 시나리오 | 소요 시간 | 성능 향상 |
+| ------------------------------------- | ------ | ---------------- |
+| 인덱스 없음 | 7.60 s | 기준 |
+| NGram BloomFilter 인덱스 추가 | 0.93 s | **약 8배** |
+
+## 이스케이프된 LIKE 패턴의 인덱스 제한 사항 {#index-limitations-for-escaped-like-patterns}
+
+4.1.5부터 사용자 지정 `ESCAPE`를 사용하거나 패턴에 백슬래시가 포함된 LIKE 쿼리는 잘못된 필터링을 방지하기 위해 NGRAM Bloom Filter를 프루닝에 사용하지 않습니다. 이러한 쿼리는 일반 스캔을 통해 계속 지원됩니다. 이스케이프가 없는 LIKE 패턴은 기존 조건을 충족하면 계속 인덱스를 사용할 수 있습니다.
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/prefix-index.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/prefix-index.md
new file mode 100644
index 00000000000..a5eae084b31
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/prefix-index.md
@@ -0,0 +1,151 @@
+---
+{
+ "title": "Prefix Index와 Sort Key",
+ "language": "ko",
+ "description": "Prefix Index는 Apache Doris에 내장된 희소 인덱스입니다. Sort Key의 처음 36바이트를 기준으로 데이터 블록을 찾아, 수동으로 생성하지 않아도 동등 조건 쿼리와 범위 쿼리를 가속합니다.",
+ "keywords": [
+ "Prefix Index",
+ "Sort Key",
+ "Apache Doris",
+ "sparse index",
+ "query acceleration",
+ "Key column design"
+ ]
+}
+---
+
+<!-- Knowledge type: Feature introduction + Design guide -->
+<!-- Applicable scenarios: Table schema design / Query performance tuning -->
+
+Prefix Index는 Apache Doris에 **내장되어 자동으로 유지 관리되는** 희소 인덱스입니다. Sort Key의 처음 36바이트를 기준으로 데이터 블록을 빠르게 찾으며, 수동으로 생성할 필요가 없습니다. 테이블 스키마를 설계할 때 적절한 Sort Key를 선택하면 `WHERE` 조건의 동등 조건 쿼리와 범위 쿼리 속도를 크게 높일 수 있습니다.
+
+## 작동 방식 {#how-it-works}
+
+
+
+### Sort Key {#sort-key}
+
+Apache Doris는 SSTable(Sorted String Table)과 유사한 정렬 구조로 데이터를 저장하며, 지정된 하나 이상의 컬럼을 기준으로 데이터를 정렬하여 저장할 수 있습니다. 이러한 정렬 기준 컬럼을 **Sort Key**라고 합니다.
+
+데이터 모델에 따라 Sort Key를 결정하는 기준이 다릅니다.
+
+| 데이터 모델 | Sort Key의 출처 |
+| --- | --- |
+| Aggregate | `CREATE TABLE` 문의 Aggregate Key |
+| Unique | `CREATE TABLE` 문의 Unique Key |
+| Duplicate | `CREATE TABLE` 문의 Duplicate Key |
+
+쿼리의 `WHERE` 조건이 정렬 컬럼과 일치하면, Doris는 Sort Key를 사용하여 조건에 맞는 데이터 범위로 빠르게 이동할 수 있습니다. 이를 통해 전체 테이블 스캔을 피하고 탐색 복잡도를 줄여 쿼리 속도를 높입니다.
+
+### Prefix Index {#prefix-index}
+
+Apache Doris는 Sort Key를 기반으로 Prefix Index도 제공합니다.
+
+1. 테이블의 여러 행이 모여 하나의 논리적 데이터 블록(Data Block)을 구성합니다.
+2. 각 데이터 블록은 Prefix Index 테이블에 항목 하나만 저장합니다. 이 항목은 **블록의 첫 번째 행에 있는 정렬 컬럼들을 이어 붙여 만든 접두사**이며, 길이는 최대 36바이트입니다.
+3. Prefix Index는 크기가 작아 **전체를 메모리에 캐시**할 수 있습니다. 대상 데이터 블록의 시작 행 번호를 빠르게 찾아 쿼리 효율을 크게 높입니다.
+
+### 36바이트 잘림 규칙 {#36-byte-truncation-rule}
+
+Prefix Index는 행의 정렬 컬럼에서 처음 36바이트를 인덱스 내용으로 사용하지만, `VARCHAR` 컬럼을 만나면 **즉시 잘라냅니다**.
+
+- 정렬 컬럼들을 이어 붙이는 과정에서 `VARCHAR` 컬럼에 도달하면, 36바이트를 채웠는지와 관계없이 해당 컬럼의 끝에서 잘라냅니다.
+- 첫 번째 컬럼 자체가 `VARCHAR`이면, 길이가 36바이트 미만이더라도 해당 컬럼의 끝에서 잘라내며 이후 컬럼은 Prefix Index에 추가하지 않습니다.
+
+## 적용 시나리오 {#applicable-scenarios}
+
+Prefix Index는 주로 다음과 같은 쿼리에 사용됩니다.
+
+- **동등 조건 쿼리**: `col = value`, `col IN (...)`
+- **범위 쿼리**: `col > value`, `BETWEEN ... AND ...` 등
+
+`WHERE` 조건이 Sort Key의 **접두사**, 즉 첫 번째 컬럼부터 연속된 맨 왼쪽의 여러 컬럼과 일치하면 Prefix Index로 쿼리를 가속할 수 있습니다.
+
+## 테이블 스키마 설계 권장 사항 {#table-schema-design-recommendations}
+
+테이블에는 Sort Key 정의가 하나뿐이므로, **테이블 하나에는 Prefix Index 집합도 하나만 있을 수 있습니다**. 테이블을 생성할 때 선택한 Sort Key가 Prefix Index의 가속 효과를 직접 결정합니다. 다음 지침을 참고하세요.
+
+1. **`WHERE` 필터 조건에 가장 자주 등장하는 컬럼을 Key 컬럼으로 우선 선택하세요.**
+2. **쿼리에서 더 자주 사용하는 컬럼을 앞에 배치하세요.** Prefix Index는 맨 왼쪽 컬럼부터 연속해서 일치하는 조건에만 효과가 있습니다.
+3. **Sort Key의 앞부분에 `VARCHAR` 컬럼을 배치할 때는 주의하세요.** 잘림 규칙이 적용되면 이후 컬럼이 Prefix Index에 포함되지 않습니다.
+
+:::tip
+Sort Key를 조정해도 자주 사용하는 쿼리 조건이 Prefix Index를 활용할 수 없다면, 아래의 [Prefix Index를 활용할 수 없을 때의 대안](#alternatives-when-the-prefix-index-cannot-be-hit)을 참고하세요.
+:::
+
+## 사용 예제 {#usage-examples}
+
+### 예제 1: 잘림이 없는 Prefix Index {#example-1-prefix-index-without-truncation}
+
+다음 Sort Key의 Prefix Index는 `user_id (8 Bytes) + age (4 Bytes) + message (first 20 Bytes)`이며, 총 32바이트입니다.
+
+| 컬럼명 | 타입 |
+| -------------- | ------------ |
+| user_id | BIGINT |
+| age | INT |
+| message | VARCHAR(100) |
+| max_dwell_time | DATETIME |
+| min_dwell_time | DATETIME |
+
+### 예제 2: 첫 번째 컬럼이 VARCHAR여서 잘림이 발생하는 경우 {#example-2-first-column-is-varchar-and-triggers-truncation}
+
+다음 Sort Key의 Prefix Index에는 `user_name (20 Bytes)`만 포함됩니다. 전체 길이가 36바이트에 도달하지 않았더라도 첫 번째 컬럼이 `VARCHAR`이므로 즉시 잘라내며, 이후 컬럼은 Prefix Index에 추가하지 않습니다.
+
+| 컬럼명 | 타입 |
+| -------------- | ------------ |
+| user_name | VARCHAR(20) |
+| age | INT |
+| message | VARCHAR(100) |
+| max_dwell_time | DATETIME |
+| min_dwell_time | DATETIME |
+
+### 예제 3: Prefix Index를 활용하는 쿼리와 활용하지 못하는 쿼리 {#example-3-query-hitting-vs-missing-the-prefix-index}
+
+예제 1의 테이블 스키마를 기준으로 살펴보겠습니다.
+
+- **Prefix Index를 활용하는 경우**(조건이 맨 왼쪽의 정렬 컬럼 두 개를 포함하므로 효율이 높습니다):
+
+ ```sql
+ SELECT * FROM table WHERE user_id = 1829239 AND age = 20;
+ ```
+
+- **Prefix Index를 활용하지 못하는 경우**(조건에서 `user_id`를 건너뛰므로 접두사를 사용하여 데이터 위치를 찾을 수 없습니다):
+
+ ```sql
+ SELECT * FROM table WHERE age = 20;
+ ```
+
+따라서 테이블을 생성할 때 컬럼 순서를 올바르게 선택하면 쿼리 효율을 크게 높일 수 있습니다.
+
+## 인덱스 효과 확인 {#verifying-index-effectiveness}
+
+Prefix Index는 **쿼리를 가속할 수 있을 때 자동으로 적용되며, 별도의 구문이 필요하지 않습니다**. [쿼리 프로파일](../../query-acceleration/query-profile.md)의 다음 지표로 가속 효과를 확인할 수 있습니다.
+
+| 지표 | 의미 |
+| --- | --- |
+| `RowsKeyRangeFiltered` | Prefix Index로 걸러낸 행 수입니다. 다른 `Rows*` 지표와 비교하여 인덱스의 필터링 효과를 평가할 수 있습니다. |
+
+## Prefix Index를 활용할 수 없을 때의 대안 {#alternatives-when-the-prefix-index-cannot-be-hit}
+
+자주 사용하는 쿼리 조건이 Prefix Index를 활용할 수 없는 경우, 예를 들어 자주 사용하는 필터 컬럼이 Sort Key의 접두사에 해당하지 않는 경우에는 다음 두 가지 방법을 고려하세요.
+
+1. **[역색인](./inverted-index/overview.md) 생성**: 테이블에는 여러 역색인을 생성할 수 있으므로, 서로 다른 쿼리 조건에서 사용하는 컬럼들을 유연하게 지원할 수 있습니다.
+2. **단일 테이블 구체화된 뷰(Duplicate 모델) 사용**: 컬럼 순서가 다르고 강력한 일관성을 보장하는 단일 테이블 [동기식 구체화된 뷰](../../query-acceleration/materialized-view/sync-materialized-view.md)를 생성하면, 간접적으로 여러 Prefix Index 집합을 구성할 수 있습니다.
+
+## 자주 묻는 질문 {#faq}
+
+**Q1: Prefix Index를 수동으로 생성해야 하나요?**
+
+아니요. 테이블을 생성하면 Doris가 자동으로 Sort Key의 처음 36바이트를 Prefix Index로 사용합니다. 이를 위한 전용 DDL 구문은 없습니다.
+
+**Q2: 하나의 테이블에 여러 Prefix Index 집합을 구성할 수 있나요?**
+
+아니요. Sort Key는 하나뿐이므로 테이블에는 Prefix Index 집합도 하나만 있을 수 있습니다. 여러 집합이 필요하다면 역색인이나 구체화된 뷰를 사용하세요.
+
+**Q3: Prefix Index가 예상보다 훨씬 짧은 이유는 무엇인가요?**
+
+가장 흔한 이유는 Sort Key의 앞부분에 `VARCHAR` 컬럼이 있어 잘림 규칙이 적용되기 때문입니다. Sort Key의 앞부분에는 고정 길이 타입(예: `BIGINT`, `INT`, `DATETIME`, `TIMESTAMP_NS`)을 배치하세요.
+
+**Q4: Prefix Index로 `LIKE` 쿼리나 텍스트 검색을 가속할 수 있나요?**
+
+아니요. `LIKE` 유사 일치 검색에는 [NGram BloomFilter Index](./ngram-bloomfilter-index.md)를, 전문 검색에는 [역색인](./inverted-index/overview.md)을 사용하세요.
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/vector-index/behind-index.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/vector-index/behind-index.md
new file mode 100644
index 00000000000..b4418e1cb96
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/vector-index/behind-index.md
@@ -0,0 +1,398 @@
+---
+{
+ "title": "성능 테스트를 뒷받침하는 최적화",
+ "language": "ko",
+ "description": "Apache Doris 4.0 벡터 인덱싱의 핵심 최적화인 다단계 샤딩, 병렬 인덱스 구축, Index Only Scan, 가상 컬럼, 전역 TopN 지연 구체화를 자세히 살펴봅니다.",
+ "keywords": [
+ "Doris 벡터 인덱스 최적화",
+ "ANN 인덱스 성능",
+ "HNSW 매개변수",
+ "Index Only Scan",
+ "가상 컬럼 CSE",
+ "Prepare Statement 벡터 검색",
+ "Scan 병렬성",
+ "전역 TopN 지연 구체화",
+ "벡터 데이터베이스 성능"
+ ]
+}
+---
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<!-- Knowledge type: Architecture selection decision / Performance optimization principles -->
+<!-- Applicable scenarios: Performance tuning / Selection evaluation / Architecture understanding -->
+
+## 개요 {#overview}
+
+Apache Doris는 2.x의 역색인 기반 텍스트 검색에서 3.x의 스토리지와 컴퓨팅 분리를 거쳐, 이제 4.x의 벡터 인덱싱 기능으로 발전하며 본격적으로 AI 데이터 분석 시대에 진입했습니다. 이 글은 다음 독자를 대상으로 합니다.
+
+- Doris 4.x 벡터 인덱싱이 업계 최고 수준의 성능을 달성하는 이유를 이해하려는 아키텍트와 개발자.
+- 벡터 데이터베이스를 평가하면서 Doris와 전용 벡터 데이터베이스 간 성능 차이가 어디에서 비롯되는지 이해해야 하는 기술 의사결정자.
+- Doris에서 ANN 검색을 튜닝하려는 운영 및 성능 엔지니어.
+
+이 글은 벡터 검색의 두 가지 주요 단계를 중심으로 구성되어 있습니다.
+
+| 단계 | 핵심 목표 | 주요 최적화 |
+|-------|-----------|--------------------|
+| 인덱싱 단계 | 품질을 유지하면서 인덱스 구축 속도 향상 | 다단계 샤딩, 이중 병렬화, SIMD 거리 계산 |
+| 쿼리 단계 | 높은 동시성에서도 P99 지연 시간 제어 | Prepare Statement, Index Only Scan, 가상 컬럼, Scan 병렬화, 전역 TopN 지연 구체화 |
+
+---
+
+## 인덱싱 단계 {#indexing-phase}
+
+<!-- Knowledge type: Performance optimization principles -->
+
+인덱싱 단계의 성능은 인덱스 하이퍼파라미터와 밀접한 관계가 있습니다. 품질이 높을수록 구축 속도는 느려집니다. Doris는 데이터 적재 경로를 최적화하여 높은 인덱스 품질을 유지하면서도 적재 처리량을 크게 향상합니다.
+
+768차원, 10M행 규모에서 Doris의 적재 성능은 업계 최고 수준에 도달합니다.
+
+
+
+### 다단계 샤딩 {#multi-level-sharding}
+
+Doris 내부 테이블은 기본적으로 분산 구조입니다. 사용자는 쿼리하거나 데이터를 적재할 때 하나의 논리 테이블(Table)만 인식합니다. 반면 Doris 커널은 테이블 정의에 따라 물리 샤드를 자동으로 생성하고, 파티션 키와 버킷 키를 기준으로 BE의 해당 tablet으로 데이터를 라우팅합니다.
+
+각 계층 간의 관계는 다음과 같습니다.
+
+| 계층 | 역할 |
+|-------|------|
+| Table | 사용자가 인식하는 논리 테이블 |
+| Tablet | 수량 요건을 충족하는 물리 샤드 |
+| Rowset | tablet에서 각 적재 트랜잭션이 생성하는 버전 관리 단위 |
+| Segment | rowset 아래에서 실제 데이터를 담는 파일. **ANN 인덱스는 segment 단위로 동작합니다** |
+
+
+
+HNSW와 같은 벡터 인덱스는 몇 가지 핵심 하이퍼파라미터에 의존합니다. 이 매개변수들은 인덱스 품질과 쿼리 성능을 직접 결정하며, 일반적으로 일정한 데이터 규모에서만 이상적인 결과를 얻을 수 있습니다.
+
+**Doris의 다단계 샤딩은 "인덱스 매개변수"와 "테이블의 전체 데이터 규모"를 분리합니다**. 사용자는 전체 데이터 양이 늘어났다는 이유로 인덱스를 다시 구축할 필요가 없습니다. 각 적재 배치의 크기와 그에 맞는 매개변수 설정에만 집중하면 됩니다.
+
+측정 결과를 바탕으로, 배치 크기별 HNSW 인덱스의 경험적 매개변수는 다음과 같습니다.
+
+| batch_size | max_degree | ef_construction | ef_search | recall@100 |
+|------------|------------|-----------------|-----------|------------|
+| 250000 | 100 | 200 | 50 | 89% |
+| 250000 | 100 | 200 | 100 | 93% |
+| 250000 | 100 | 200 | 150 | 95% |
+| 250000 | 100 | 200 | 200 | 98% |
+| 500000 | 120 | 240 | 50 | 91% |
+| 500000 | 120 | 240 | 100 | 94% |
+| 500000 | 120 | 240 | 150 | 96% |
+| 500000 | 120 | 240 | 200 | 99% |
+| 1000000 | 150 | 300 | 50 | 90% |
+| 1000000 | 150 | 300 | 100 | 93% |
+| 1000000 | 150 | 300 | 150 | 96% |
+| 1000000 | 150 | 300 | 200 | 98% |
+
+즉, 사용자는 "각 적재 배치의 데이터 양"에만 집중하고 그에 맞는 인덱스 매개변수를 선택하면, 인덱스 품질을 보장하면서 안정적인 쿼리 성능을 얻을 수 있습니다.
+
+### 고성능 인덱스 구축 {#high-performance-index-construction}
+
+#### 병렬 처리를 통한 고품질 인덱스 구축 {#parallel-high-quality-index-construction}
+
+Doris는 "이중 병렬화"로 인덱스 구축 속도를 높입니다.
+
+1. **클러스터 수준 병렬화**: 여러 BE 노드에서 병렬로 구축합니다.
+2. **노드 내부 병렬화**: 각 BE 내에서 동일 배치의 데이터를 그룹으로 묶고 멀티스레드로 거리를 계산하여 인덱스 자료구조의 구축 속도를 높입니다.
+
+Doris는 속도를 높이는 동시에 **메모리 내 배치 처리**로 인덱스 품질도 개선합니다. 전체 벡터 수가 일정하더라도 배치가 너무 작아 인덱스에 데이터를 지나치게 자주 추가하면, 그래프 구조가 희소해지고 재현율이 떨어지는 경향이 있습니다.
+
+예를 들어, 768D / 10M 벡터 데이터의 경우:
+
+- 10개 배치로 인덱스를 구축하면 약 99%의 재현율을 얻습니다.
+- 100개 배치로 인덱스를 구축하면 재현율이 약 95%로 떨어질 수 있습니다.
+
+메모리 내 배치 처리를 통해 Doris는 동일한 하이퍼파라미터에서 메모리 사용량과 그래프 품질의 균형을 더 잘 맞추고, 지나치게 잘게 나눈 배치로 인한 품질 저하를 방지할 수 있습니다.
+
+#### SIMD 거리 계산 {#simd-distance-computation}
+
+ANN 인덱스 구축에서 가장 큰 비용은 대규모 거리 계산이며, 이는 전형적인 CPU 집약적 작업입니다. Doris는 이 계산을 BE 노드에 집중시킵니다. 관련 구현은 C++로 작성되었으며, Faiss의 자동 및 수동 벡터화 최적화를 최대한 활용합니다.
+
+L2 거리를 예로 들면, Faiss는 컴파일러 지시문 매크로를 통해 자동 벡터화를 활성화합니다.
+
+```cpp
+FAISS_PRAGMA_IMPRECISE_FUNCTION_BEGIN
+float fvec_L2sqr(const float* x, const float* y, size_t d) {
+ size_t i;
+ float res = 0;
+ FAISS_PRAGMA_IMPRECISE_LOOP
+ for (i = 0; i < d; i++) {
+ const float tmp = x[i] - y[i];
+ res += tmp * tmp;
+ }
+ return res;
+}
+FAISS_PRAGMA_IMPRECISE_FUNCTION_END
+```
+
+`FAISS_PRAGMA_IMPRECISE_*` 매크로는 컴파일러가 자동 벡터화를 수행하도록 유도합니다.
+
+```cpp
+#define FAISS_PRAGMA_IMPRECISE_LOOP \
+ _Pragma("clang loop vectorize(enable) interleave(enable)")
+```
+
+동시에 Faiss는 `_mm*` / `_mm256*` / `_mm512*` 명령어를 `#ifdef SSE3/AVX2/AVX512F` 조건부 블록 안에서 사용하여 명시적 벡터화를 수행합니다. 여기에 L2와 내적의 원소별 연산을 각각 구현하는 `ElementOpL2 / ElementOpIP` 템플릿과 차원별 특수화인 `fvec_op_ny_D{1,2,4,8,12}`를 결합하여 다음을 구현합니다.
+
+- 여러 샘플(예: 8개 또는 16개)을 **배치 처리**하고, 레지스터 내 행렬 전치(예: `transpose_8x2/16x4/...`)를 통해 메모리 접근 지역성을 높입니다.
+- 곱셈과 덧셈을 융합하는 **FMA 명령어**(예: `_mm512_fmadd_ps`)로 명령어 수를 줄입니다.
+- **수평 합산**으로 스칼라 결과를 빠르게 산출합니다.
+- **마스킹된 분기**로 4/8/16 단위에 맞지 않는 나머지 원소를 처리합니다.
+
+이러한 최적화는 거리 계산의 명령어 및 메모리 접근 오버헤드를 효과적으로 줄여 인덱스 구축 처리량을 크게 향상합니다.
+
+---
+
+## 쿼리 단계 {#query-phase}
+
+<!-- Knowledge type: Performance optimization principles -->
+
+검색 시나리오는 지연 시간에 매우 민감합니다. 수천만 행의 데이터와 높은 쿼리 동시성을 처리할 때는 일반적으로 P99 지연 시간을 500 ms 미만으로 유지해야 합니다. 따라서 Doris 옵티마이저, 실행 엔진, 인덱스 구현에 더 높은 요구사항이 적용됩니다.
+
+기본 설정으로 수행한 테스트에서 Doris의 쿼리 성능은 업계의 주요 전용 벡터 데이터베이스 수준에 도달했습니다. 아래 그림은 Performance768D10M 데이터셋에서 Doris와 벡터 검색 기능을 갖춘 다른 데이터베이스를 비교한 것입니다. 다른 데이터베이스의 데이터는 Zilliz의 오픈 소스 [VectorDBBench](https://github.com/zilliztech/VectorDBBench) 프레임워크에서 가져왔습니다.
+
+
+
+> 참고: 이 그림에는 일부 데이터베이스의 기본 설정 테스트 결과만 포함되어 있습니다. OpenSearch와 Elastic Cloud는 인덱스 파일 수를 최적화하여 쿼리 성능을 더 높일 수 있습니다.
+
+쿼리 단계의 최적화는 **중복 계산과 불필요한 디스크 IO를 제거하고 동시 처리 성능을 극대화한다**는 핵심 목표를 중심으로 이루어집니다. 구체적인 기법은 다음과 같습니다.
+
+### Prepare Statement {#prepare-statement}
+
+기존 실행 경로에서 Doris는 모든 SQL 문에 대해 전체 최적화 과정(구문 분석, 의미 분석, RBO, CBO)을 수행합니다. 이는 일반적인 OLAP 시나리오에서는 필수적이지만, 검색처럼 단순하고 반복적인 쿼리 패턴에서는 상당한 추가 오버헤드를 발생시킵니다.
+
+Doris 4.0은 Prepare Statement를 확장하여 포인트 쿼리뿐 아니라 벡터 검색을 포함한 모든 SQL 유형을 지원합니다. 핵심 아이디어는 다음과 같습니다.
+
+1. **컴파일과 실행 분리**
+ - Prepare 단계에서 구문 분석, 의미 분석, 최적화를 한 번 수행하고 재사용 가능한 Logical Plan을 생성합니다.
+ - Execute 단계에서는 실제 매개변수만 바인딩하고 생성된 계획을 바로 실행하므로 옵티마이저를 완전히 건너뜁니다.
+2. **Plan Cache**
+ - 계획의 재사용 가능 여부는 SQL 지문(정규화된 SQL + 스키마 버전)으로 결정합니다.
+ - 매개변수 값이 달라도 구조가 같으면 계획을 바로 재사용할 수 있어 반복 최적화를 피할 수 있습니다.
+3. **스키마 버전 검증**
+ - 실행 시 테이블 스키마 버전을 확인하여 계획의 정확성을 보장합니다.
+ - 스키마가 변경되지 않았으면 계획을 바로 재사용합니다. 변경되었으면 계획을 자동으로 무효화하고 다시 준비합니다.
+4. **옵티마이저를 건너뛰어 속도 대폭 향상**
+ - Execute는 더 이상 RBO/CBO를 실행하지 않으므로 옵티마이저에 소요되는 시간이 거의 완전히 제거됩니다.
+ - 벡터 검색처럼 템플릿화된 쿼리에서는 Prepare가 종단 간 지연 시간을 크게 줄일 수 있습니다.
+
+### Index Only Scan {#index-only-scan}
+
+Doris의 벡터 인덱스는 부속 인덱스로 구현됩니다. 부속 인덱스는 관리하기 쉽고 비동기 구축도 용이하지만, **중복 계산과 불필요한 IO를 어떻게 피할 것인가**라는 성능 과제도 수반합니다.
+
+ANN 인덱스는 일치하는 행 ID뿐 아니라 벡터 간 거리도 반환할 수 있습니다. 실행 엔진은 이 추가 정보를 효율적으로 활용하기 위해 Scan 연산자의 거리 관련 표현식을 "조기에 단락 평가"합니다. Doris는 "가상 컬럼" 메커니즘으로 이 단락 평가를 자동으로 수행하고, Ann Index Only Scan을 사용하여 거리 계산과 관련된 읽기 IO를 완전히 제거합니다.
+
+**기본 처리 흐름**: Scan이 조건자를 인덱스로 푸시다운하면 인덱스가 행 ID를 반환합니다. Scan은 행 ID로 데이터 페이지를 읽은 다음 표현식을 계산하고 N행의 결과를 상위 연산자에 반환합니다.
+
+
+
+**Index Only Scan 적용 후**:
+
+
+
+예를 들면 다음과 같습니다.
+
+```sql
+SELECT l2_distance_approximate(embedding, [...]) AS dist
+FROM tbl
+ORDER BY dist
+LIMIT 100;
+```
+
+이 실행 과정에서는 더 이상 데이터 파일 IO가 발생하지 않습니다.
+
+#### Index Only Scan이 지원하는 쿼리 유형 {#query-types-supported-by-index-only-scan}
+
+Ann TopN Search 외에도 인덱스 가속을 지원하는 Range Search와 Compound Search에 유사한 최적화가 적용됩니다. Range Search는 TopN보다 복잡합니다. 비교 방식에 따라 인덱스가 dist를 반환할 수 있는지가 달라집니다. 아래 표는 Ann Index Only Scan과 관련된 쿼리 유형을 정리한 것입니다.
+
+| 번호 | 패턴 | IndexScan 사용 여부 | 핵심 이유 |
+|-----|---------|----------------|------------|
+| Sql1 | Range + proj, `dist <= 10` | True | 인덱스가 dist를 반환할 수 있으며, cse용 가상 컬럼이 proj에서 dist를 다시 계산하지 않도록 함 |
+| Sql2 | Range + no-proj, `dist <= 10` | True | 인덱스가 dist를 반환할 수 있음 |
+| Sql3 | Range + proj, `dist > 10` | False | 인덱스가 dist를 반환할 수 없고 proj에 dist가 필요하므로 embedding을 다시 읽어야 함 |
+| Sql4 | Range + proj, `dist > 10`, proj에 dist가 필요하지 않음 | True | proj에 dist가 필요하지 않으므로 embedding을 다시 읽을 필요가 없음 |
+| Sql5 | TopN | True | 인덱스가 dist를 반환하고 가상 슬롯이 proj로 전달됨 |
+| Sql6 | TopN + IndexFilter | True | comment 컬럼은 이미 역색인 스캔으로 최적화되었으며 embedding을 읽지 않음 |
+| Sql7 | TopN + Range | True | Sql1과 Sql5의 조합 |
+| Sql8 | TopN + Range + IndexFilter | True | Sql6과 Sql7의 조합 |
+| Sql9 | TopN + Range + CommonFilter (`dist < 10`) | False | 잔여 일반 필터로 인해 embedding이 여전히 구체화됨(ROI가 낮아 현재 최적화하지 않음) |
+| Sql10 | Sql9의 변형 (`dist > 10`) | False | 인덱스가 embedding을 반환할 수 없으므로 abs를 계산하려면 embedding을 구체화해야 함 |
+| Sql11 | Sql9의 변형 (`array_size(embedding) > 10`) | False | array_size로 인해 embedding을 반드시 구체화해야 함 |
+
+자세한 주석을 포함한 전체 SQL은 다음과 같습니다.
+
+```SQL
+-- Sql1
+-- Range + proj
+-- The Ann index can return dist, so dist does not need to be computed again.
+-- At the same time, virtual column for cse avoids the dist computation in proj.
+-- IndexScan: True
+select id, dist(embedding, [...]) from tbl where dist <= 10;
+
+-- Sql2
+-- Range + no-proj
+-- The Ann index can return dist, so dist does not need to be computed again.
+-- IndexScan: True
+select id from tbl where dist <= 10 order by id limit N;
+
+-- Sql3
+-- Range + proj + no-dist-from index
+-- The Ann index cannot return dist (the index can only update the rowid map).
+-- Since proj requires dist to be returned, embedding must be re-read.
+-- IndexScan: False
+select id, dist(embedding, [...]) from tbl where dist > 10;
+
+-- Sql4
+-- Range + proj + no-dist-from index
+-- The Ann index cannot return dist (the index can only update the rowid map).
+-- However, proj does not need dist, so embedding does not need to be re-read.
+-- IndexScan: True
+select id from tbl where dist > 10;
+
+-- Sql5
+-- TopN
+-- AnnIndex returns dist, and virtual slot for cse ensures that the dist from the index is passed up to proj,
+-- so the embedding column does not need to be read.
+-- IndexScan: True
+select id[, dist(embedding, [...])] from tbl order by dist(embedding, [...]) asc limit N;
+
+-- Sql6
+-- TopN + IndexFilter
+-- 1. The comment column does not need to be read; the inverted index scan has already done this optimization.
+-- 2. The embedding column does not need to be read, for the same reason as Sql5.
+-- IndexScan: True
+select id[, dist(embedding, [...])] from tbl where comment match_any 'olap' ORDER BY dist(embedding, [...]) LIMIT N;
+
+-- Sql7
+-- TopN + Range
+-- IndexScan: True, because this is a combination of Sql1 and Sql5.
+select id[, dist(embedding, [...])] from tbl where dist(embedding, [...]) > 10 order by dist(embedding, [...]) limit N;
+
+-- Sql8
+-- TopN + Range + IndexFilter
+-- IndexScan: True, because this is a combination of Sql7 and Sql6.
+select id[, dist(embedding, [...])] from tbl where comment match_any 'olap' and dist(embedding, [...]) > 10 ORDER BY dist(embedding, [...]) LIMIT N;
+
+-- Sql9
+-- TopN + Range + CommonFilter
+-- The key points here: 1. dist < 10, not dist > 10; 2. the common filter does not read embedding directly, but reads dist.
+-- The Ann index can return dist, and virtual slot ref for cse ensures that all reads of dist refer to the same column.
+-- In this case, although Ann TopN cannot be applied, in theory the embedding column does not need to be materialized at any point.
+-- However, in practice, embedding is still materialized, because whether a column can skip reading is currently judged by whether predicates on this column still have residuals;
+-- the common filter itself cannot be eliminated, so the current code still considers it necessary to materialize the column.
+-- The ROI of this optimization is low, so it is not done.
+-- IndexScan: False
+select id[, dist(embedding, [...])] from tbl where comment match_any 'olap' and dist(embedding, [...]) < 10 AND abs(dist(embedding) + 10) > 10 ORDER BY dist(embedding, [...]) LIMIT N;
+
+-- Sql10
+-- A variant of Sql9: dist < 10 becomes dist > 10. In this case the index cannot return embedding,
+-- so embedding must be materialized in order to compute abs(dist(embedding, [...])).
+-- IndexScan: False
+select id[, dist(embedding, [...])] from tbl where comment match_any 'olap' and dist(embedding, [...]) > 10 AND abs(dist(embedding) + 10) > 10 ORDER BY dist(embedding, [...]) LIMIT N;
+
+-- Sql11
+-- A variant of Sql9: abs(dist(embedding) + 10) > 10 becomes array_size(embedding) > 10. The difference is that array_size forces embedding to be materialized.
+-- To compute array_size(embedding, [...]), embedding must be materialized.
+-- IndexScan: False
+select id[, dist(embedding, [...])] from tbl where comment match_any 'olap' and dist(embedding, [...]) < 10 AND array_size(embedding) > 10 ORDER BY dist(embedding, [...]) LIMIT N;
+```
+
+### 공통 부분식 최적화를 위한 가상 컬럼 {#virtual-columns-for-common-subexpression-optimization}
+
+Index Only Scan은 주로 IO 문제를 해결하며 embedding에 대한 대량의 임의 읽기를 방지합니다. Doris는 중복 계산까지 제거하기 위해 계산 계층에 "가상 컬럼" 메커니즘을 도입하여, 인덱스가 반환한 dist를 컬럼 형태로 표현식 실행기에 전달합니다.
+
+가상 컬럼의 핵심 설계 사항은 다음과 같습니다.
+
+1. 표현식 노드 `VirtualSlotRef`를 도입하여, 특정 표현식에 의해 구체화되고 여러 표현식이 공유할 수 있는 특수한 "런타임 계산" 컬럼을 나타냅니다. 이 컬럼은 처음 사용할 때 한 번만 계산되므로 Projection과 조건자 사이의 공통 부분식(CSE) 중복을 제거합니다.
+2. 컬럼 반복자 `VirtualColumnIterator`를 도입하여 인덱스가 반환한 거리를 표현식에서 사용할 수 있도록 구체화하고, 중복된 거리 함수 계산을 방지합니다.
+
+이 메커니즘은 처음에는 ANN 관련 쿼리의 CSE 제거에 사용되었으며, 이후 일반적인 Projection + Scan + Filter 조합으로 확장되었습니다.
+
+#### 측정 결과 {#measured-results}
+
+ClickBench 데이터셋을 기반으로 Google에서 유입된 클릭 수가 가장 많은 상위 20개 웹사이트를 집계합니다.
+
+```sql
+set experimental_enable_virtual_slot_for_cse=true;
+
+SELECT counterid,
+ COUNT(*) AS hit_count,
+ COUNT(DISTINCT userid) AS unique_users
+FROM hits
+WHERE ( UPPER(regexp_extract(referer, '^https?://([^/]+)', 1)) = 'GOOGLE.COM'
+ OR UPPER(regexp_extract(referer, '^https?://([^/]+)', 1)) = 'GOOGLE.RU'
+ OR UPPER(regexp_extract(referer, '^https?://([^/]+)', 1)) LIKE '%GOOGLE%' )
+ AND ( LENGTH(regexp_extract(referer, '^https?://([^/]+)', 1)) > 3
+ OR regexp_extract(referer, '^https?://([^/]+)', 1) != ''
+ OR regexp_extract(referer, '^https?://([^/]+)', 1) IS NOT NULL )
+ AND eventdate = '2013-07-15'
+GROUP BY counterid
+HAVING hit_count > 100
+ORDER BY hit_count DESC
+LIMIT 20;
+```
+
+핵심 표현식인 `regexp_extract(referer, '^https?://([^/]+)', 1)`은 CPU 집약적이며 여러 곳에서 재사용됩니다. 가상 컬럼 최적화의 활성화 여부에 따른 비교 결과는 다음과 같습니다.
+
+| 상태 | 소요 시간 |
+|-------|------|
+| 최적화 비활성화 | 1.50 s |
+| 최적화 활성화 (`set experimental_enable_virtual_slot_for_cse=true`) | 0.57 s |
+
+종단 간 성능이 약 **3배** 향상됩니다.
+
+### Scan 병렬화 최적화 {#scan-parallelism-optimization}
+
+Doris는 Ann TopN Search에 맞춰 Scan 병렬화 전략을 재설계했습니다.
+
+| 항목 | 기존 전략 | 새 전략 |
+|-----------|--------------|--------------|
+| 병렬화 기준 | 행 수(기본값: 2,097,152행 / Scan Task) | segment마다 정확히 하나의 Scan Task 생성 |
+| 고차원 벡터 시나리오에서의 동작 | 단일 segment의 행 수가 임계값보다 훨씬 적어 여러 segment를 직렬로 스캔 | 인덱스 분석 단계에서 병렬성 향상 |
+| 테이블 조회의 영향 | - | Ann TopN은 필터링 비율이 높으므로 직렬 테이블 조회가 전체 성능에 영향을 주지 않음 |
+
+SIFT 1M을 예로 들면, `set optimize_index_scan_parallelism=true;`를 활성화한 후 직렬 TopN 쿼리의 소요 시간이 **230 ms에서 50 ms로** 줄어듭니다.
+
+또한 4.0에서는 "동적 병렬성 조정"을 도입했습니다. 각 스케줄링 라운드 전에 Scan 스레드 풀의 부하를 기준으로 제출 가능한 작업 수를 동적으로 결정합니다. 부하가 높으면 병렬성을 낮추고, 리소스가 유휴 상태이면 병렬성을 높여 직렬 및 높은 동시성 시나리오 모두에서 리소스 활용도와 스케줄링 오버헤드의 균형을 맞춥니다.
+
+### 전역 TopN 지연 구체화 {#global-topn-late-materialization}
+
+일반적인 Ann TopN 쿼리는 두 단계로 구성됩니다.
+
+1. **첫 번째 단계**: Scan 연산자가 인덱스를 통해 각 segment의 TopN 거리를 가져옵니다.
+2. **두 번째 단계**: 전역 정렬 노드가 segment별 TopN을 병합하고 정렬하여 최종 TopN을 얻습니다.
+
+프로젝션이 여러 컬럼을 반환하거나 String과 같은 큰 컬럼을 포함하면, 첫 번째 단계에서 각 segment로부터 읽은 N행이 많은 디스크 IO를 유발할 수 있습니다. 또한 이 행들은 최종 TopN에 포함되지 않아 두 번째 단계의 전역 정렬에서 버려질 수 있습니다. Doris는 "전역 TopN 지연 구체화"를 사용하여 첫 번째 단계의 읽기 양을 최소화합니다.
+
+다음 예를 살펴보겠습니다.
+
+```sql
+SELECT id, l2_distance_approximate(embedding, [...]) AS dist
+FROM tbl
+ORDER BY dist
+LIMIT 100;
+```
+
+실행 흐름:
+
+1. 첫 번째 단계: 각 segment가 Ann Index Only Scan + 가상 컬럼을 사용하여 100개의 `dist` 값과 해당 `rowid`만 출력합니다.
+2. 두 번째 단계: 전체 segment 수가 M이면, `100 * M`개의 `dist` 값을 전역 정렬하여 최종 TopN과 해당 `rowid`를 얻습니다.
+3. 마지막으로 Materialize 연산자가 이 `rowid`를 기반으로 해당 tablet/rowset/segment에서 필요한 컬럼을 구체화합니다.
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/vector-index/hnsw.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/vector-index/hnsw.md
new file mode 100644
index 00000000000..bd7c326df28
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/vector-index/hnsw.md
@@ -0,0 +1,461 @@
+---
+{
+ "title": "HNSW",
+ "language": "ko",
+ "description": "Apache Doris HNSW 벡터 인덱스의 알고리즘 원리, 파라미터 튜닝, 재현율 최적화, 쿼리 성능 벤치마크를 알아보고 고성능 ANN 검색 시스템을 구축합니다.",
+ "keywords": [
+ "HNSW",
+ "ANN 인덱스",
+ "벡터 검색",
+ "근사 최근접 이웃 검색",
+ "Apache Doris 벡터 인덱스",
+ "ef_construction",
+ "ef_search",
+ "max_degree",
+ "재현율 최적화"
+ ]
+}
+---
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<!-- Knowledge type: algorithm principles + configuration parameters + operating procedures -->
+<!-- Applicable scenarios: vector search selection / index tuning / recall optimization / performance benchmarking -->
+
+HNSW(Hierarchical Navigable Small World, Malkov & Yashunin, 2016)는 운영 환경에서 비교적 적은 리소스로 높은 재현율과 낮은 지연 시간을 제공하여, 온라인 고성능 벡터 검색의 사실상 표준으로 자리 잡았습니다. Apache Doris는 4.0 버전부터 HNSW 기반 ANN(Approximate Nearest Neighbor) 인덱스를 지원합니다. 이 문서에서는 알고리즘 원리부터 시작하여 파라미터와 실제 운영 사례를 함께 살펴보고, Apache Doris 운영 클러스터에서 HNSW 인덱스를 사용하고 튜닝하는 방법을 설명합니다.
+
+## 빠른 탐색 {#quick-navigation}
+
+- HNSW가 처음이라면 [HNSW 이전](#before-hnsw)과 [계층적 탐색 가능 스몰 월드](#hierarchical-navigable-small-world)에서 알고리즘의 발전 과정을 살펴보세요.
+- 바로 실습하고 싶다면 [Apache Doris의 HNSW](#hnsw-in-apache-doris)에서 테이블 생성, 인덱스 구축, 쿼리 예제를 확인하세요.
+- 검색 품질이 중요하다면 [재현율 최적화](#recall-optimization)와 [벤치마크](#benchmark)를 참조하세요.
+- 리소스 비용이 중요하다면 [메모리 사용량과 성능](#memory-footprint-and-performance)을 참조하세요.
+
+## HNSW 이전 {#before-hnsw}
+
+<!-- Knowledge type: algorithm background -->
+
+HNSW 알고리즘은 논문 [Hierarchical Navigable Small World 그래프를 이용한 효율적이고 견고한 근사 최근접 이웃 검색](https://arxiv.org/abs/1603.09320)에서 제안되었습니다. HNSW 이전에도 업계에는 다양한 근사 KNN 검색 알고리즘이 있었지만, 각각 문제가 있었습니다.
+
+### 근접 그래프 {#proximate-graph}
+
+근접 그래프 알고리즘의 기본 흐름은 다음과 같습니다.
+
+1. 그래프의 진입점(임의의 정점 또는 특정 전략에 따라 선택한 정점)에서 시작하여 그래프를 반복적으로 탐색합니다.
+2. 각 단계에서 쿼리 벡터와 현재 기준 노드의 모든 이웃 사이의 거리를 계산하고, 거리가 가장 가까운 이웃을 다음 기준 노드로 선택합니다.
+3. 지금까지 찾은 최상의 후보 이웃 집합을 유지합니다.
+4. 종료 조건이 충족되면(예: 한 번의 반복에서 더 가까운 노드를 찾지 못한 경우) 탐색을 중단하고, 후보 집합에서 Top K를 최종 결과로 선택합니다.
+
+근접 그래프 알고리즘은 본질적으로 Delaunay Graph의 근사 방식입니다. Delaunay Graph에는 **탐욕 검색으로 항상 최근접 이웃을 찾을 수 있다**는 중요한 특성이 있기 때문입니다.
+
+하지만 이러한 알고리즘에는 두 가지 뚜렷한 단점이 있습니다.
+
+| 단점 | 영향 |
+|------|------|
+| 쿼리 라우팅 단계의 반복 횟수가 데이터 규모에 따라 다항식으로 증가함 | 대규모 데이터에서 쿼리 비용이 급격히 증가함 |
+| 고품질 근접 그래프를 구축하기 어렵고 국소적인 군집이 형성되기 쉬움 | 그래프의 전역 연결성이 부족해 일부 노드에 도달하기 어려움 |
+
+
+
+위 그림은 품질이 낮은 근접 그래프를 보여 줍니다. 점의 색이 진할수록 연결성이 떨어집니다. 일부 점은 자신의 이웃조차 거의 찾지 못하므로, 검색 단계에서 이러한 점에 도달하기 어렵습니다.
+
+### 탐색 가능 스몰 월드(Navigable Small World) {#navigable-small-world}
+
+위 문제를 해결하기 위해 업계에서는 두 가지 접근법을 제시했습니다.
+
+1. **하이브리드 알고리즘**: 인접 그래프를 검색하기 전에 대략적인 순위 산정을 통해 더 적합한 진입점을 찾은 다음, 탐욕 검색을 수행합니다.
+2. **탐색 가능 스몰 월드 구조**: 우수한 연결성을 확보하고 노드별 최대 이웃 수에 상한을 두어 검색 복잡도를 제어합니다.
+
+NSW(Navigable Small World)는 두 번째 접근법을 사용합니다.
+
+NSW 모델은 [J. Kleinberg](https://www.nature.com/articles/35022643)가 사회 실험에서 처음 제안했습니다. 이 모델은 사회 구성원 간의 연결 관계를 연구하는 데 사용되었으며, 유명한 [여섯 단계 분리 이론](https://en.wikipedia.org/wiki/Small-world_experiment)과 관련이 있습니다.
+
+K-NN 그래프 알고리즘에서는 검색 시 로그 또는 다중 로그 복잡도를 갖는 모든 스몰 월드 네트워크를 Navigable Small World Network라고 합니다. 구현 방식은 다양하며, 여기서는 다루지 않습니다.
+
+NSW는 당시 일부 데이터셋에서 최고 수준의 검색 성능을 보였지만, 복잡도가 엄밀한 로그 복잡도는 아니므로 저차원 벡터 공간 등의 테스트 데이터셋에서는 성능이 떨어집니다.
+
+## 계층적 탐색 가능 스몰 월드(Hierarchical Navigable Small World) {#hierarchical-navigable-small-world}
+
+<!-- Knowledge type: algorithm principles -->
+
+NSW 알고리즘의 검색 과정은 두 단계로 나뉩니다.
+
+| 단계 | 동작 |
+|------|------|
+| **zoom-out** | 차수가 낮은 정점을 무작위로 골라 진입점으로 사용합니다. 검색 중에는 차수가 높은 노드를 우선 탐색하며, 노드에서 이웃까지의 평균 거리가 해당 노드에서 쿼리 벡터까지의 거리보다 커질 때까지 계속합니다 |
+| **zoom-in** | 적합한 고차수 노드를 찾은 후, 최상의 TopN을 찾을 때까지 탐욕 검색을 수행합니다 |
+
+NSW가 다중 로그 복잡도를 갖는 이유는 총 거리 계산 횟수가 대략 "홉 수 x 거쳐 간 정점의 평균 차수"에 비례하기 때문입니다. 평균 홉 수와 평균 차수 모두 데이터 규모에 따라 로그 형태로 증가하므로, 전체 복잡도는 다중 로그가 됩니다.
+
+**HNSW는 zoom-out 과정을 가속하여 쿼리 시간 복잡도를 로그 시간으로 줄입니다.**
+
+
+
+HNSW에서 "계층"은 NSW 그래프의 정점을 간선의 특성 반경에 따라 여러 계층으로 나누는 것을 의미합니다. 검색 흐름은 다음과 같습니다.
+
+1. 최상위 계층의 진입점에서 시작합니다.
+2. 현재 계층에서 탐욕 검색을 수행하여 해당 계층에서 가장 가까운 점을 찾습니다.
+3. 한 계층 아래로 이동하여 탐욕 검색을 반복합니다.
+4. 최하위 계층에 도달할 때까지 계속하여 최종 결과를 얻습니다.
+
+각 계층에서 노드별 최대 연결 수에 상한이 있으므로, 전체 로그 시간 복잡도가 유지됩니다.
+
+계층을 구성하기 위해 HNSW는 각 노드가 삽입될 때 **기하 분포**에 따라 해당 노드의 계층 `l`을 계산하여, 전체 계층 수가 지나치게 많아지지 않도록 합니다. HNSW는 데이터 적재 전에 데이터를 섞을 필요가 없습니다(NSW에서는 데이터를 반드시 섞어야 하며, 그렇지 않으면 그래프 품질이 떨어집니다). 인덱싱 중 무작위로 계층을 할당하는 과정 자체가 무작위화 단계이기 때문입니다. 이 때문에 HNSW는 진정한 증분 업데이트도 지원합니다.
+
+## Apache Doris의 HNSW {#hnsw-in-apache-doris}
+
+<!-- Knowledge type: operating procedures -->
+
+Doris는 4.0 버전부터 HNSW 알고리즘 기반 ANN 인덱스 구축을 지원합니다.
+
+### 인덱스 구축 {#building-an-index}
+
+ANN 인덱스를 생성하는 방법은 두 가지입니다.
+
+| 방법 | 구축 시점 | 장점 | 단점 |
+|------|----------|------|------|
+| 테이블 생성 시 지정 | 데이터 적재 중 세그먼트가 생성될 때 동기적으로 구축됨 | 데이터 적재가 완료되는 즉시 인덱스로 쿼리를 가속할 수 있음 | 동기식 구축으로 데이터 적재 속도가 느려지고, 컴팩션 시 인덱스가 반복적으로 재구축됨 |
+| `CREATE/BUILD INDEX` | 데이터 적재 후 비동기적으로 구축됨 | 데이터 적재 속도에 영향을 주지 않으며 파라미터 튜닝이 쉬움 | 인덱스를 구축하는 동안 ANN 가속을 사용할 수 없음 |
+
+#### 방법 1: 테이블 생성 시 인덱스 지정 {#method-1-specify-the-index-at-table-creation}
+
+인덱스 파라미터가 정해져 있고 자주 튜닝할 필요가 없는 안정적인 환경에 적합합니다.
+
+```sql
+CREATE TABLE sift_1M (
+ id int NOT NULL,
+ embedding array<float> NOT NULL COMMENT "",
+ INDEX ann_index (embedding) USING ANN PROPERTIES(
+ "index_type"="hnsw",
+ "metric_type"="l2_distance",
+ "dim"="128"
+ )
+) ENGINE=OLAP
+DUPLICATE KEY(id) COMMENT "OLAP"
+DISTRIBUTED BY HASH(id) BUCKETS 1
+PROPERTIES (
+ "replication_num" = "1"
+);
+
+INSERT INTO sift_1M
+SELECT *
+FROM S3(
+ "uri" = "https://selectdb-customers-tools-bj.oss-cn-beijing.aliyuncs.com/sift_database.tsv",
+ "format" = "csv");
+```
+
+#### 방법 2: CREATE / BUILD INDEX {#method-2-create--build-index}
+
+유연한 튜닝이 필요하고 데이터 적재 성능에 민감한 환경에 적합합니다.
+
+1단계: 인덱스 없이 테이블을 생성하고 데이터를 적재합니다.
+
+```sql
+CREATE TABLE sift_1M (
+ id int NOT NULL,
+ embedding array<float> NOT NULL COMMENT ""
+) ENGINE=OLAP
+DUPLICATE KEY(id) COMMENT "OLAP"
+DISTRIBUTED BY HASH(id) BUCKETS 1
+PROPERTIES (
+ "replication_num" = "1"
+);
+
+INSERT INTO sift_1M
+SELECT *
+FROM S3(
+ "uri" = "https://selectdb-customers-tools-bj.oss-cn-beijing.aliyuncs.com/sift_database.tsv",
+ "format" = "csv");
+```
+
+2단계: `CREATE INDEX`로 인덱스 정의를 추가합니다. 이 시점에는 인덱스 정의만 존재하며, 기존 데이터에 대한 인덱스는 아직 구축되지 않았습니다.
+
+```sql
+CREATE INDEX idx_test_ann ON sift_1M (`embedding`) USING ANN PROPERTIES (
+ "index_type"="hnsw",
+ "metric_type"="l2_distance",
+ "dim"="128"
+);
+
+SHOW DATA ALL FROM sift_1M;
+```
+
+출력 예시:
+
+```text
++-----------+-----------+--------------+----------+----------------+---------------+----------------+-----------------+----------------+-----------------+
+| TableName | IndexName | ReplicaCount | RowCount | LocalTotalSize | LocalDataSize | LocalIndexSize | RemoteTotalSize | RemoteDataSize | RemoteIndexSize |
++-----------+-----------+--------------+----------+----------------+---------------+----------------+-----------------+----------------+-----------------+
+| sift_1M | sift_1M | 1 | 1000000 | 170.001 MB | 170.001 MB | 0.000 | 0.000 | 0.000 | 0.000 |
+| | Total | 1 | | 170.001 MB | 170.001 MB | 0.000 | 0.000 | 0.000 | 0.000 |
++-----------+-----------+--------------+----------+----------------+---------------+----------------+-----------------+----------------+-----------------+
+2 rows in set (0.01 sec)
+```
+
+3단계: `BUILD INDEX`로 실제 구축을 시작합니다.
+
+```sql
+BUILD INDEX idx_test_ann ON sift_1M;
+```
+
+`BUILD INDEX`는 비동기적으로 실행됩니다. `SHOW BUILD INDEX`로 작업 상태를 확인할 수 있습니다.
+
+```sql
+SHOW BUILD INDEX WHERE TableName = "sift_1M";
+```
+
+출력 예시:
+
+```text
++---------------+-----------+---------------+------------------------------------------------------------------------------------------------------------------------------------+-------------------------+-------------------------+---------------+----------+------+----------+
+| JobId | TableName | PartitionName | AlterInvertedIndexes | CreateTime | FinishTime | TransactionId | State | Msg | Progress |
++---------------+-----------+---------------+------------------------------------------------------------------------------------------------------------------------------------+-------------------------+-------------------------+---------------+----------+------+----------+
+| 1763603913428 | sift_1M | sift_1M | [ADD INDEX idx_test_ann (`embedding`) USING ANN PROPERTIES("dim" = "128", "index_type" = "hnsw", "metric_type" = "l2_distance")], | 2025-11-20 11:14:55.253 | 2025-11-20 11:15:10.622 | 126128 | FINISHED | | NULL |
++---------------+-----------+---------------+------------------------------------------------------------------------------------------------------------------------------------+-------------------------+-------------------------+---------------+----------+------+----------+
+```
+
+#### DROP INDEX {#drop-index}
+
+튜닝 단계에서는 다양한 파라미터 조합을 테스트해야 할 수 있습니다. `DROP INDEX`로 인덱스를 유연하게 관리할 수 있습니다.
+
+```sql
+ALTER TABLE sift_1M DROP INDEX idx_test_ann;
+```
+
+### 쿼리 실행 {#running-queries}
+
+ANN 인덱스는 **TopN 검색**과 **범위 검색**을 모두 가속할 수 있습니다.
+
+> 벡터 열의 차원이 높으면 쿼리 벡터 자체를 표현하는 문자열로 인해 추가적인 파싱 오버헤드가 발생합니다. **운영 환경, 특히 동시성이 높은 환경에서는 원시 SQL을 직접 사용하여 벡터 검색을 실행하지 마세요.** 대신 준비된 문을 사용하여 SQL 파싱을 미리 수행하세요.
+
+Doris는 벡터 검색용 [Python 라이브러리](https://github.com/uchenily/doris_vector_search)를 공식적으로 제공합니다. 이 라이브러리는 준비된 문을 사용하는 데 필요한 작업을 캡슐화하고, 쿼리 결과를 pandas DataFrame으로 바로 변환하는 데이터 변환 파이프라인을 통합하여 Doris 기반 AI 애플리케이션 개발을 편리하게 해 줍니다.
+
+```python
+from doris_vector_search import DorisVectorClient, AuthOptions
+
+auth = AuthOptions(
+ host="localhost",
+ query_port=9030,
+ user="root",
+ password="",
+)
+
+client = DorisVectorClient(database="demo", auth_options=auth)
+
+tbl = client.open_table("sift_1M")
+
+query = [0.1] * 128 # Example 128-dimensional vector
+
+# SELECT id FROM sift_1M ORDER BY l2_distance_approximate(embedding, query) LIMIT 10;
+result = tbl.search(query, metric_type="l2_distance").limit(10).select(["id"]).to_pandas()
+
+print(result)
+```
+
+실행 결과 예시:
+
+```text
+ id
+0 123911
+1 11743
+2 108584
+3 123739
+4 73311
+5 124746
+6 620941
+7 124493
+8 177392
+9 153178
+```
+
+### 재현율 최적화 {#recall-optimization}
+
+<!-- Knowledge type: performance tuning -->
+<!-- Applicable scenarios: recall does not meet target / index parameter selection -->
+
+벡터 검색에서 가장 중요한 지표는 **재현율**입니다. 성능 수치는 일정 수준의 재현율을 충족할 때만 의미가 있습니다. 재현율에 영향을 미치는 주요 요인은 다음과 같습니다.
+
+1. HNSW 인덱싱 단계 파라미터(`max_degree`, `ef_construction`)와 쿼리 단계 파라미터(`ef_search`)
+2. 인덱스 벡터 양자화
+3. 세그먼트의 크기와 개수
+
+이 절에서는 항목 1과 3을 다룹니다. 벡터 양자화는 다른 문서에서 설명합니다.
+
+#### 인덱스 하이퍼파라미터 {#index-hyperparameters}
+
+HNSW 인덱스는 벡터를 계층적 그래프로 구성합니다. **구축 단계**는 크게 세 단계로 이루어집니다.
+
+1. **여러 계층에 무작위 할당**: 각 벡터를 여러 계층에 무작위로 할당합니다. 상위 계층일수록 더 희소하며, 빠른 탐색에 사용됩니다.
+2. **`ef_construction`을 사용한 후보 이웃 검색**: 각 계층에서 HNSW는 최대 길이가 `ef_construction`인 후보 큐를 사용하여 너비 우선 국소 검색을 수행합니다. 값이 클수록 더 정확한 이웃과 더 나은 그래프 구조를 얻지만, 구축 시간이 길어집니다.
+3. **`max_degree`를 사용한 연결 수 제한**: 노드별 이웃 수를 `max_degree`로 제한하여 그래프가 지나치게 조밀해지는 것을 방지합니다.
+
+**쿼리 단계**는 두 단계로 이루어집니다.
+
+1. **상위 계층 탐욕 검색(Coarse search)**: 진입점에서 시작하여 상위 계층에서 위에서 아래로 탐욕 검색을 수행하고, 목표 영역에 빠르게 접근합니다.
+2. **최하위 계층 너비 우선 검색(Fine search)**: 계층 0에서 최대 길이가 `ef_search`인 후보 큐를 사용하여 이웃 영역을 더 철저하게 확장합니다.
+
+핵심 파라미터 세 가지의 역할과 상충 관계는 다음과 같습니다.
+
+| 파라미터 | 역할 | 기본값 | 값을 늘렸을 때의 영향 |
+|------|------|--------|-----------|
+| `max_degree` | 그래프의 노드별로 저장되는 양방향 간선 수 | 32 | 재현율 증가, 메모리 사용량 증가, 쿼리 성능 저하 |
+| `ef_construction` | 인덱싱 단계에서 후보 큐의 최대 길이 | 40 | 그래프 품질 향상, 재현율 증가, 구축 시간 증가 |
+| `ef_search` | 쿼리 단계에서 후보 큐의 최대 길이 | 32 | 재현율 증가, 거리 계산 횟수 증가, 쿼리 지연 시간 및 CPU 비용 증가 |
+
+아래 표는 SIFT_1M 데이터셋의 측정 결과입니다.
+
+| max_degree | ef_construction | ef_search | recall@1 | recall@100 |
+|------------|------------------|-----------|----------|------------|
+| 32 | 80 | 32 | 0.955 | 0.75335 |
+| 32 | 80 | 64 | 0.98 | 0.88015 |
+| 32 | 80 | 96 | 0.995 | 0.9328 |
+| 32 | 120 | 32 | 0.96 | 0.7736 |
+| 32 | 120 | 64 | 0.975 | 0.89865 |
+| 32 | 120 | 96 | 0.99 | 0.94575 |
+| 32 | 160 | 32 | 0.955 | 0.78745 |
+| 32 | 160 | 64 | 0.98 | 0.9097 |
+| 32 | 160 | 96 | 0.995 | 0.95485 |
+| 48 | 80 | 32 | 0.985 | 0.85895 |
+| 48 | 80 | 64 | 0.99 | 0.9453 |
+| 48 | 80 | 96 | 1 | 0.97325 |
+| 48 | 120 | 32 | 0.97 | 0.78335 |
+| 48 | 120 | 64 | 1 | 0.9089 |
+| 48 | 120 | 96 | 1 | 0.95325 |
+| 48 | 160 | 32 | 0.975 | 0.79745 |
+| 48 | 160 | 64 | 0.995 | 0.9192 |
+| 48 | 160 | 96 | 0.995 | 0.9601 |
+| 64 | 80 | 32 | 1 | 0.9026 |
+| 64 | 80 | 64 | 1 | 0.97025 |
+| 64 | 80 | 96 | 1 | 0.9862 |
+| 64 | 120 | 32 | 0.985 | 0.8548 |
+| 64 | 120 | 64 | 0.99 | 0.94755 |
+| 64 | 120 | 96 | 0.995 | 0.97645 |
+| 64 | 160 | 32 | 0.97 | 0.80585 |
+| 64 | 160 | 64 | 0.99 | 0.91925 |
+| 64 | 160 | 96 | 0.995 | 0.96165 |
+
+표에서 볼 수 있듯이 여러 파라미터 조합으로 동일한 수준의 재현율을 달성할 수 있습니다. 예를 들어 `recall@100 > 95%`를 목표로 할 때, 조건을 충족하는 조합은 다음과 같습니다.
+
+| max_degree | ef_construction | ef_search | recall@1 | recall@100 |
+|------------|------------------|-----------|----------|------------|
+| 32 | 160 | 96 | 0.995 | 0.95485 |
+| 48 | 80 | 96 | 1 | 0.97325 |
+| 48 | 120 | 96 | 1 | 0.95325 |
+| 48 | 160 | 96 | 0.995 | 0.9601 |
+| 64 | 80 | 64 | 1 | 0.97025 |
+| 64 | 80 | 96 | 1 | 0.9862 |
+| 64 | 120 | 96 | 0.995 | 0.97645 |
+| 64 | 160 | 96 | 0.995 | 0.96165 |
+
+**하이퍼파라미터를 선택하는 실용적인 방법**:
+
+1. 인덱스가 없고 여러 벡터 열(벡터 열 2~3개)을 포함하는 테이블 `table_multi_index`를 생성합니다.
+2. Stream Load 등의 방법으로 이 테이블에 데이터를 적재합니다.
+3. `CREATE INDEX`와 `BUILD INDEX`로 모든 벡터 열에 인덱스를 구축하되, **열마다 서로 다른 파라미터 조합을 사용합니다**.
+4. 인덱스 구축이 완료되면 각 열의 재현율을 별도로 계산하고 가장 적합한 하이퍼파라미터 조합을 선택합니다.
+
+#### 인덱스가 처리할 수 있는 행 수 {#number-of-rows-covered-by-an-index}
+
+Doris 내부 테이블의 데이터는 계층적으로 구성됩니다.
+
+| 계층 | 의미 |
+|------|------|
+| 테이블 | 최상위 개념 |
+| 태블릿(Tablet) | 데이터 마이그레이션과 리밸런싱의 기본 단위. 테이블 데이터는 버킷 키에 따라 N개의 태블릿에 고르게 분산됨 |
+| Rowset | 버전 관리의 기본 단위. 데이터 적재 또는 컴팩션이 수행될 때마다 태블릿 아래에 새로운 rowset이 추가됨 |
+| 세그먼트(Segment) | 데이터를 저장하는 실제 파일 |
+
+역색인과 마찬가지로 **벡터 인덱스도 세그먼트 단위로 동작합니다**. 세그먼트 크기는 BE 설정인 `write_buffer_size`와 `vertical_compaction_max_segment_size`에 따라 결정됩니다. 데이터 적재 및 컴팩션 중 memtable이 일정 크기에 도달하면 세그먼트 파일로 플러시되며, 해당 세그먼트에 대한 벡터 인덱스가 구축됩니다(인덱스 열마다 인덱스 하나씩).
+
+HNSW의 검색 및 구축 메커니즘에 따르면, **주어진 인덱스 파라미터 조합으로 효과적으로 처리할 수 있는 데이터 범위에는 한계가 있습니다**. 데이터 규모가 임계값을 넘으면 재현율이 더 이상 요구 수준을 충족하지 못합니다.
+
+다음은 일부 하이퍼파라미터 조합과 해당 조합으로 처리할 수 있는 세그먼트별 행 수의 경험적 수치입니다.
+
+| max_degree | ef_construction | ef_search | num_segment | recall@100 |
+|------------|------------------|-----------|-------------|------------|
+| 32 | 160 | 96 | 1M | 0.95485 |
+| 48 | 80 | 96 | 1M | 0.97325 |
+| 32 | 160 | 32 | 3M | 0.66983 |
+| 128 | 512 | 128 | 3M | 0.9931 |
+
+> `SHOW TABLETS FROM <table>`을 실행하여 테이블의 컴팩션 상태를 확인하세요. 해당 URL을 클릭하면 세그먼트 수를 확인할 수 있습니다.
+
+#### 컴팩션이 재현율에 미치는 영향 {#effect-of-compaction-on-recall}
+
+컴팩션으로 더 큰 세그먼트가 생성되면, 기존 인덱스 하이퍼파라미터로는 새로 커진 세그먼트를 충분히 처리하지 못할 수 있습니다.
+
+**권장 방법**: `FULL COMPACTION`을 수행한 다음 `BUILD INDEX`를 실행하세요. 컴팩션을 완전히 마친 세그먼트에 인덱스를 구축하면 다음 두 가지 이점이 있습니다.
+
+- 안정적인 재현율
+- 인덱스 구축으로 발생하는 쓰기 증폭 감소
+
+### 쿼리 성능 {#query-performance}
+
+<!-- Knowledge type: performance tuning -->
+
+#### 인덱스 파일의 콜드 로딩 {#cold-loading-of-index-files}
+
+Doris ANN 인덱스는 Meta의 오픈 소스 [faiss](https://github.com/facebookresearch/faiss)를 기반으로 구현되었습니다. **HNSW 인덱스는 전체 그래프 구조를 메모리에 로딩한 후에만 쿼리를 가속할 수 있습니다.**
+
+동시성이 높은 쿼리를 실행하기 전에 콜드 쿼리를 먼저 실행하여 관련 세그먼트의 인덱스 파일을 메모리에 미리 로딩하세요. 그렇지 않으면 쿼리 성능이 크게 떨어집니다.
+
+#### 메모리 사용량과 성능 {#memory-footprint-and-performance}
+
+> **양자화 압축을 적용하지 않은 HNSW 인덱스는 인덱싱 대상 벡터 메모리의 약 1.3배를 차지합니다.**
+
+예를 들어 128차원, 1M 데이터셋의 경우 HNSW FLAT 인덱스에는 약 `128 x 4 x 1,000,000 x 1.3 ~= 650 MB`가 필요합니다.
+
+데이터 규모별 예상 메모리 사용량은 다음과 같습니다.
+
+| dim | rows | 예상 메모리 |
+|-----|------|---------|
+| 128 | 1M | 650 MB |
+| 768 | 10M | 48 GB |
+| 768 | 100M | 110 GB |
+
+쿼리 성능을 보장하려면 **BE 노드에 충분한 메모리를 구성해야 합니다**. 그렇지 않으면 빈번한 인덱스 I/O로 인해 쿼리 성능이 크게 저하됩니다.
+
+### 벤치마크 {#benchmark}
+
+<!-- Knowledge type: performance benchmark -->
+
+테스트 하드웨어: 16C 64GB 머신. 테스트 프레임워크: [VectorDBBench](https://github.com/zilliztech/VectorDBBench). 부하 클라이언트: 별도의 16C 머신.
+
+Doris 운영 클러스터의 일반적인 배포 방식은 FE와 BE를 **분리 배포**하는 것입니다(16C 64GB 머신 두 대 필요). 아래 표에는 일반적인 배포 방식과 함께 FE와 BE를 **혼합 배포**한 테스트 결과도 나와 있습니다.
+
+#### Performance768D1M {#performance768d1m}
+
+테스트 명령어:
+
+```bash
+NUM_PER_BATCH=1000000 python3.11 -m vectordbbench doris --host 127.0.0.1 --port 9030 --case-type Performance768D1M --db-name Performance768D1M --search-concurrent --search-serial --num-concurrency 10,40,80 --stream-load-rows-per-batch 500000 --index-prop max_degree=128,ef_construction=512 --session-var hnsw_ef_search=128
+```
+
+테스트 결과 비교:
+
+| | Doris (FE/BE 분리) | Doris (FE/BE 혼합) |
+|------|----------------------|----------------------|
+| **인덱스 속성** | max_degree=128, ef_construction=512, hnsw_ef_search=128 | max_degree=128, ef_construction=512, hnsw_ef_search=156 |
+| **Recall@100** | 0.9931 | 0.9929 |
+| **동시성(클라이언트)** | 10, 40, 80 | 10, 40, 80 |
+| **결과 QPS** | 163.1567 (10)<br />606.6832 (40)<br />859.3842 (80) | 162.3002 (10)<br />542.3488 (40)<br />607.7951 (80) |
+| **평균 지연 시간(s)** | 0.06123 (10)<br />0.06579 (40)<br />0.09281 (80) | 0.06154 (10)<br />0.07351 (40)<br />0.13093 (80) |
+| **P95 지연 시간(s)** | 0.06560 (10)<br />0.07747 (40)<br />0.12967 (80) | 0.06726 (10)<br />0.08789 (40)<br />0.18719 (80) |
+| **P99 지연 시간(s)** | 0.06889 (10)<br />0.08618 (40)<br />0.14605 (80) | 0.06154 (10)<br />0.07351 (40)<br />0.13093 (80) |
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/vector-index/index-management.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/vector-index/index-management.md
new file mode 100644
index 00000000000..29755f8693a
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/vector-index/index-management.md
@@ -0,0 +1,330 @@
+---
+{
+ "title": "ANN 인덱스 관리",
+ "language": "ko",
+ "description": "Apache Doris ANN 벡터 인덱스의 생성, 빌드, 조회 및 삭제를 위한 전체 SQL 작업 가이드로, HNSW, IVF 및 양자화 매개변수 설명을 포함합니다.",
+ "keywords": [
+ "ANN 인덱스",
+ "벡터 인덱스 관리",
+ "HNSW",
+ "IVF",
+ "벡터 유사도 검색",
+ "Doris 벡터 검색",
+ "BUILD INDEX",
+ "스칼라 양자화 SQ",
+ "곱 양자화 PQ"
+ ]
+}
+---
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<!-- Knowledge type: Operation steps + Configuration parameters -->
+<!-- Applicable scenarios: Vector retrieval table creation / Index operations / Performance tuning -->
+
+# ANN 인덱스 관리 {#ann-index-management}
+
+Apache Doris의 근사 최근접 이웃(ANN) 인덱스는 고차원 벡터 열에서 벡터 유사도 검색을 효율적으로 수행하는 데 사용됩니다. Doris 4.x부터 일반 인덱스 작업 구문에서 ANN 인덱스를 지원합니다. 이 문서에서는 ANN 인덱스와 관련된 SQL 작업 구문과 매개변수를 설명합니다.
+
+## 빠른 탐색 {#quick-navigation}
+
+사용 사례에 따라 해당 섹션으로 이동할 수 있습니다.
+
+| 사용 사례 | 섹션 |
+| ----------------------------------------------------- | -------------------------------------------------- |
+| 벡터 열에 인덱스를 처음 생성 | [ANN 인덱스 생성](#create-an-ann-index) |
+| 기존 데이터에 인덱스를 오프라인으로 빌드 | [ANN 인덱스 빌드](#build-an-ann-index) |
+| 기존 인덱스와 매개변수 설정 조회 | [ANN 인덱스 조회](#view-an-ann-index) |
+| 더 이상 필요하지 않은 인덱스 삭제 | [ANN 인덱스 삭제](#drop-an-ann-index) |
+| HNSW, IVF 등의 특정 알고리즘 또는 양자화기 선택 | [인덱스 매개변수](#index-parameters) |
+
+## 사전 요구 사항 {#prerequisites}
+
+ANN 인덱스를 생성하기 전에 다음 사항을 확인하세요.
+
+- 벡터 열의 데이터 타입이 `ARRAY<FLOAT> NOT NULL`이어야 합니다.
+- 적절한 거리 측정 유형을 선택해야 합니다. `l2_distance`(유클리드 거리) 또는 `inner_product`를 사용할 수 있습니다.
+- 데이터 규모와 재현율/성능 요구 사항에 따라 인덱스 알고리즘(HNSW, IVF 또는 IVF On-Disk)을 선택해야 합니다.
+
+## ANN 인덱스 생성 {#create-an-ann-index}
+
+Doris는 ANN 인덱스를 생성하는 두 가지 방법을 제공합니다. 데이터가 이미 적재되었는지에 따라 선택하세요.
+
+| 방법 | 적용 상황 | 인덱스 빌드 시점 |
+| ------------------------------------- | -------------------------------------------------------------------- | -------------------------------------- |
+| 테이블 생성 시 인덱스 정의 | 테이블이 아직 생성되지 않았거나, 데이터가 기록될 때마다 인덱스를 계속 빌드해야 하는 경우 | 데이터 적재 중 동기적으로 빌드 |
+| 인덱스 생성과 빌드를 별도로 수행 | 테이블에 데이터가 이미 존재하며, 나중에 인덱스를 추가해야 하는 경우 | `BUILD INDEX`로 비동기적으로 빌드 |
+
+### 방법 1: 테이블 생성 시 인덱스 정의 {#method-1-define-the-index-when-creating-the-table}
+
+ANN 인덱스는 `INDEX ... USING ANN`을 사용하여 `CREATE TABLE` 문의 열 정의 뒤에 직접 선언합니다. 데이터가 적재될 때 인덱스가 동기적으로 빌드됩니다.
+
+```sql
+CREATE TABLE [IF NOT EXISTS] <table_name> (
+ <columns_definition>
+ INDEX <index_name> (<vector_column>) USING ANN PROPERTIES (
+ "<key>" = "<value>" [, ...]
+ )
+)
+...
+```
+
+### 방법 2: 인덱스를 별도로 생성 {#method-2-create-the-index-separately}
+
+기존 테이블에서는 `CREATE INDEX` 또는 `ALTER TABLE ADD INDEX`로 ANN 인덱스를 추가한 다음, [BUILD INDEX](#build-an-ann-index)를 사용하여 기존 데이터에 인덱스를 빌드합니다.
+
+```sql
+CREATE INDEX [IF NOT EXISTS] <index_name>
+ ON <table_name> (<column_name>)
+ USING ANN
+ PROPERTIES ("<key>" = "<value>" [, ...])
+ [COMMENT '<index_comment>']
+
+-- Or
+
+ALTER TABLE <table_name> ADD INDEX <index_name>(<column_name>)
+ USING ANN
+ [PROPERTIES ("<key>" = "<value>" [, ...])]
+ [COMMENT '<index_comment>']
+```
+
+## 인덱스 매개변수 {#index-parameters}
+
+ANN 인덱스의 동작은 `PROPERTIES`의 속성에 따라 결정됩니다. 속성은 일반 속성, 인덱스 알고리즘별 속성, 양자화기별 속성의 세 범주로 나뉩니다.
+
+### 일반 속성 {#general-attributes}
+
+모든 ANN 인덱스에서 설정해야 하는 기본 속성입니다.
+
+| 속성 | 설명 | 기본값 |
+| ------------- | ---------------------------------------------------------------------------- | ------- |
+| `index_type` | ANN 인덱스 유형입니다. 사용 가능한 값: `ivf`, `ivf_on_disk`, `hnsw` | - |
+| `metric_type` | 거리 측정 유형입니다. 사용 가능한 값: `l2_distance`(유클리드 거리), `inner_product` | - |
+| `dim` | 벡터 열의 차원 수 | - |
+| `quantizer` | 양자화기 유형입니다. 사용 가능한 값: `flat`, `sq4`, `sq8`, `pq` | `flat` |
+
+### 인덱스 알고리즘별 속성 {#index-algorithm-specific-attributes}
+
+#### IVF / IVF On-Disk {#ivf--ivf-on-disk}
+
+| 속성 | 설명 | 기본값 |
+| --------- | ------------------------------------------------------------------------------------------------------------------------ | ------- |
+| `nlist` | 클러스터(역방향 목록)의 개수입니다. `ivf`와 `ivf_on_disk` 모두에 필요합니다. 값이 클수록 재현율이 높아지지만 빌드 시간과 리소스 사용량도 증가합니다. | `1024` |
+
+#### HNSW {#hnsw}
+
+| 속성 | 설명 | 기본값 |
+| ----------------- | ---------------------------------------------------------------------------- | ------- |
+| `max_degree` | 노드당 최대 연결 수로, 재현율과 쿼리 성능에 영향을 줍니다. | `32` |
+| `ef_construction` | 인덱스 빌드 중 사용하는 후보 큐의 크기입니다. 값이 클수록 그래프의 품질이 높아지지만 빌드 시간도 증가합니다. | `40` |
+
+### 양자화기별 속성 {#quantizer-specific-attributes}
+
+`quantizer`는 벡터 저장 공간을 압축하는 데 사용됩니다. 양자화기별 차이는 다음과 같습니다.
+
+| 양자화기 | 의미 | 추가 매개변수 |
+| --------- | ------------------------------------------------------------------------------------------------ | ---------------------------- |
+| `flat` | 양자화를 수행하지 않습니다. 벡터를 원래의 32비트 부동소수점 수로 저장합니다. | 없음 |
+| `sq4` | 스칼라 양자화입니다. 각 차원을 32비트 부동소수점 수 대신 4비트 정수로 저장합니다. | 없음 |
+| `sq8` | 스칼라 양자화입니다. 각 차원을 32비트 부동소수점 수 대신 8비트 정수로 저장합니다. | 없음 |
+| `pq` | 곱 양자화입니다. 벡터를 여러 하위 벡터로 나누고 각각 양자화합니다. | `pq_m`과 `pq_nbits`가 필요함 |
+
+#### 곱 양자화(PQ)의 추가 매개변수 {#extra-parameters-for-product-quantization-pq}
+
+| 속성 | 설명 |
+| ---------- | ---------------------------------------------------------------------------------------- |
+| `pq_m` | 하위 벡터의 개수입니다. 벡터 차원 수 `dim`은 `pq_m`으로 나누어떨어져야 합니다. |
+| `pq_nbits` | 하위 벡터당 비트 수입니다. faiss에서는 일반적으로 `pq_nbits`가 24 이하여야 합니다. |
+
+## 인덱스 생성 예시 {#index-creation-examples}
+
+다음 SQL 예시는 일반적인 조합을 다루며 템플릿으로 사용할 수 있습니다.
+
+### 테이블 생성 시 HNSW 인덱스 선언 {#declare-an-hnsw-index-when-creating-the-table}
+
+```sql
+CREATE TABLE tbl_ann (
+ id int NOT NULL,
+ embedding array<float> NOT NULL,
+ INDEX ann_index (embedding) USING ANN PROPERTIES(
+ "index_type"="hnsw",
+ "metric_type"="l2_distance",
+ "dim"="128"
+ )
+) ENGINE=OLAP
+DUPLICATE KEY(id)
+DISTRIBUTED BY HASH(id) BUCKETS 1
+PROPERTIES ("replication_num" = "1");
+```
+
+### IVF 인덱스 {#ivf-index}
+
+```sql
+CREATE INDEX ann_ivf_index ON tbl_ivf (`embedding`) USING ANN PROPERTIES(
+ "index_type"="ivf",
+ "metric_type"="l2_distance",
+ "dim"="128",
+ "nlist"="1024"
+);
+```
+
+### HNSW 인덱스 {#hnsw-index}
+
+```sql
+CREATE INDEX ann_hnsw_index ON tbl_hnsw (`embedding`) USING ANN PROPERTIES(
+ "index_type"="hnsw",
+ "metric_type"="l2_distance",
+ "dim"="128",
+ "max_degree"="32",
+ "ef_construction"="40"
+);
+```
+
+### HNSW + SQ {#hnsw--sq}
+
+```sql
+CREATE INDEX ann_hnsw_sq ON tbl_hnsw (`embedding`) USING ANN PROPERTIES(
+ "index_type"="hnsw",
+ "metric_type"="l2_distance",
+ "dim"="128",
+ "max_degree"="32",
+ "ef_construction"="40",
+ "quantizer"="sq8"
+);
+```
+
+### HNSW + PQ {#hnsw--pq}
+
+```sql
+CREATE INDEX ann_hnsw_pq ON tbl_hnsw (`embedding`) USING ANN PROPERTIES(
+ "index_type"="hnsw",
+ "metric_type"="l2_distance",
+ "dim"="128",
+ "max_degree"="32",
+ "ef_construction"="40",
+ "quantizer"="pq",
+ "pq_m"="8",
+ "pq_nbits"="8"
+);
+```
+
+### IVF + SQ {#ivf--sq}
+
+```sql
+CREATE INDEX ann_ivf_sq ON tbl_ivf (`embedding`) USING ANN PROPERTIES(
+ "index_type"="ivf",
+ "metric_type"="l2_distance",
+ "dim"="128",
+ "nlist"="1024",
+ "quantizer"="sq8"
+);
+```
+
+### IVF + PQ {#ivf--pq}
+
+```sql
+CREATE INDEX ann_ivf_pq ON tbl_ivf (`embedding`) USING ANN PROPERTIES(
+ "index_type"="ivf",
+ "metric_type"="l2_distance",
+ "dim"="128",
+ "nlist"="1024",
+ "quantizer"="pq",
+ "pq_m"="8",
+ "pq_nbits"="8"
+);
+```
+
+## ANN 인덱스 빌드 {#build-an-ann-index}
+
+인덱스를 `CREATE INDEX` 또는 `ALTER TABLE ADD INDEX`로 별도로 생성한 경우, `BUILD INDEX`를 사용하여 기존 데이터에 인덱스를 빌드합니다. 이 작업은 **비동기적으로** 실행됩니다.
+
+### 빌드 시작 {#trigger-a-build}
+
+```sql
+BUILD INDEX <index_name> ON <table_name> [PARTITION (<partition_name> [, ...])]
+```
+
+### 빌드 진행 상황 모니터링 {#monitor-build-progress}
+
+`SHOW BUILD INDEX`를 사용하여 인덱스 빌드 작업의 진행 상황과 상태를 확인합니다.
+
+```sql
+-- View the progress of all BUILD INDEX tasks (a database can be specified)
+SHOW BUILD INDEX [FROM db_name];
+
+-- View the progress of BUILD INDEX tasks for a specific table
+SHOW BUILD INDEX WHERE TableName = "<table_name>";
+```
+
+출력에는 `JobId`, `TableName`, `State`(예: `FINISHED` 또는 `RUNNING`), `Progress` 등의 열이 포함됩니다. 예시:
+
+```sql
+mysql> show build index where TableName = "sift_1M";
++---------------+-----------+---------------+-----------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+-------------------------+---------------+----------+------+----------+
+| JobId | TableName | PartitionName | AlterInvertedIndexes | CreateTime | FinishTime | TransactionId | State | Msg | Progress |
++---------------+-----------+---------------+-----------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+-------------------------+---------------+----------+------+----------+
+| 1764579876673 | sift_1M | sift_1M | [ADD INDEX idx_test_ann (`embedding`) USING ANN PROPERTIES("dim" = "128", "index_type" = "ivf", "metric_type" = "l2_distance", "nlist" = "1024")], | 2025-12-01 17:59:54.277 | 2025-12-01 17:59:56.987 | 82 | FINISHED | | NULL |
++---------------+-----------+---------------+-----------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+-------------------------+---------------+----------+------+----------+
+1 row in set (0.00 sec)
+```
+
+### 빌드 취소 {#cancel-a-build}
+
+진행 중인 인덱스 빌드 작업을 취소하려면 다음 구문을 사용합니다.
+
+```sql
+CANCEL BUILD INDEX ON <table_name> [(<job_id> [, ...])]
+```
+
+## ANN 인덱스 조회 {#view-an-ann-index}
+
+`SHOW INDEX` 또는 `SHOW CREATE TABLE`로 인덱스 정보를 조회할 수 있습니다.
+
+```sql
+SHOW INDEX[ES] FROM [<db_name>.]<table_name> [FROM <db_name>]
+
+-- Or
+
+SHOW CREATE TABLE [<db_name>.]<table_name>
+```
+
+`SHOW INDEX`의 출력에는 `Table`, `Key_name`, `Index_type`(ANN 인덱스의 경우 `ANN`으로 표시), `Properties`(전체 인덱스 설정 포함) 등의 열이 포함됩니다. 예시:
+
+```sql
+mysql> SHOW INDEX FROM sift_1M;
++---------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+----------------------------------------------------------------------------------------+
+| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Properties |
++---------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+----------------------------------------------------------------------------------------+
+| sift_1M | | idx_test_ann | | embedding | | | | | | ANN | | ("dim" = "128", "index_type" = "ivf", "metric_type" = "l2_distance", "nlist" = "1024") |
++---------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+----------------------------------------------------------------------------------------+
+1 row in set (0.01 sec)
+```
+
+## ANN 인덱스 삭제 {#drop-an-ann-index}
+
+`DROP INDEX` 또는 `ALTER TABLE DROP INDEX`를 사용하여 기존 ANN 인덱스를 삭제합니다.
+
+```sql
+DROP INDEX [IF EXISTS] <index_name> ON [<db_name>.]<table_name>
+
+-- Or
+
+ALTER TABLE [<db_name>.]<table_name> DROP INDEX <index_name>
+```
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/vector-index/ivf-on-disk.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/vector-index/ivf-on-disk.md
new file mode 100644
index 00000000000..cf345405dab
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/vector-index/ivf-on-disk.md
@@ -0,0 +1,222 @@
+---
+{
+ "title": "IVF On-Disk",
+ "language": "ko",
+ "description": "Apache Doris의 IVF On-Disk 인덱스는 역색인 목록을 디스크에 저장하고 전용 캐시를 사용하여 대규모 벡터 검색의 메모리 사용량을 줄입니다.",
+ "keywords": [
+ "IVF On-Disk",
+ "Apache Doris 벡터 인덱스",
+ "ANN 인덱스",
+ "ivf_on_disk",
+ "벡터 검색 메모리 최적화",
+ "ivf_nprobe",
+ "ann_index_ivf_list_cache_limit",
+ "대규모 벡터 검색"
+ ]
+}
+---
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+# Apache Doris의 IVF On-Disk {#ivf-on-disk-in-apache-doris}
+
+<!-- Knowledge type: Capability definition + Configuration parameters + Performance reference -->
+<!-- Applicable scenarios: Large-scale vector retrieval / Constrained memory budget / ANN index selection -->
+
+`ivf_on_disk`는 Apache Doris가 대규모 벡터 검색(ANN) 시나리오를 위해 제공하는 인덱스 유형입니다. IVF 역색인 목록의 주요 부분을 디스크에 저장하고 전용 캐시를 통해 자주 사용하는 데이터를 필요할 때 불러오므로, IVF 검색 기능을 유지하면서 상주 메모리 사용량을 크게 줄일 수 있습니다.
+
+## 빠른 탐색 {#quick-navigation}
+
+- `ivf_on_disk`가 필요한 이유는 [배경 및 목표](#background-and-goals)를 참고하세요.
+- 테이블을 생성할 때 바로 사용하려면 [인덱스 DDL](#1-index-ddl)과 [쿼리 매개변수](#2-query-parameters)를 참고하세요.
+- 메모리 사용량을 제어하려면 [BE 캐시 구성](#3-be-cache-configuration)과 [튜닝 권장 사항](#tuning-recommendations)을 참고하세요.
+- 실제 환경에서의 동작을 평가하려면 [성능 참고 데이터](#performance-reference-data)를 참고하세요.
+- 메모리 내 IVF와 비교하려면 [IVF와 비교](#comparison-with-ivf)를 참고하세요.
+
+## 배경 및 목표 {#background-and-goals}
+
+<!-- Knowledge type: Capability definition -->
+
+벡터 수가 수천만 개 이상에 이르면, IVF를 전부 메모리에 저장할 때 인덱스의 메모리 비용이 급격히 증가하여 리소스 병목이 발생합니다. `ivf_on_disk`의 설계 목표는 다음과 같습니다.
+
+- IVF의 매개변수 모델과 검색 의미 체계(`nlist` / `nprobe`)를 유지합니다.
+- "전체를 메모리에 상주시켜야 하는" 방식에서 "디스크 + 전용 캐시" 방식으로 전환합니다.
+- 기존 ANN SQL 사용 방식과 운영 관행을 계속 사용할 수 있도록 합니다.
+
+즉, `ivf_on_disk`는 주로 **메모리 예산이 제한되어 있지만 ANN 가속이 필요한** 프로덕션 시나리오를 위한 기능입니다.
+
+## IVF와 비교 {#comparison-with-ivf}
+
+<!-- Knowledge type: Architecture selection decision -->
+
+다음 표를 통해 `ivf_on_disk`를 `ivf`보다 우선하여 선택해야 하는 상황을 빠르게 판단할 수 있습니다.
+
+| 비교 항목 | `ivf`(메모리) | `ivf_on_disk`(디스크 + 캐시) |
+| -------------------- | ------------------- | ------------------------------------------- |
+| 역색인 목록 저장 방식 | 전체를 메모리에 저장 | 주로 디스크에 저장하고 캐시를 통해 필요할 때 불러옴 |
+| 메모리 사용량 | 높음, 데이터 양에 비례하여 증가 | 훨씬 낮음, 캐시 한도로 상한을 명시적으로 설정할 수 있음 |
+| 쿼리 지연 시간 | 가장 낮음 | 메모리 내 IVF보다 약간 높으며, 캐시 적중률의 영향을 받음 |
+| 매개변수 모델 | `nlist` / `nprobe` | 동일 |
+| 쿼리 함수 | ANN 쿼리 함수 | 동일 |
+| 적용 규모 | 소규모~중규모 | 수천만 개 이상 |
+| 마이그레이션 비용 | - | 낮음, `index_type`만 변경하면 됨 |
+
+## 사용자 인터페이스 {#user-interface}
+
+### 1) 인덱스 DDL {#1-index-ddl}
+
+<!-- Knowledge type: Operational steps -->
+
+`index_type="ivf_on_disk"`를 지정하여 ANN 인덱스를 생성합니다.
+
+```sql
+CREATE TABLE vec_tbl (
+ id BIGINT NOT NULL,
+ embedding ARRAY<FLOAT> NOT NULL,
+ INDEX idx_emb (embedding) USING ANN PROPERTIES (
+ "index_type" = "ivf_on_disk",
+ "metric_type" = "l2_distance",
+ "dim" = "768",
+ "nlist" = "1024"
+ )
+) ENGINE=OLAP
+DUPLICATE KEY(id)
+DISTRIBUTED BY HASH(id) BUCKETS 8
+PROPERTIES ("replication_num" = "1");
+```
+
+주요 사항:
+
+- `ivf`와 `ivf_on_disk` 모두 `nlist`를 명시적으로 지정해야 합니다.
+- `metric_type`은 `l2_distance`와 `inner_product`를 지원합니다.
+- 쿼리 함수는 기존과 동일하게 `l2_distance_approximate` / `inner_product_approximate`를 사용합니다.
+
+### 2) 쿼리 매개변수 {#2-query-parameters}
+
+<!-- Knowledge type: Configuration parameters -->
+
+`ivf_nprobe`는 여전히 IVF 계열에서 쿼리 단계의 가장 중요한 매개변수입니다.
+
+```sql
+SET ivf_nprobe = 64;
+```
+
+일반적으로 `nprobe` 값이 클수록 재현율이 높아지지만, 쿼리 지연 시간도 그에 따라 증가합니다.
+
+### 3) BE 캐시 구성 {#3-be-cache-configuration}
+
+<!-- Knowledge type: Configuration parameters -->
+
+`ivf_on_disk`는 IVF 역색인 목록을 위한 전용 캐시를 도입합니다. 관련 BE 구성은 다음과 같습니다.
+
+| 구성 항목 | 기본값 | 설명 |
+| ----------------------------------------------- | ------- | ---------------------------------------------------------- |
+| `ann_index_ivf_list_cache_limit` | `70%` | 캐시 상한입니다. 백분율은 머신 전체의 물리 메모리가 아니라 BE 프로세스에서 사용할 수 있는 메모리(`mem_limit`으로 제한됨)를 기준으로 합니다. |
+| `ann_index_ivf_list_cache_stale_sweep_time_sec` | `3600` | 캐시에서 오래된 항목을 정리하는 주기이며, 단위는 초입니다. |
+
+## 관측성 {#observability}
+
+<!-- Knowledge type: Monitoring metrics -->
+<!-- Applicable scenarios: Troubleshooting / Performance tuning -->
+
+`ivf_on_disk`의 성능 병목을 파악할 수 있도록 전용 Profile 카운터와 BE 메트릭을 제공합니다. 이를 통해 현재 캐시 크기가 적절한지, 지연 시간이 주로 디스크 페이지 폴트에서 발생하는지 또는 검색 연산 자체에서 발생하는지 확인할 수 있습니다.
+
+주요 Profile 필드:
+
+- `AnnIvfOnDiskLoadCosts`
+- `AnnIvfOnDiskCacheHitCnt`
+- `AnnIvfOnDiskCacheMissCnt`
+
+주요 BE 메트릭:
+
+- `ann_ivf_on_disk_fetch_page_costs_ms`
+- `ann_ivf_on_disk_fetch_page_cnt`
+- `ann_ivf_on_disk_search_costs_ms`
+- `ann_ivf_on_disk_search_cnt`
+- `ann_ivf_on_disk_cache_hit_cnt`
+- `ann_ivf_on_disk_cache_miss_cnt`
+
+## 사용 시 유의 사항 {#usage-notes}
+
+<!-- Knowledge type: Usage constraints -->
+
+- `ivf_on_disk`에는 기존 ANN 인덱스의 주요 사용 제약 사항(예: 벡터 컬럼 타입 및 인덱스 매개변수의 유효성)이 동일하게 적용됩니다.
+- 학습 품질과 검색 효과는 여전히 데이터 규모와 매개변수 조합(`nlist`, `ivf_nprobe`)에 따라 달라집니다.
+- `ivf_on_disk`는 Stream Load와 같은 일반적인 데이터 적재 경로를 지원합니다. 프로덕션 환경에 적용하기 전에 실제 업무 데이터로 검증하는 것이 좋습니다.
+
+## 성능 참고 데이터 {#performance-reference-data}
+
+<!-- Knowledge type: Performance reference -->
+
+다음 표는 캐시가 포괄하는 데이터 비율, 메모리 사용량, 지연 시간 사이의 실질적인 상충 관계를 보여 주는 참고용 벤치마크 결과입니다.
+
+| 시나리오 | 메모리 사용량 (GB) | AnnIndexIVFListCache 적중률 | 최대 QPS | Recall@100 | 평균 지연 시간 (s) | P99 지연 시간 (s) | P95 지연 시간 (s) |
+| ---------------------- | ----------------: | -----------------------------: | ------: | ---------: | ------------------: | --------------: | --------------: |
+| Brute Force(인덱스 없음) | - | - | 0.2922 | 0.0000 | 292.5394 | 307.9490 | 307.9442 |
+| 메모리 내 IVF | 32.0 | 100% | 71.8535 | 0.9598 | 0.4167 | 0.5623 | 0.5151 |
+| OnDisk 캐시 100% | 32.0 | 100% | 72.3649 | 0.9599 | 0.8274 | 1.1236 | 1.0395 |
+| OnDisk 캐시 79% | 22.0 | 70% | 45.0266 | 0.9599 | 1.9900 | 4.4059 | 3.3568 |
+| OnDisk 캐시 60% | 16.7 | 55% | 38.3141 | 0.9599 | 2.3281 | 4.0063 | 3.5542 |
+
+데이터 해석 지침:
+
+- 재현율이 거의 동일할 때(약 0.96), 캐시를 줄이면 메모리 사용량이 크게 감소하지만 꼬리 지연 시간이 증가합니다.
+- 캐시가 포괄하는 데이터 비율이 100%에 가까워지면 `ivf_on_disk`는 메모리 내 IVF에 근접한 재현율을 유지할 수 있지만, 지연 시간은 다소 증가합니다.
+- 프로덕션 환경에서는 적중률 메트릭을 지속적으로 모니터링하고, 이를 바탕으로 `ann_index_ivf_list_cache_limit`를 조정하는 것이 좋습니다.
+
+## 튜닝 권장 사항 {#tuning-recommendations}
+
+<!-- Knowledge type: Operational steps -->
+<!-- Applicable scenarios: Performance tuning -->
+
+다음 단계에 따라 반복적으로 튜닝하는 것을 권장합니다.
+
+1. 먼저 `nlist` / `ivf_nprobe`에 `ivf`에서 기준으로 사용하던 매개변수 값을 그대로 적용하여 테스트를 시작합니다.
+2. 메모리 예산에 맞게 `ann_index_ivf_list_cache_limit`를 설정한 다음, 적중률과 지연 시간의 변화를 관찰합니다.
+3. 재현율은 안정적이지만 지연 시간 변동이 크다면, 우선 캐시 비율을 높인 뒤 적중률을 다시 테스트합니다.
+4. 캐시 비율을 변경한 후에는 `ivf_nprobe`도 함께 다시 조정하여 재현율과 지연 시간의 균형을 맞춥니다.
+
+## 자주 묻는 질문 {#faq}
+
+<!-- Knowledge type: Frequently asked questions -->
+
+**Q1: `ivf_on_disk`와 `ivf`의 SQL 사용 방식에 차이가 있나요?**
+
+차이가 없습니다. 인덱스를 생성할 때 `index_type`을 `ivf_on_disk`로 변경하기만 하면 됩니다. 쿼리 함수(`l2_distance_approximate` / `inner_product_approximate`)와 매개변수(`ivf_nprobe`)는 동일합니다.
+
+**Q2: `ann_index_ivf_list_cache_limit`의 백분율은 무엇을 기준으로 하나요?**
+
+머신 전체의 물리 메모리가 아니라 BE 프로세스에서 사용할 수 있는 메모리(`mem_limit`으로 제한됨)를 기준으로 합니다. BE 메모리 상한을 기준으로 캐시 비율을 계획하세요.
+
+**Q3: 어느 정도의 적중률이 적절한가요?**
+
+업무에서 허용할 수 있는 꼬리 지연 시간에 따라 달라집니다. 참고 데이터에 따르면 적중률이 100%일 때 지연 시간이 가장 안정적입니다. 적중률이 55%-70%로 떨어지면 메모리 사용량은 크게 줄어들지만, P99 지연 시간은 수 초 수준까지 증가할 수 있습니다. 관측성 메트릭을 기준으로 지속적으로 튜닝하세요.
+
+**Q4: `ivf_on_disk`를 `ivf`보다 우선하여 선택해야 하는 경우는 언제인가요?**
+
+벡터 규모가 크고(수천만 개 이상), 메모리 예산이 빠듯하며, ANN 가속이 필요한 경우에는 `ivf_on_disk`를 우선 선택하세요. 지연 시간에 매우 민감하고 메모리가 충분한 경우에는 `ivf`를 선택하세요.
+
+## 관련 문서 {#related-documents}
+
+- [벡터 인덱스 개요](./overview.md)
+- [IVF 인덱스](./ivf.md)
+- [HNSW 인덱스](./hnsw.md)
+- [벡터 인덱스 관리](./index-management.md)
+- [대규모 벡터 검색 성능](./performance-large-scale.md)
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/vector-index/ivf.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/vector-index/ivf.md
new file mode 100644
index 00000000000..f24f6126780
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/vector-index/ivf.md
@@ -0,0 +1,459 @@
+---
+{
+ "title": "IVF",
+ "language": "ko",
+ "description": "Apache Doris에서 IVF 인덱스로 대규모 벡터 검색을 가속하는 방법: 원리, 매개변수 튜닝, 재현율 최적화, 성능 벤치마크.",
+ "keywords": [
+ "IVF",
+ "Inverted File Index",
+ "벡터 인덱스",
+ "ANN 인덱스",
+ "근사 최근접 이웃 검색",
+ "Apache Doris 벡터 검색",
+ "nlist",
+ "nprobe",
+ "재현율 최적화",
+ "벡터 데이터베이스"
+ ]
+}
+---
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+# IVF: IVF 인덱스로 Apache Doris의 벡터 검색 가속하기 {#ivf-accelerating-vector-search-in-apache-doris-with-ivf-indexes}
+
+<!-- Knowledge type: Feature concept + Operation steps + Configuration parameters -->
+<!-- Applicable scenarios: Vector index selection / Index building / Recall and performance tuning -->
+
+**한 문장 정의**: IVF(Inverted File Index)는 클러스터링으로 벡터 공간을 분할하여 검색 범위를 좁히는 근사 최근접 이웃(ANN) 인덱스입니다. Apache Doris 4.x부터 기본 지원됩니다.
+
+이 문서에서는 다음 질문에 답합니다.
+
+- IVF 인덱스란 무엇이며, 벡터 검색을 어떻게 가속하나요?
+- Apache Doris에서 IVF 인덱스를 생성, 구축, 삭제하려면 어떻게 해야 하나요?
+- 재현율과 성능의 균형을 맞추려면 `nlist`, `nprobe` 등의 주요 매개변수를 어떻게 선택해야 하나요?
+- 재현율에 영향을 주는 요인은 무엇이며, 성능 저하를 어떻게 방지할 수 있나요?
+
+## 빠른 탐색 {#quick-navigation}
+
+| 목표 | 바로 가기 |
+| --- | --- |
+| IVF의 기본 원리 이해 | [IVF 인덱스란](#what-is-the-ivf-index) |
+| IVF 인덱스 생성 및 사용 | [Apache Doris에서 IVF 사용하기](#using-ivf-in-apache-doris) |
+| 재현율 튜닝 | [재현율 최적화](#recall-optimization) |
+| 쿼리 성능 문제 해결 | [쿼리 성능](#query-performance) |
+| 성능 벤치마크 재현 | [벤치마크](#benchmark) |
+| 자주 묻는 질문 | [자주 묻는 질문](#faq) |
+
+---
+
+## IVF 인덱스란 {#what-is-the-ivf-index}
+
+<!-- Knowledge type: Concept explanation -->
+
+### 역색인에서 벡터 역색인으로 {#from-inverted-indexes-to-vector-inverted-indexes}
+
+IVF(Inverted File)라는 용어는 정보 검색 분야에서 유래했습니다. 텍스트 검색을 예로 들어 보겠습니다.
+
+- **정방향 인덱스**: 각 문서가 단어 목록을 관리합니다. 쿼리는 모든 문서를 스캔해야 합니다.
+
+ | 문서 | 단어 |
+ | --- | --- |
+ | 문서 1 | the, cow, says, moo |
+ | 문서 2 | the, cat, and, the, hat |
+ | 문서 3 | the, dish, ran, away, with, the, spoon |
+
+- **역색인**: 각 단어가 "이 단어를 포함하는 문서" 목록을 관리합니다. 쿼리는 관련 목록만 스캔하면 됩니다.
+
+ | 단어 | 문서 |
+ | --- | --- |
+ | the | 문서 1, 문서 3, 문서 4, 문서 5, 문서 7 |
+ | cow | 문서 2, 문서 3, 문서 4 |
+ | says | 문서 5 |
+ | moo | 문서 7 |
+
+오늘날 텍스트는 주로 벡터 임베딩으로 표현됩니다. IVF는 역색인의 개념을 차용합니다. 클러스터의 중심점이 "사전" 역할을 하고, 각 중심점은 "이 클러스터에 속하는 벡터" 목록을 관리합니다. 쿼리는 선택된 소수의 클러스터만 살펴보면 됩니다.
+
+### IVF가 벡터 검색을 가속하는 원리 {#why-ivf-accelerates-vector-search}
+
+데이터셋이 수백만 개 또는 수십억 개의 벡터로 늘어나면 정확한 kNN 검색, 즉 쿼리 벡터와 데이터베이스의 모든 벡터 사이의 거리를 계산하는 작업은 대규모 행렬 곱셈에 해당하며, 계산 비용이 감당하기 어려울 정도로 커집니다.
+
+근사 최근접 이웃(ANN) 검색은 정확도를 약간 양보하는 대신 속도를 열 배 수준으로 높입니다. IVF는 업계에서 가장 널리 사용되는 효과적인 ANN 방법 중 하나입니다. 핵심 아이디어는 **"분할 정복"**입니다.
+
+1. 전체 벡터 데이터셋을 여러 클러스터로 분할하고, 각 클러스터를 **중심점**으로 표현합니다.
+2. 쿼리 시점에 먼저 쿼리 벡터와 중심점이 가장 가까운 소수의 클러스터를 찾은 다음, 해당 클러스터 내부만 검색하고 나머지 데이터는 건너뜁니다.
+
+
+
+---
+
+## Apache Doris에서 IVF 사용하기 {#using-ivf-in-apache-doris}
+
+<!-- Knowledge type: Operation steps -->
+<!-- Applicable scenarios: Table creation / Index building / Index management -->
+
+Apache Doris는 4.x 버전부터 IVF 기반 ANN 인덱스를 지원합니다. 인덱스 유형은 `ANN`으로 고정되며, `index_type=ivf`를 지정하여 IVF 알고리즘을 선택합니다.
+
+### 인덱스 구축 방식 {#index-building-approaches}
+
+ANN 인덱스를 생성하는 방법은 두 가지이며, 각각 적합한 사용 상황이 다릅니다.
+
+| 방식 | 구축 시점 | 장점 | 단점 | 적합한 상황 |
+| --- | --- | --- | --- | --- |
+| 테이블 생성 시 인덱스 정의 | 데이터 적재 중 동기적으로 구축 | 데이터가 기록되는 즉시 쿼리 가속 가능 | 쓰기 속도 저하, Compaction 시 인덱스 재구축으로 리소스 낭비 가능 | 인덱스 매개변수가 이미 확정된 운영 환경 |
+| `CREATE INDEX` + `BUILD INDEX` | 데이터 적재 후 비동기적으로 구축 | 데이터 적재에 영향을 주지 않으며 매개변수 튜닝이 편리함 | 구축 중에는 가속 불가 | 매개변수 튜닝 단계, 초대형 테이블 초기화 |
+
+### 방식 1: 테이블 생성 시 인덱스 정의 {#approach-1-define-the-index-at-table-creation}
+
+```sql
+CREATE TABLE sift_1M (
+ id int NOT NULL,
+ embedding array<float> NOT NULL COMMENT "",
+ INDEX ann_index (embedding) USING ANN PROPERTIES(
+ "index_type"="ivf",
+ "metric_type"="l2_distance",
+ "dim"="128",
+ "nlist"="1024"
+ )
+) ENGINE=OLAP
+DUPLICATE KEY(id) COMMENT "OLAP"
+DISTRIBUTED BY HASH(id) BUCKETS 1
+PROPERTIES (
+ "replication_num" = "1"
+);
+
+INSERT INTO sift_1M
+SELECT *
+FROM S3(
+ "uri" = "https://selectdb-customers-tools-bj.oss-cn-beijing.aliyuncs.com/sift_database.tsv",
+ "format" = "csv");
+```
+
+### 방식 2: CREATE INDEX + BUILD INDEX {#approach-2-create-index--build-index}
+
+**1단계**: 인덱스 없이 테이블을 생성하고 데이터를 적재합니다.
+
+```sql
+CREATE TABLE sift_1M (
+ id int NOT NULL,
+ embedding array<float> NOT NULL COMMENT ""
+) ENGINE=OLAP
+DUPLICATE KEY(id) COMMENT "OLAP"
+DISTRIBUTED BY HASH(id) BUCKETS 1
+PROPERTIES (
+ "replication_num" = "1"
+);
+
+INSERT INTO sift_1M
+SELECT *
+FROM S3(
+ "uri" = "https://selectdb-customers-tools-bj.oss-cn-beijing.aliyuncs.com/sift_database.tsv",
+ "format" = "csv");
+```
+
+**2단계**: `CREATE INDEX`를 실행하여 인덱스 정의를 추가합니다. 이 시점에는 인덱스 메타데이터만 등록되며, 기존 데이터에 대한 인덱스는 아직 구축되지 않습니다.
+
+```sql
+CREATE INDEX idx_test_ann ON sift_1M (`embedding`) USING ANN PROPERTIES (
+ "index_type"="ivf",
+ "metric_type"="l2_distance",
+ "dim"="128",
+ "nlist"="1024"
+);
+
+SHOW DATA ALL FROM sift_1M;
+```
+
+예상 출력(`LocalIndexSize`는 여전히 0):
+
+```text
++-----------+-----------+--------------+----------+----------------+---------------+----------------+-----------------+----------------+-----------------+
+| TableName | IndexName | ReplicaCount | RowCount | LocalTotalSize | LocalDataSize | LocalIndexSize | RemoteTotalSize | RemoteDataSize | RemoteIndexSize |
++-----------+-----------+--------------+----------+----------------+---------------+----------------+-----------------+----------------+-----------------+
+| sift_1M | sift_1M | 10 | 1000000 | 170.093 MB | 170.093 MB | 0.000 | 0.000 | 0.000 | 0.000 |
+| | Total | 10 | | 170.093 MB | 170.093 MB | 0.000 | 0.000 | 0.000 | 0.000 |
++-----------+-----------+--------------+----------+----------------+---------------+----------------+-----------------+----------------+-----------------+
+```
+
+**3단계**: `BUILD INDEX`를 실행하여 기존 데이터에 인덱스를 구축합니다. 이 작업은 비동기적으로 실행됩니다.
+
+```sql
+BUILD INDEX idx_test_ann ON sift_1M;
+```
+
+**4단계**: `SHOW BUILD INDEX`로 작업 상태를 확인합니다.
+
+```sql
+SHOW BUILD INDEX WHERE TableName = "sift_1M";
+```
+
+작업이 완료되면 데이터 크기를 다시 확인합니다. 인덱스 크기(`LocalIndexSize`)가 생성되어 있습니다.
+
+```text
++---------------+-----------+---------------+-----------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+-------------------------+---------------+----------+------+----------+
+| JobId | TableName | PartitionName | AlterInvertedIndexes | CreateTime | FinishTime | TransactionId | State | Msg | Progress |
++---------------+-----------+---------------+-----------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+-------------------------+---------------+----------+------+----------+
+| 1764392359610 | sift_1M | sift_1M | [ADD INDEX idx_test_ann (`embedding`) USING ANN PROPERTIES("dim" = "128", "index_type" = "ivf", "metric_type" = "l2_distance", "nlist" = "1024")], | 2025-12-01 14:18:22.360 | 2025-12-01 14:18:27.885 | 5036 | FINISHED | | NULL |
++---------------+-----------+---------------+-----------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+-------------------------+---------------+----------+------+----------+
+
+mysql> SHOW DATA ALL FROM sift_1M;
++-----------+-----------+--------------+----------+----------------+---------------+----------------+-----------------+----------------+-----------------+
+| TableName | IndexName | ReplicaCount | RowCount | LocalTotalSize | LocalDataSize | LocalIndexSize | RemoteTotalSize | RemoteDataSize | RemoteIndexSize |
++-----------+-----------+--------------+----------+----------------+---------------+----------------+-----------------+----------------+-----------------+
+| sift_1M | sift_1M | 10 | 1000000 | 671.084 MB | 170.093 MB | 500.991 MB | 0.000 | 0.000 | 0.000 |
+| | Total | 10 | | 671.084 MB | 170.093 MB | 500.991 MB | 0.000 | 0.000 | 0.000 |
++-----------+-----------+--------------+----------+----------------+---------------+----------------+-----------------+----------------+-----------------+
+```
+
+### 인덱스 삭제 {#dropping-the-index}
+
+매개변수를 튜닝할 때는 재현율을 확보하기 위해 다양한 매개변수 조합을 테스트해야 하는 경우가 많습니다. `DROP INDEX`를 사용하면 인덱스를 유연하게 관리할 수 있습니다.
+
+```sql
+ALTER TABLE sift_1M DROP INDEX idx_test_ann;
+```
+
+### 벡터 쿼리 실행 {#running-vector-queries}
+
+ANN 인덱스는 **TopN 검색**과 **범위 검색**을 모두 가속합니다.
+
+**운영 환경 권장 사항**: 고차원 벡터를 문자열로 표현하면 SQL 파싱 과정에서 추가 오버헤드가 발생하므로, 동시 요청이 많은 환경에서는 원시 SQL을 직접 사용하지 않는 것이 좋습니다. 다음 두 가지 최적화 방법을 권장합니다.
+
+1. Prepare Statement를 사용하여 SQL을 미리 파싱합니다.
+2. 공식 Doris 벡터 검색 [Python 라이브러리](https://github.com/uchenily/doris_vector_search)를 사용합니다. 이 라이브러리는 Prepare Statement 호출을 감싸고 쿼리 결과를 pandas DataFrame으로 바로 변환하므로 AI 애플리케이션 개발에 편리합니다.
+
+예제 코드:
+
+```python
+from doris_vector_search import DorisVectorClient, AuthOptions
+
+auth = AuthOptions(
+ host="127.0.0.1",
+ query_port=9030,
+ user="root",
+ password="",
+)
+
+client = DorisVectorClient(database="test", auth_options=auth)
+
+tbl = client.open_table("sift_1M")
+
+query = [0.1] * 128 # Example 128-dimensional vector
+
+# SELECT id FROM sift_1M ORDER BY l2_distance_approximate(embedding, query) LIMIT 10;
+result = tbl.search(query, metric_type="l2_distance").limit(10).select(["id"]).to_pandas()
+
+print(result)
+```
+
+예상 출력:
+
+```text
+ id
+0 123911
+1 926855
+2 123739
+3 73311
+4 124493
+5 153178
+6 126138
+7 123740
+8 125741
+9 124048
+```
+
+---
+
+## 재현율 최적화 {#recall-optimization}
+
+<!-- Knowledge type: Performance tuning -->
+<!-- Applicable scenarios: Index parameter tuning / Recall troubleshooting -->
+
+벡터 검색의 핵심 지표는 재현율입니다. **성능 수치는 재현율이 허용 가능한 수준일 때만 의미가 있습니다.** 재현율에 영향을 주는 주요 요인은 다음과 같습니다.
+
+1. IVF 인덱스 매개변수(`nlist`)와 쿼리 매개변수(`nprobe`)
+2. 인덱스의 벡터 양자화
+3. Segment의 크기와 개수
+
+이 절에서는 1번과 3번 항목을 다룹니다. 벡터 양자화는 다른 문서에서 설명합니다.
+
+### 인덱스 하이퍼파라미터: nlist와 nprobe {#index-hyperparameters-nlist-and-nprobe}
+
+IVF는 인덱스 구축 시점과 쿼리 시점에 주요 매개변수를 사용합니다.
+
+**인덱스 구축 단계**:
+
+1. **클러스터링**: k-means와 같은 클러스터링 알고리즘으로 벡터를 `nlist`개의 클러스터로 분할한 다음, 각 클러스터의 중심점을 계산하여 저장합니다.
+2. **벡터 할당**: 각 벡터를 중심점이 가장 가까운 클러스터에 할당하고, 해당 역색인 목록에 벡터를 추가합니다.
+
+**쿼리 단계**:
+
+1. **클러스터 선택**: 쿼리 벡터에서 모든 `nlist`개 중심점까지의 거리를 계산하고 가장 가까운 `nprobe`개의 클러스터를 선택합니다.
+2. **클러스터 내부 전수 검색**: 선택한 `nprobe`개의 클러스터 내부에서 벡터를 하나씩 비교하여 최근접 이웃을 찾습니다.
+
+| 매개변수 | 용도 | 영향 | Doris 기본값 |
+| --- | --- | --- | --- |
+| `nlist` | 클러스터(역색인 목록) 개수 | 값이 클수록 더 세밀하게 분할되어 검색이 빨라지지만, 클러스터링 비용이 증가하고 이웃이 서로 다른 클러스터에 흩어질 가능성이 커짐 | 1024 |
+| `nprobe` | 쿼리 시 탐색할 클러스터 개수 | 값이 클수록 재현율과 지연 시간이 높아짐. 값이 작을수록 빠르지만 결과를 놓칠 가능성이 커짐 | 64 |
+
+**SIFT_1M 데이터셋의 측정 결과**:
+
+| nlist | nprobe | recall@100 |
+| --- | --- | --- |
+| 1024 | 64 | 0.9542 |
+| 1024 | 32 | 0.9034 |
+| 1024 | 16 | 0.8299 |
+| 1024 | 8 | 0.7337 |
+| 512 | 32 | 0.9384 |
+| 512 | 16 | 0.8763 |
+| 512 | 8 | 0.7869 |
+
+### 실무에서의 하이퍼파라미터 선택 {#hyperparameter-selection-in-practice}
+
+정확한 최적 매개변수를 미리 결정할 수는 없지만, 다음과 같이 체계적으로 선택할 수 있습니다.
+
+1. 인덱스 없이 벡터 컬럼을 2~3개 포함하는 임시 테이블 `table_multi_index`를 생성합니다.
+2. Stream Load나 다른 방법으로 이 테이블에 데이터를 적재합니다.
+3. 각 벡터 컬럼에 서로 다른 매개변수로 `CREATE INDEX`와 `BUILD INDEX`를 실행합니다.
+4. 각 컬럼의 재현율을 비교하여 가장 적합한 매개변수 조합을 선택합니다.
+
+예제:
+
+```sql
+ALTER TABLE tbl DROP INDEX idx_embedding;
+CREATE INDEX idx_embedding ON tbl (`embedding`) USING ANN PROPERTIES (
+ "index_type"="ivf",
+ "metric_type"="inner_product",
+ "dim"="768",
+ "nlist"="1024"
+);
+BUILD INDEX idx_embedding ON tbl;
+```
+
+### 인덱스가 포괄하는 행 수 {#number-of-rows-covered-by-the-index}
+
+Doris 내부 테이블의 데이터는 다음 계층으로 구성됩니다.
+
+- **Table**에서 **Tablet**으로: 버킷 키에 따라 N개의 **Tablet**에 균등하게 분산됩니다. Tablet은 데이터 마이그레이션과 리밸런싱의 기본 단위입니다.
+- **Tablet**에서 **Rowset**으로: 데이터 적재 또는 Compaction이 수행될 때마다 새로운 **Rowset**이 추가됩니다. Rowset은 버전 관리 단위입니다.
+- **Rowset**에서 **Segment**로: 실제 데이터는 **Segment** 파일에 저장됩니다.
+
+역색인과 마찬가지로 벡터 인덱스도 Segment 단위로 동작합니다. Segment 크기는 BE 설정 항목인 `write_buffer_size`와 `vertical_compaction_max_segment_size`로 제어합니다. 데이터 적재 또는 Compaction 중에 memtable이 일정 크기까지 쌓이면 Segment 파일로 플러시되며, 해당 Segment에 대한 벡터 인덱스가 구축됩니다. 인덱스 컬럼이 여러 개이면 인덱스도 여러 개 생성됩니다.
+
+각 IVF 인덱스 매개변수 조합이 효과적으로 포괄할 수 있는 데이터 양에는 한계가 있습니다. **Segment의 행 수가 임계값을 초과하면 재현율이 떨어집니다.**
+
+> 팁: `SHOW TABLETS FROM <table>`을 사용하여 테이블의 Compaction 상태를 확인합니다. 해당 URL을 열면 Segment 개수를 볼 수 있습니다.
+
+### Compaction이 재현율에 미치는 영향 {#effect-of-compaction-on-recall}
+
+Compaction은 여러 작은 Segment를 더 큰 Segment로 병합합니다. 이로 인해 작은 데이터 규모에 맞춰 튜닝한 인덱스 매개변수가 더 이상 효과적이지 않게 되어 재현율이 떨어집니다.
+
+**권장 사항**: `BUILD INDEX`를 실행하기 전에 FULL COMPACTION을 수행합니다. 완전히 병합된 Segment에 인덱스를 구축하면 다음 두 가지 이점이 있습니다.
+
+- 재현율이 안정적으로 유지됩니다.
+- 인덱스 구축으로 발생하는 쓰기 증폭이 줄어듭니다.
+
+---
+
+## 쿼리 성능 {#query-performance}
+
+<!-- Knowledge type: Performance tuning -->
+<!-- Applicable scenarios: Online query performance optimization / Memory capacity planning -->
+
+### 인덱스 파일의 콜드 로딩 {#cold-loading-of-index-files}
+
+Doris ANN 인덱스는 Meta의 오픈 소스 [faiss](https://github.com/facebookresearch/faiss)를 기반으로 구현되었습니다. **IVF 인덱스는 메모리에 완전히 적재되어야 쿼리를 가속할 수 있습니다.**
+
+권장 사항: 동시 요청이 많은 쿼리를 실행하기 전에 콜드 쿼리를 실행하여 관련된 모든 Segment 인덱스 파일이 메모리에 적재되었는지 확인합니다. 그렇지 않으면 첫 쿼리의 성능이 크게 저하됩니다.
+
+### 메모리 사용량과 성능 {#memory-footprint-and-performance}
+
+> **양자화 압축을 사용하지 않는 IVF 인덱스는 인덱싱하는 벡터 메모리의 약 1.02배를 차지합니다.**
+
+예를 들어, 차원이 128이고 행 수가 1M인 데이터셋의 IVF FLAT 인덱스 메모리 사용량은 대략 다음과 같습니다.
+
+```text
+128 * 4 * 1,000,000 * 1.02 ≈ 500 MB
+```
+
+참고 값:
+
+| dim | rows | 예상 메모리 사용량 |
+| --- | --- | --- |
+| 128 | 1M | 500 MB |
+| 768 | 1M | 2.9 GB |
+
+쿼리 성능을 보장하려면 BE에 전체 인덱스를 담을 수 있는 충분한 메모리가 있어야 합니다. 그렇지 않으면 인덱스 파일에 대한 잦은 IO로 인해 쿼리 성능이 크게 저하됩니다.
+
+---
+
+## 벤치마크 {#benchmark}
+
+<!-- Knowledge type: Performance benchmark -->
+<!-- Applicable scenarios: Performance reproduction / Selection evaluation -->
+
+**배포 권장 사항**: 벤치마크는 운영 환경을 모방해야 합니다. FE와 BE를 분리하여 배포하고, 클라이언트도 별도의 머신에서 실행합니다.
+
+**테스트 프레임워크**: [VectorDBBench](https://github.com/zilliztech/VectorDBBench).
+
+### Performance768D1M {#performance768d1m}
+
+벤치마크 명령어:
+
+```bash
+# load
+NUM_PER_BATCH=1000000 python3 -m vectordbbench doris --host 127.0.0.1 --port 9030 --case-type Performance768D1M --db-name Performance768D1M --stream-load-rows-per-batch 500000 --index-prop index_type=ivf,nlist=1024 --skip-search-serial --skip-search-concurrent
+
+# search
+NUM_PER_BATCH=1000000 python3 -m vectordbbench doris --host 127.0.0.1 --port 9030 --case-type Performance768D1M --db-name Performance768D1M --search-concurrent --search-serial --num-concurrency 10,40,80 --stream-load-rows-per-batch 500000 --index-prop index_type=ivf,nlist=1024 --session-var ivf_nprobe=64 --skip-load --skip-drop-old
+```
+
+---
+
+## 자주 묻는 질문 {#faq}
+
+<!-- Knowledge type: FAQ -->
+
+**Q1: IVF와 HNSW 중 무엇을 선택해야 하나요?**
+IVF는 메모리가 충분하고 구축 비용과 쿼리 지연 시간 사이의 균형을 맞춰야 하는 대규모 환경에 적합합니다. HNSW는 쿼리 지연 시간 면에서 유리하지만 메모리 사용량이 더 많습니다. 자세한 내용은 [HNSW 문서](./hnsw.md)를 참조하세요.
+
+**Q2: `BUILD INDEX` 이후에도 재현율이 낮은 이유는 무엇인가요?**
+일반적인 원인으로는 `nprobe`가 너무 낮게 설정된 경우, Segment가 너무 커서 인덱스가 충분히 포괄하지 못하는 경우, BUILD 전에 FULL COMPACTION을 실행하지 않은 경우가 있습니다. [재현율 최적화](#recall-optimization)를 참조하세요.
+
+**Q3: 동시 요청이 많은 쿼리를 실행하기 전에 콜드 쿼리를 실행하는 이유는 무엇인가요?**
+IVF 인덱스는 메모리에 완전히 적재되어야 쿼리를 가속할 수 있습니다. 콜드 쿼리는 디스크에서 메모리로 인덱스를 적재하여 캐시를 워밍업하므로, 첫 온라인 쿼리에서 발생하는 성능 저하를 방지합니다.
+
+**Q4: `nlist`의 기본값인 1024를 조정해야 하나요?**
+Doris의 기본값은 `nlist=1024`와 `nprobe=64`이며, 대부분의 중간 규모 데이터셋에 적합합니다. [실무에서의 하이퍼파라미터 선택](#hyperparameter-selection-in-practice)에 따라 실제 데이터 크기와 재현율 요구 사항에 맞게 조정하세요.
+
+**Q5: `DROP INDEX`를 실행하면 메모리가 즉시 해제되나요?**
+`DROP INDEX`는 인덱스 정의를 제거하며, 인덱스 파일은 이후에 정리됩니다. 매개변수를 튜닝할 때는 `CREATE INDEX` 및 `BUILD INDEX` 작업 흐름과 함께 사용하세요.
+
+---
+
+## 문제 해결 {#troubleshooting}
+
+<!-- Knowledge type: Troubleshooting -->
+
+| 증상 | 가능한 원인 | 해결 방법 |
+| --- | --- | --- |
+| 재현율이 예상보다 현저히 낮음 | `nprobe`가 너무 낮음 / Segment가 너무 큼 / FULL COMPACTION을 실행하지 않음 | `nprobe`를 높이고, BUILD 전에 FULL COMPACTION을 실행하며, `nlist`를 조정 |
+| 첫 쿼리의 지연 시간이 매우 길고 이후 쿼리는 정상임 | 인덱스가 아직 메모리에 적재되지 않음(콜드 로딩) | 동시 요청이 많은 쿼리를 실행하기 전에 콜드 쿼리로 워밍업 |
+| BE 메모리가 부족하고 쿼리 성능이 저하됨 | 전체 인덱스가 메모리에 상주하지 않아 IO가 자주 발생함 | BE 메모리를 늘리고, 메모리 사용량을 줄이기 위해 양자화 압축 사용을 고려 |
+| `BUILD INDEX`가 오랫동안 완료되지 않음 | 작업이 비동기적으로 실행되며 데이터 양이 많음 | `SHOW BUILD INDEX WHERE TableName = "<tbl>"`로 진행 상황 확인 |
+| 데이터 적재 속도가 느려짐 | 테이블 생성 시 인덱스가 동기적으로 구축됨 | `CREATE INDEX` + `BUILD INDEX` 방식으로 전환하여 비동기적으로 구축 |
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/vector-index/overview.md b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/vector-index/overview.md
new file mode 100644
index 00000000000..ce74a0df5f1
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/table-design/index/vector-index/overview.md
@@ -0,0 +1,610 @@
+---
+{
+ "title": "벡터 검색",
+ "sidebar_label": "개요",
+ "language": "ko",
+ "description": "Apache Doris ANN 벡터 인덱스 가이드: 테이블 생성, 쿼리, 양자화, 필터링, 성능 튜닝 및 코사인 유사도 구현.",
+ "keywords": [
+ "벡터 검색",
+ "ANN 인덱스",
+ "벡터 검색",
+ "근사 최근접 이웃",
+ "HNSW",
+ "IVF",
+ "벡터 양자화",
+ "RAG 검색",
+ "코사인 유사도",
+ "Faiss",
+ "Doris 벡터 데이터베이스"
+ ]
+}
+---
+
+<!-- Knowledge type: capability overview + operation guide + configuration parameters -->
+<!-- Applicable scenarios: RAG retrieval / vector similarity search / multimodal retrieval / performance tuning -->
+
+Apache Doris는 4.0 버전부터 ANN(Approximate Nearest Neighbor, 근사 최근접 이웃) 벡터 검색을 기본 지원합니다. Faiss 기반의 HNSW 및 IVF 인덱스를 통해 수십억 개의 벡터에서 밀리초 수준의 TopN 검색과 범위 검색을 제공합니다.
+
+## 활용 시나리오 {#applicable-scenarios}
+
+벡터 검색은 RAG(Retrieval-Augmented Generation, 검색 증강 생성)와 멀티모달 검색의 핵심 기능입니다. 대표적인 활용 사례는 다음과 같습니다.
+
+- **RAG 검색**: 대규모 지식 베이스에서 사용자 쿼리와 가장 관련성이 높은 Top-K 텍스트 조각을 검색하고, 이를 LLM 생성의 근거로 사용합니다. 이를 통해 환각 현상과 오래된 지식으로 인한 문제를 완화합니다.
+- **멀티모달 검색**: 이미지, 오디오, 비디오 등의 데이터를 벡터로 인코딩하여 의미적 유사도 쿼리를 수행합니다. 예를 들어 의료 질의응답에서는 진료 기록과 문헌을 검색하여 진단 제안을 돕습니다.
+- **추천 시스템**: 범위 검색을 사용하여 "유사하지만 동일하지는 않은" 후보 콘텐츠를 검색함으로써 추천의 다양성을 높입니다.
+- **이상 탐지**: 정상 패턴에서 벗어나는 데이터 포인트를 찾습니다.
+
+벡터 검색의 핵심은 동일한 방식으로 쿼리와 문서를 의미 벡터로 인코딩한 다음, 대규모 벡터 집합에서 쿼리와 가장 유사한 K개의 벡터를 찾는 것입니다.
+
+## 빠른 탐색 {#quick-navigation}
+
+| 시나리오 | 섹션 |
+|------|----------|
+| 벡터 인덱스 생성 방법 알아보기 | [근사 최근접 이웃 검색](#approximate-nearest-neighbor-search) |
+| 코사인 유사도 검색 구현하기 | [코사인 유사도 사용](#using-cosine-similarity) |
+| 거리 임계값으로 필터링하기 | [근사 범위 검색](#approximate-range-search) |
+| TopN과 범위 조건 결합하기 | [복합 검색](#compound-search) |
+| ANN 검색 전에 다른 컬럼으로 필터링하기 | [필터를 적용한 ANN 검색](#ann-search-with-filters) |
+| 쿼리 동작 매개변수 조정하기 | [쿼리 매개변수](#query-parameters) |
+| 메모리 절약 및 인덱스 크기 줄이기 | [벡터 양자화](#vector-quantization) |
+| QPS 향상 및 지연 시간 줄이기 | [성능 튜닝](#performance-tuning) |
+| Python SDK 사용하기 | [Python SDK](#python-sdk) |
+| 사용 제한 사항 알아보기 | [사용 제한 사항](#usage-limitations) |
+
+---
+
+## 근사 최근접 이웃 검색 {#approximate-nearest-neighbor-search}
+
+<!-- Knowledge type: operation steps + configuration parameters -->
+
+Doris는 새로운 데이터 타입을 도입하지 않습니다. 벡터는 고정 길이의 `Array<Float>`로 저장되며, 거리 기반 검색을 위한 Faiss 기반 ANN 인덱스 타입을 제공합니다.
+
+### 테이블 생성 예제 {#table-creation-example}
+
+널리 사용되는 [SIFT](http://corpus-texmex.irisa.fr/) 데이터셋을 예로 들어 보겠습니다.
+
+```sql
+CREATE TABLE sift_1M (
+ id int NOT NULL,
+ embedding array<float> NOT NULL COMMENT "",
+ INDEX ann_index (embedding) USING ANN PROPERTIES(
+ "index_type"="hnsw",
+ "metric_type"="l2_distance",
+ "dim"="128",
+ "quantizer"="flat"
+ )
+) ENGINE=OLAP
+DUPLICATE KEY(id) COMMENT "OLAP"
+DISTRIBUTED BY HASH(id) BUCKETS 1
+PROPERTIES (
+ "replication_num" = "1"
+);
+```
+
+각 핵심 매개변수의 의미는 다음과 같습니다.
+
+- `index_type`: 인덱스 알고리즘입니다. `hnsw`([Hierarchical Navigable Small World](https://en.wikipedia.org/wiki/Hierarchical_navigable_small_world)), `ivf`(역파일 인덱스), `ivf_on_disk`(역색인 목록을 디스크에 저장하고 캐시를 통해 제공하는 IVF 변형) 중에서 선택할 수 있습니다.
+- `metric_type`: 거리 척도입니다. `l2_distance`는 거리 함수로 L2 거리를 사용한다는 의미입니다.
+- `dim`: 벡터 차원입니다. `128`은 이 컬럼에 있는 각 벡터의 길이가 128이라는 의미입니다.
+- `quantizer`: 인코딩 방식입니다. `flat`은 각 차원의 값을 원본 float32 값으로 저장한다는 의미입니다.
+
+### 전체 인덱스 매개변수 {#full-index-parameters}
+
+| 매개변수 | 필수 여부 | 지원 값 / 선택 가능한 값 | 기본값 | 설명 |
+|------|----------|-------------|--------|------|
+| `index_type` | 예 | `hnsw`, `ivf`, `ivf_on_disk` | (없음) | ANN 인덱스 알고리즘을 지정합니다. 현재 HNSW, 메모리 내 IVF, IVF On-Disk를 지원합니다. |
+| `metric_type` | 예 | `l2_distance`, `inner_product` | (없음) | 벡터 유사도 / 거리 척도를 지정합니다. `l2_distance`는 유클리드 거리입니다. `inner_product`는 코사인 유사도 시나리오에 사용할 수 있지만, 먼저 벡터를 정규화해야 합니다. |
+| `dim` | 예 | 양의 정수 (> 0) | (없음) | 벡터 차원을 지정합니다. 이후 적재되는 모든 벡터의 차원이 같아야 하며, 그렇지 않으면 오류가 발생합니다. |
+| `nlist` | 아니요 | 양의 정수 | `1024` | IVF의 역색인 버킷 수입니다. `index_type=ivf` 또는 `ivf_on_disk`일 때 적용됩니다. 값이 클수록 일반적으로 재현율과 속도 사이의 균형을 개선할 수 있지만, 빌드 비용이 증가합니다. |
+| `max_degree` | 아니요 | 양의 정수 | `32` | HNSW 그래프에서 노드당 최대 이웃 수(M)입니다. 인덱스 메모리 사용량과 검색 성능에 영향을 줍니다. |
+| `ef_construction` | 아니요 | 양의 정수 | `40` | HNSW 구축 중 후보 큐의 크기(efConstruction)입니다. 값이 클수록 그래프 품질이 높아지지만 빌드 속도가 느려집니다. |
+| `quantizer` | 아니요 | `flat`, `sq8`, `sq4`, `pq` | `flat` | 벡터 인코딩 / 양자화 방식입니다. `flat`: 원본 저장. `sq8` / `sq4`: 스칼라 양자화(8 / 4비트). `pq`: 곱 양자화. |
+| `pq_m` | `quantizer=pq`일 때 필수 | 양의 정수 | (없음) | 원본 고차원 벡터를 분할할 하위 벡터의 수입니다. `dim`은 `pq_m`으로 나누어떨어져야 합니다. |
+| `pq_nbits` | `quantizer=pq`일 때 필수 | 양의 정수 | (없음) | 각 하위 벡터를 양자화하는 데 사용하는 비트 수로, 부분 공간의 코드북 크기(k = 2 ^ pq_nbits)를 결정합니다. Faiss에서는 일반적으로 이 값이 24 이하여야 합니다. |
+
+### 데이터 적재 {#data-loading}
+
+S3 TVF를 통해 SIFT 데이터셋을 적재합니다.
+
+```sql
+INSERT INTO sift_1M
+SELECT *
+FROM S3(
+ "uri" = "https://selectdb-customers-tools-bj.oss-cn-beijing.aliyuncs.com/sift_database.tsv",
+ "format" = "csv");
+
+select count(*) from sift_1M
+--------------
+
++----------+
+| count(*) |
++----------+
+| 1000000 |
++----------+
+```
+
+### 쿼리 예제 {#query-example}
+
+`l2_distance_approximate` / `inner_product_approximate`를 호출하면 ANN 인덱스 경로가 활성화됩니다.
+
+**호출 규칙:**
+
+- 함수 이름은 인덱스의 `metric_type`과 정확히 일치해야 합니다.
+ - `metric_type=l2_distance` → `l2_distance_approximate` 사용
+ - `metric_type=inner_product` → `inner_product_approximate` 사용
+- 정렬 순서:
+ - L2 거리는 오름차순을 사용합니다(`ORDER BY dist ASC`, 작을수록 더 가깝습니다).
+ - 내적은 내림차순을 사용합니다(`ORDER BY dist DESC`, 클수록 더 가깝습니다).
+
+```sql
+SELECT id,
+ l2_distance_approximate(
+ embedding,
+ [0,11,77,24,3,0,0,0,28,70,125,8,0,0,0,0,44,35,50,45,9,0,0,0,4,0,4,56,18,0,3,9,16,17,59,10,10,8,57,57,100,105,125,41,1,0,6,92,8,14,73,125,29,7,0,5,0,0,8,124,66,6,3,1,63,5,0,1,49,32,17,35,125,21,0,3,2,12,6,109,21,0,0,35,74,125,14,23,0,0,6,50,25,70,64,7,59,18,7,16,22,5,0,1,125,23,1,0,7,30,14,32,4,0,2,2,59,125,19,4,0,0,2,1,6,53,33,2]
+ ) AS distance
+FROM sift_1M
+ORDER BY distance
+LIMIT 10;
+--------------
+
++--------+----------+
+| id | distance |
++--------+----------+
+| 178811 | 210.1595 |
+| 177646 | 217.0161 |
+| 181997 | 218.5406 |
+| 181605 | 219.2989 |
+| 821938 | 221.7228 |
+| 807785 | 226.7135 |
+| 716433 | 227.3148 |
+| 358802 | 230.7314 |
+| 803100 | 230.9112 |
+| 866737 | 231.6441 |
++--------+----------+
+10 rows in set (0.02 sec)
+```
+
+정확한 검색 결과와 비교하려면 `l2_distance` / `inner_product`를 사용합니다(`_approximate` 접미사 제외). 이 예제에서 정확 검색에는 약 290 ms가 걸립니다. ANN 인덱스를 사용하면 쿼리 지연 시간이 약 290 ms에서 약 20 ms로 줄어듭니다.
+
+```
+10 rows in set (0.29 sec)
+```
+
+### 실행 방식 {#execution-mechanism}
+
+ANN 인덱스는 세그먼트 단위로 구축됩니다. 분산 테이블에서는 다음과 같이 동작합니다.
+
+1. 각 세그먼트가 로컬 TopN 결과를 반환합니다.
+2. TopN 연산자가 여러 태블릿과 세그먼트의 결과를 병합하여 전역 TopN을 생성합니다.
+
+---
+
+## 코사인 유사도 사용 {#using-cosine-similarity}
+
+<!-- Knowledge type: operation steps + design rationale -->
+<!-- Applicable scenarios: semantic similarity retrieval / recommendation recall -->
+
+Doris ANN 인덱스의 `metric_type`은 현재 `l2_distance`와 `inner_product`만 지원하며, **`cosine`을 직접 지원하지 않습니다**. 비즈니스에서 사용하는 척도가 코사인 유사도라면, 정규화를 통해 동등한 내적 계산으로 변환할 수 있습니다.
+
+### 절차 {#steps}
+
+1. **쓰기 전**: 벡터를 L2 정규화합니다(단위 길이로 정규화).
+2. **인덱스 생성 시**: `metric_type="inner_product"`를 사용합니다.
+3. **쿼리 시**: `inner_product_approximate(...)`를 사용하고 `ORDER BY ... DESC`로 정렬합니다.
+
+예제:
+
+```sql
+CREATE INDEX idx_emb_cosine ON your_table (embedding) USING ANN PROPERTIES (
+ "index_type"="hnsw",
+ "metric_type"="inner_product",
+ "dim"="768"
+);
+```
+
+### 동등성이 성립하는 원리 {#equivalence-rationale}
+
+- 코사인 유사도 공식: `cos(x, y) = (x · y) / (||x|| ||y||)`
+- 벡터를 L2 정규화하면(`||x|| = ||y|| = 1`): `cos(x, y) = x · y`
+
+따라서 단위 벡터 공간에서는 코사인 유사도를 최대화하는 것이 내적을 최대화하는 것과 같습니다. 정규화하지 않으면 내적과 코사인 유사도는 더 이상 동등하지 않습니다.
+
+---
+
+## 근사 범위 검색 {#approximate-range-search}
+
+<!-- Knowledge type: operation steps -->
+<!-- Applicable scenarios: recommendation diversity recall / anomaly detection -->
+
+벡터 검색에는 TopN 최근접 이웃 검색 외에도 **거리 임계값을 기준으로 하는 범위 검색**이라는 일반적인 쿼리 유형이 있습니다. 이 쿼리는 고정된 수의 행을 반환하지 않고, 대상 벡터와의 거리가 조건을 만족하는 모든 데이터 포인트를 찾습니다.
+
+대표적인 활용 사례:
+
+- 추천 시스템에서 다양성을 높이기 위해 "가깝지만 동일하지는 않은" 콘텐츠를 검색합니다.
+- 이상 탐지에서 정상 패턴에서 벗어나는 데이터 포인트를 찾습니다.
+
+예제: 대상 벡터와의 L2 거리가 300보다 큰 행의 수를 계산합니다.
+
+```sql
+SELECT count(*)
+FROM sift_1M
+WHERE l2_distance_approximate(
+ embedding,
+ [0,11,77,24,3,0,0,0,28,70,125,8,0,0,0,0,44,35,50,45,9,0,0,0,4,0,4,56,18,0,3,9,16,17,59,10,10,8,57,57,100,105,125,41,1,0,6,92,8,14,73,125,29,7,0,5,0,0,8,124,66,6,3,1,63,5,0,1,49,32,17,35,125,21,0,3,2,12,6,109,21,0,0,35,74,125,14,23,0,0,6,50,25,70,64,7,59,18,7,16,22,5,0,1,125,23,1,0,7,30,14,32,4,0,2,2,59,125,19,4,0,0,2,1,6,53,33,2])
+ > 300
+--------------
+
++----------+
+| count(*) |
++----------+
+| 999271 |
++----------+
+1 row in set (0.19 sec)
+```
+
+범위 검색도 ANN 인덱스로 가속됩니다. 시스템은 먼저 후보 벡터 집합을 빠르게 추린 다음, 정밀한 근사 거리를 계산하여 오버헤드를 크게 줄입니다. **현재 지원되는 범위 조건은 다음과 같습니다**: `>`, `>=`, `<`, `<=`.
+
+---
+
+## 복합 검색 {#compound-search}
+
+<!-- Knowledge type: operation steps + execution rationale -->
+
+복합 검색은 동일한 SQL 문에서 ANN TopN과 범위 필터링을 함께 수행하여 범위 제약 조건을 만족하는 TopN을 반환하는 방식입니다.
+
+```sql
+SELECT id,
+ l2_distance_approximate(
+ embedding, [0,11,77,24,3,0,0,0,28,70,125,8,0,0,0,0,44,35,50,45,9,0,0,0,4,0,4,56,18,0,3,9,16,17,59,10,10,8,57,57,100,105,125,41,1,0,6,92,8,14,73,125,29,7,0,5,0,0,8,124,66,6,3,1,63,5,0,1,49,32,17,35,125,21,0,3,2,12,6,109,21,0,0,35,74,125,14,23,0,0,6,50,25,70,64,7,59,18,7,16,22,5,0,1,125,23,1,0,7,30,14,32,4,0,2,2,59,125,19,4,0,0,2,1,6,53,33,2]) as dist
+FROM sift_1M
+WHERE l2_distance_approximate(
+ embedding, [0,11,77,24,3,0,0,0,28,70,125,8,0,0,0,0,44,35,50,45,9,0,0,0,4,0,4,56,18,0,3,9,16,17,59,10,10,8,57,57,100,105,125,41,1,0,6,92,8,14,73,125,29,7,0,5,0,0,8,124,66,6,3,1,63,5,0,1,49,32,17,35,125,21,0,3,2,12,6,109,21,0,0,35,74,125,14,23,0,0,6,50,25,70,64,7,59,18,7,16,22,5,0,1,125,23,1,0,7,30,14,32,4,0,2,2,59,125,19,4,0,0,2,1,6,53,33,2])
+ > 300
+ORDER BY dist limit 10
+--------------
+
++--------+----------+
+| id | dist |
++--------+----------+
+| 243590 | 300.005 |
+| 549298 | 300.0317 |
+| 429685 | 300.0533 |
+| 690172 | 300.0916 |
+| 123410 | 300.1333 |
+| 232540 | 300.1649 |
+| 547696 | 300.2066 |
+| 855437 | 300.2782 |
+| 589017 | 300.3048 |
+| 930696 | 300.3381 |
++--------+----------+
+10 rows in set (0.12 sec)
+```
+
+### 사전 필터링과 사후 필터링 비교 {#pre-filter-vs-post-filter}
+
+| 전략 | 의미 | 장점 | 단점 |
+|------|------|------|------|
+| 사전 필터링(Doris에서 사용) | 먼저 술어를 적용한 다음 남은 집합에서 TopN을 선택 | 높은 재현율 | 상대적으로 느림 |
+| 사후 필터링 | 먼저 TopN을 선택한 다음 필터링 | 빠름 | 재현율이 크게 떨어질 수 있음 |
+
+Doris에서는 복합 검색의 두 단계 모두 인덱스로 가속할 수 있습니다. 하지만 일부 시나리오에서는(예: 첫 번째 단계의 범위 필터 선택도가 매우 높은 경우) 두 단계 모두에 인덱스를 사용하면 재현율이 떨어질 수 있습니다. Doris는 술어 선택도와 인덱스 타입에 따라 두 단계 모두에 인덱스를 사용할지 **상황에 맞게** 결정합니다.
+
+---
+
+## 필터를 적용한 ANN 검색 {#ann-search-with-filters}
+
+<!-- Knowledge type: operation steps -->
+<!-- Applicable scenarios: multi-condition hybrid retrieval / full-text + vector joint queries -->
+
+필터를 적용한 ANN 검색은 ANN TopN을 수행하기 전에 다른 술어를 적용하고, 조건을 만족하는 TopN을 반환하는 방식입니다.
+
+다음 8차원 예제는 하이브리드 검색의 처리 과정을 보여 줍니다.
+
+```sql
+CREATE TABLE ann_with_fulltext (
+ id int NOT NULL,
+ embedding array<float> NOT NULL,
+ comment String NOT NULL,
+ value int NULL,
+ INDEX idx_comment(`comment`) USING INVERTED PROPERTIES("parser" = "english") COMMENT 'inverted index for comment',
+ INDEX ann_embedding(`embedding`) USING ANN PROPERTIES("index_type"="hnsw","metric_type"="l2_distance","dim"="8")
+) DUPLICATE KEY (`id`)
+DISTRIBUTED BY HASH(`id`) BUCKETS 1
+PROPERTIES("replication_num"="1");
+
+INSERT INTO ann_with_fulltext VALUES
+(1, [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8], 'this is about music', 10),
+(2, [0.2,0.1,0.5,0.3,0.9,0.4,0.7,0.1], 'sports news today', 20),
+(3, [0.9,0.8,0.7,0.6,0.5,0.4,0.3,0.2], 'latest music trend', 30),
+(4, [0.05,0.06,0.07,0.08,0.09,0.1,0.2,0.3], 'politics update',40)
+```
+
+사용자 쿼리 벡터 `[0.1,0.1,0.2,0.2,0.3,0.3,0.4,0.4]`가 주어지면, 가장 유사한 문서 상위 2개를 `comment`에 "music"이 포함된 문서 중에서만 검색합니다.
+
+```sql
+SELECT id, comment,
+ l2_distance_approximate(embedding, [0.1,0.1,0.2,0.2,0.3,0.3,0.4,0.4]) AS dist
+FROM ann_with_fulltext
+WHERE comment MATCH_ANY 'music' -- Filter using the inverted index first
+ORDER BY dist ASC -- Then perform ANN TopN over the filtered result set
+LIMIT 2;
+
++------+---------------------+----------+
+| id | comment | dist |
++------+---------------------+----------+
+| 1 | this is about music | 0.663325 |
+| 3 | latest music trend | 1.280625 |
++------+---------------------+----------+
+2 rows in set (0.04 sec)
+```
+
+:::tip 핵심 팁
+필터를 적용한 ANN 검색에서 벡터 인덱스로 TopN을 가속하려면, **필터링에 사용되는 컬럼에 역색인과 같은 보조 인덱스가 있어야 합니다**.
+:::
+
+---
+
+## 쿼리 매개변수 {#query-parameters}
+
+<!-- Knowledge type: configuration parameters -->
+
+HNSW 인덱스 구축 시 지정하는 매개변수 외에도, 쿼리 단계에서 세션 변수를 통해 동작을 조정할 수 있습니다.
+
+| 세션 변수 | 기본값 | 설명 |
+|----------|--------|------|
+| `hnsw_ef_search` | `32` | HNSW 인덱스의 EF 검색 매개변수입니다. 검색 중 후보 큐의 최대 길이를 제어합니다. 값이 클수록 정확도가 높아지지만 지연 시간도 늘어납니다. |
+| `hnsw_check_relative_distance` | `true` | HNSW 검색 정확도를 높이기 위한 상대 거리 검사 메커니즘을 활성화할지 여부입니다. |
+| `hnsw_bounded_queue` | `true` | HNSW 검색 성능을 최적화하기 위해 크기가 제한된 우선순위 큐를 사용할지 여부입니다. |
+
+---
+
+## 벡터 양자화 {#vector-quantization}
+
+<!-- Knowledge type: optimization strategy + configuration parameters -->
+<!-- Applicable scenarios: memory-constrained / very large vector sets -->
+
+FLAT 인코딩을 사용하면 HNSW 인덱스(원본 벡터와 그래프 구조)가 많은 메모리를 사용할 수 있습니다. HNSW가 동작하려면 **전체가 메모리에 상주해야 하므로**, 매우 큰 데이터셋에서는 쉽게 병목이 됩니다.
+
+Doris는 두 가지 유형의 양자화 방식을 제공합니다.
+
+| 양자화 | 원리 | Doris 지원 |
+|----------|------|-----------|
+| 스칼라 양자화(SQ) | 각 FLOAT32 차원을 압축하여 메모리 오버헤드 감소 | `sq8` (INT8), `sq4` (INT4) |
+| 곱 양자화(PQ) | 고차원 벡터를 분해하고 각 하위 벡터를 개별적으로 양자화 | `pq` |
+
+### 스칼라 양자화(SQ) 예제 {#scalar-quantization-sq-example}
+
+```sql
+CREATE TABLE sift_1M (
+ id int NOT NULL,
+ embedding array<float> NOT NULL COMMENT "",
+ INDEX ann_index (embedding) USING ANN PROPERTIES(
+ "index_type"="hnsw",
+ "metric_type"="l2_distance",
+ "dim"="128",
+ "quantizer"="sq8" -- Use INT8 for quantization
+ )
+) ENGINE=OLAP
+DUPLICATE KEY(id) COMMENT "OLAP"
+DISTRIBUTED BY HASH(id) BUCKETS 1
+PROPERTIES (
+ "replication_num" = "1"
+);
+```
+
+768차원의 Cohere-MEDIUM-1M 및 Cohere-LARGE-10M 데이터셋으로 수행한 테스트에서 SQ8은 인덱스 크기를 FLAT의 약 1/3로 압축합니다.
+
+### 양자화 비교 {#quantization-comparison}
+
+| 데이터셋 | 벡터 차원 | 저장 / 인덱스 방식 | 총 디스크 사용량 | 데이터 부분 | 인덱스 부분 | 참고 |
+|--------|----------|---------------|------------|----------|----------|------|
+| Cohere-MEDIUM-1M | 768D | Doris (FLAT) | 5.647 GB (2.533 + 3.114) | 2.533 GB | 3.114 GB | 1M 벡터, 원본 + HNSW FLAT 인덱스 |
... 21871 lines suppressed ...
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org