

 Amazon Redshift 將不再支援從修補程式 198 開始建立新的 Python UDFs。現有 Python UDF 將繼續正常運作至 2026 年 6 月 30 日。如需詳細資訊，請參閱[部落格文章](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/)。

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 資料列層級安全性
<a name="t_rls"></a>

使用 Amazon Redshift 中的資料列層級安全 (RLS)，您可以對敏感資料進行精細的存取控制。您可以根據資料庫物件層級定義的安全政策，決定哪些使用者或角色可以存取結構描述或資料表內的特定資料記錄。除了可用來授予使用者資料欄子集許可的資料欄層級安全之外，還可以使用 RLS 政策進一步限制可見資料欄的特定資料列存取。如需資料欄層級安全的相關資訊，請參閱 [欄位層級存取控制的使用須知](r_GRANT-usage-notes.md#r_GRANT-usage-notes-clp)。

在資料表上強制執行 RLS 政策時，您可以在使用者執行查詢時限制傳回的結果集。

建立 RLS 政策時，您可以指定運算式來指出 Amazon Redshift 是否在查詢中傳回資料表中的任何現有資料列。藉由建立 RLS 政策來限制存取，您不必在查詢中新增或外部化其他條件。

建立 RLS 政策時，建議您建立簡單的政策，並避免在政策中使用複雜的陳述式。定義 RLS 政策時，請勿在以政策為基礎的政策定義中使用過多的資料表聯結。

當政策參照查閱資料表時，除了政策所在的資料表之外，Amazon Redshift 還會掃描其他表格。對於已附加 RLS 政策的使用者，以及未附加任何政策的使用者，相同查詢之間會有效能差異。

# 在 SQL 陳述式中使用 RLS 政策
<a name="t_rls_statements"></a>

在 SQL 陳述式中使用 RLS 政策時，Amazon Redshift 會套用下列規則：
+ 根據預設，Amazon Redshift 會將 RLS 政策套用至 SELECT、UPDATE 和 DELETE 陳述式。
+ 對於 SELECT 和 UNLOAD，Amazon Redshift 會根據您定義的政策篩選資料列。
+ 對於 UPDATE，Amazon Redshift 只會更新您可以看到的資料列。如果政策限制了資料表中的資料列子集，您就無法將其更新。
+ 對於 DELETE，您只能刪除您可以看到的資料列。如果政策限制了資料表中的資料列子集，您就無法將其刪除。對於 TRUNCATE，您仍然可以截斷資料表。
+ 對於 CREATE TABLE LIKE，使用 LIKE 選項建立的資料表不會繼承從來源資料表設定的許可。同樣地，目標資料表不會繼承來源資料表的 RLS 政策。

# 每個使用者結合多個政策
<a name="t_rls_combine_policies"></a>

Amazon Redshift 中的 RLS 支援為每個使用者和物件附加多個政策。為使用者定義多個政策時，Amazon Redshift 會使用 AND 或 OR 語法 (取決於資料表的 RLS CONJUNCTION TYPE 設定) 套用所有政策。如需結合類型的更多相關資訊，請參閱 [ALTER TABLE](r_ALTER_TABLE.md)。

資料表上的多個政策都可以與您建立關聯。您可以直接附加多個政策，或者您屬於多個角色，而這些角色附加了不同的政策。

當多個政策應限制指定關係中的資料列存取時，您可以將關係的 RLS CONJUNCTION TYPE 設定為 AND。請考量下列範例。Alice 只能看到具有 NBA「貓名」的體育賽事做為指定政策。

```
-- Create an analyst role and grant it to a user named Alice.
CREATE ROLE analyst;
CREATE USER alice WITH PASSWORD 'Name_is_alice_1';
GRANT ROLE analyst TO alice;

-- Create an RLS policy that only lets the user see sports.
CREATE RLS POLICY policy_sports
WITH (catgroup VARCHAR(10))
USING (catgroup = 'Sports');

-- Create an RLS policy that only lets the user see NBA.
CREATE RLS POLICY policy_nba
WITH (catname VARCHAR(10))
USING (catname = 'NBA');

-- Attach both to the analyst role.
ATTACH RLS POLICY policy_sports ON category TO ROLE analyst;
ATTACH RLS POLICY policy_nba ON category TO ROLE analyst;

-- Activate RLS on the category table with AND CONJUNCTION TYPE. 
ALTER TABLE category ROW LEVEL SECURITY ON CONJUNCTION TYPE AND;

-- Change session to Alice.
SET SESSION AUTHORIZATION alice;

-- Select all from the category table.
SELECT catgroup, catname
FROM category;

 catgroup | catname 
---------+---------
 Sports   | NBA
(1 row)
```

當多個策略應允許使用者查看指定關係中的更多資料列時，使用者可以將關係的 RLS CONJUNCTION TYPE 設定為 OR。請考量下列範例。Alice 只能看到「音樂會」和「體育」做為指定政策。

```
-- Create an analyst role and grant it to a user named Alice.
CREATE ROLE analyst;
CREATE USER alice WITH PASSWORD 'Name_is_alice_1';
GRANT ROLE analyst TO alice;

-- Create an RLS policy that only lets the user see concerts.
CREATE RLS POLICY policy_concerts
WITH (catgroup VARCHAR(10))
USING (catgroup = 'Concerts');

-- Create an RLS policy that only lets the user see sports.
CREATE RLS POLICY policy_sports
WITH (catgroup VARCHAR(10))
USING (catgroup = 'Sports');

-- Attach both to the analyst role.
ATTACH RLS POLICY policy_concerts ON category TO ROLE analyst;
ATTACH RLS POLICY policy_sports ON category TO ROLE analyst;

-- Activate RLS on the category table with OR CONJUNCTION TYPE. 
ALTER TABLE category ROW LEVEL SECURITY ON CONJUNCTION TYPE OR;

-- Change session to Alice.
SET SESSION AUTHORIZATION alice;

-- Select all from the category table.
SELECT catgroup, count(*)
FROM category
GROUP BY catgroup ORDER BY catgroup;

 catgroup | count 
---------+-------
 Concerts |  3
 Sports   |  5
(2 rows)
```

# RLS 政策擁有權和管理
<a name="t_rls_ownership"></a>

身為擁有 sys:secadmin 角色的超級使用者、安全管理員或使用者，您可以建立、修改、連接和分離 RLS 政策。RLS 政策可以連接至資料表、檢視、近期繫結檢視 (LBV) 和具體化視觀表 (MV)。在物件層級上，您可以開啟或關閉資料列層級安全，而不必修改資料表的結構描述定義。

若要開始使用資料列層級安全，下列是您可以使用的 SQL 陳述式：
+ 使用 ALTER TABLE 陳述式來開啟或關閉資料表、檢視或近期繫結檢視上的 RLS。如需詳細資訊，請參閱[ALTER TABLE](r_ALTER_TABLE.md)。
+ 使用 ALTER MATERIALIZED VIEW 陳述式在具體化視觀表 (MV) 上開啟或關閉 RLS。如需詳細資訊，請參閱[ALTER MATERIALIZED VIEW](r_ALTER_MATERIALIZED_VIEW.md)。
+ 使用 CREATE RLS POLICY 陳述式為一或多個資料表建立安全政策，並在政策中指定一或多個使用者或角色。

  如需詳細資訊，請參閱[CREATE RLS POLICY](r_CREATE_RLS_POLICY.md)。
+ 使用 ALTER RLS POLICY 陳述式來修改政策，例如變更政策定義。您可以針對多個資料表或檢視使用相同的政策。

  如需詳細資訊，請參閱[ALTER RLS POLICY](r_ALTER_RLS_POLICY.md)。
+ 使用 ATTACH RLS POLICY 陳述式可將政策附加至一或多個關係、一或多個使用者或角色。

  如需詳細資訊，請參閱[ATTACH RLS POLICY](r_ATTACH_RLS_POLICY.md)。
+ 使用 DETACH RLS POLICY 陳述式從一或多個關係、一或多個使用者或是角色中將政策分離。

  如需詳細資訊，請參閱[DETACH RLS POLICY](r_DETACH_RLS_POLICY.md)。
+ 您可以使用 DROP RLS POLICY 陳述式來捨棄政策。

  如需詳細資訊，請參閱[DROP RLS POLICY](r_DROP_RLS_POLICY.md)。
+ 您可以使用 GRANT 和 REVOKE 陳述式，明確授予及撤銷參考查閱資料表之 RLS 政策的 SELECT 許可。如需詳細資訊，請參閱[GRANT](r_GRANT.md)及[REVOKE](r_REVOKE.md)。

若要監控所建立的證測，sys:secadmin 可以檢視 [SVV\$1RLS\$1POLICY](r_SVV_RLS_POLICY.md) 和 [SVV\$1RLS\$1ATTACHED\$1POLICY](r_SVV_RLS_ATTACHED_POLICY.md)。

若要列出受 RLS 保護的關係，sys:secadmin 可以檢視 [SVV\$1RLS\$1RELATION](r_SVV_RLS_RELATION.md)。

若要追蹤參照受 RLS 保護關係之查詢上的 RLS 政策應用程式，超級使用者、sys:operator 或任何具有系統許可 ACCESS SYSTEM TABLE 的使用者都可以檢視 [SVV\$1RLS\$1APPLIED\$1POLICY](r_SVV_RLS_APPLIED_POLICY.md)。請注意，在預設情況下，sys:secadmin 不會授予這些許可。

若要允許使用者完整存取受 RLS 保護的關係，您可以授予 IGNORE RLS 許可。超級使用者或 sys:secadmin 會自動獲得 IGNORE RLS 許可。如需詳細資訊，請參閱[GRANT](r_GRANT.md)。

若要說明 EXPLAIN 計劃中查詢的 RLS 政策篩選，以針對與 RLS 相關的查詢進行疑難排解，您可以將 EXPLAIN RLS 許可授予任何使用者。如需詳細資訊，請參閱[GRANT](r_GRANT.md)及[EXPLAIN](r_EXPLAIN.md)。

# 政策相依物件和原則
<a name="t_rls_object_dependency"></a>

為了提供應用程式的安全性，並防止政策物件過時或無效，Amazon Redshift 不允許捨棄或變更 RLS 政策所參照的物件。

以下列出 Amazon Redshift 針對 RLS 政策追蹤的結構描述物件相依性。
+ 追蹤目標資料表的結構描述物件相依性時，Amazon Redshift 會遵循下列規則：
  + 當您捨棄目標資料表時，Amazon Redshift 會將政策與關係、使用者、角色或公開分離。
  + 當您重新命名目標資料表名稱時，附加的政策不會受到影響。
  + 如果您先將政策捨棄或分離，您只能捨棄政策定義中參照的目標資料表資料欄。這也適用於指定 CASCADE 選項時。您可以捨棄目標資料表中的其他資料欄。
  + 您無法重命名目標資料表的參照資料欄。若要重新命名參照的資料欄，請先將政策分離。這也適用於指定 CASCADE 選項時。
  + 即使您指定 CASCADE 選項，也無法變更參照資料欄的類型。
+ 追蹤查閱資料表的結構描述物件相依性時，Amazon Redshift 會遵循下列規則：
  + 您無法捨棄查閱資料表。若要捨棄查閱資料表，請先捨棄參照查詢資料表的政策。
  + 您無法重新命名查閱資料表。若要重新命名查閱資料表，請先捨棄參照查詢資料表的政策。這也適用於指定 CASCADE 選項時。
  + 您無法捨棄政策定義中使用的查閱資料表資料欄。若要捨棄政策定義中使用的查閱資料表資料欄，請先捨棄參照查詢資料表的政策。這也適用於在 ALTER TABLE DROP COLUMN 陳述式中指定 CASCADE 選項時。您可以捨棄查閱資料表中的其他資料欄。
  + 您無法重命名查閱資料表的參照資料欄。若要重新命名參照的資料欄，請先捨棄參照查詢資料表的政策。這也適用於指定 CASCADE 選項時。
  + 您無法變更參照資料欄的類型。
+ 捨棄使用者或角色時，Amazon Redshift 會自動分離附加到該使用者或角色的所有政策。
+ 當您在 DROP SCHEMA 陳述式中使用 CASCADE 選項時，Amazon Redshift 也會捨棄結構描述中的關係。還會捨棄任何其他結構描述中依賴於已捨棄結構描述中關係的關係。對於政策中作為查閱資料表的關係，Amazon Redshift 會使 DROP SCHEMA DDL 失敗。對於 DROP SCHEMA 陳述式捨棄的任何關係，Amazon Redshift 會將所有附加到這些關係的政策分離。
+ 您只能在捨棄政策時捨棄查詢函數 (政策定義中參照的函數)。這也適用於指定 CASCADE 選項時。
+ 將政策附加至資料表時，Amazon Redshift 會檢查此資料表是否為不同政策中的查閱資料表。如果是這種情況，Amazon Redshift 將不允許在此資料表中附加政策。
+ 建立 RLS 政策時，Amazon Redshift 會檢查此資料表是否為任何其他 RLS 政策的目標資料表。如果是這種情況，Amazon Redshift 將不允許在此資料表上建立政策。

## 範例
<a name="t_rls_object_dependency-example"></a>

下列範例說明如何追蹤結構描述相依性。

```
-- The CREATE and ATTACH policy statements for `policy_events` references some
-- target and lookup tables.
-- Target tables are tickit_event_redshift and target_schema.target_event_table.
-- Lookup table is tickit_sales_redshift.
-- Policy `policy_events` has following dependencies:
--   table tickit_sales_redshift column eventid, qtysold
--   table tickit_event_redshift column eventid
--   table target_event_table column eventid
--   schema public and target_schema
CREATE RLS POLICY policy_events
WITH (eventid INTEGER)
USING (
    eventid IN (SELECT eventid FROM tickit_sales_redshift WHERE qtysold <3)
);

ATTACH RLS POLICY policy_events ON tickit_event_redshift TO ROLE analyst;

ATTACH RLS POLICY policy_events ON target_schema.target_event_table TO ROLE consumer;
```

# 使用 RLS 政策的考量事項和限制
<a name="t_rls_usage"></a>

## 考量事項
<a name="t_rls_considerations"></a>

以下是使用 RLS 政策時的考量事項：
+ Amazon Redshift 會將 RLS 政策套用至 SELECT、UPDATE 或 DELETE 陳述式。
+ Amazon Redshift 不會將 RLS 政策套用至 INSERT、COPY、ALTER TABLE APPEND 陳述式。
+ RLS 政策可以連接至資料表、檢視、近期繫結檢視 (LBV) 和具體化視觀表 (MV)。
+ 資料列層級安全可搭配資料欄層級安全來保護您的資料。
+ 針對來源關係開啟 RLS 時，Amazon Redshift 會針對超級使用者、已明確授予系統許可 IGNORE RLS 的使用者或 sys:secadmin 角色支援 ALTER TABLE APPEND 陳述式。在這種情況下，您可以執行 ALTER TABLE APPEND 陳述式，藉由從現有來源資料表移動資料來將資料列附加至目標資料表。Amazon Redshift 會將所有元組從來源關係移動到目標關係。目標關係的 RLS 狀態不會影響 ALTER TABLE APPEND 陳述式。
+ 若要協助從其他資料倉儲系統移轉，您可以指定變數名稱和值，以設定和擷取用於連線的自訂工作階段內容變數。

  下列範例會針對資料列層級安全 (RLS) 政策設定工作階段內容變數。

  ```
  -- Set a customized context variable.
  SELECT set_config(‘app.category’, ‘Concerts’, FALSE);
  
  -- Create a RLS policy using current_setting() to get the value of a customized context variable.
  CREATE RLS POLICY policy_categories
  WITH (catgroup VARCHAR(10)) 
  USING (catgroup = current_setting('app.category', FALSE));
  
  -- Set correct roles and attach the policy on the target table to one or more roles.
  ATTACH RLS POLICY policy_categories ON tickit_category_redshift TO ROLE analyst, ROLE dbadmin;
  ```

  如需有關如何設定和擷取自訂工作階段內容變數的詳細資訊，請前往 [SET](r_SET.md)、[SET\$1CONFIG](r_SET_CONFIG.md)、[SHOW](r_SHOW.md)、[CURRENT\$1SETTING](r_CURRENT_SETTING.md) 和 [RESET](r_RESET.md)。如需修改伺服器組態的一般詳細資訊，請前往 [修改伺服器組態](cm_chap_ConfigurationRef.md#t_Modifying_the_default_settings)。
**重要**  
 在 RLS 政策內使用工作階段內容變數時，安全政策會依賴調用政策的使用者或角色。在 RLS 政策中使用工作階段內容變數時，請小心避免安全漏洞。
+ 在 DECLARE 和 FETCH 之間或後續 FETCH 陳述式之間使用 SET SESSION AUTHORIZATION 變更工作階段使用者，將不會根據 DECLARE 時間的使用者政策重新整理已就緒的計劃。當游標與受 RLS 保護的資料表搭配使用時，請避免變更工作階段使用者。
+ 當檢視物件中的基底物件受到 RLS 保護時，附加至執行查詢之使用者的政策會套用至個別的基底物件。這與物件層級許可檢查不同，檢視擁有者的許可會根據檢視基礎物件進行檢查。您可以在查詢的 EXPLAIN 計畫輸出中檢視受到 RS 保護的關係。
+ 在附加至使用者的關係的 RLS 政策中參照使用者定義函數 (UDF) 時，使用者必須擁有 UDF 的 EXECUTE 許可，才能查詢關係。
+  資料列層級安全性可能會限制最佳查詢效果。在大型資料集上部署受 RLS 保護的視觀表之前，我們建議您仔細評估查詢效能。
+  套用至最新繫結視觀表的資料列層級安全政策，可能會推入聯合資料表。這些 RLS 政策可能會顯示在外部處理引擎日誌檔中。

## 限制
<a name="t_rls_limitations"></a>

下列是使用 RLS 政策時的限制：
+ RLS 政策無法連接到外部資料表和其他數種關係類型。如需詳細資訊，請參閱[ATTACH RLS POLICY](r_ATTACH_RLS_POLICY.md)。
+ Amazon Redshift 可針對具有複雜聯結的特定 RLS 政策支援 SELECT 陳述式，但不支援 UPDATE 或 DELETE 陳述式。如果使用 UPDATE 或 DELETE，Amazon Redshift 會傳回以下錯誤：

  ```
  ERROR: One of the RLS policies on target relation is not supported in UPDATE/DELETE.
  ```
+ 每當在附加至使用者的關係的 RLS 政策中參照使用者定義函數 (UDF) 時，使用者必須擁有 UDF 的 EXECUTE 許可，才能查詢關係。
+ 不支援相關子查詢。Amazon Redshift 會傳回以下錯誤：

  ```
  ERROR: RLS policy could not be rewritten.
  ```
+ Amazon Redshift 不支援使用 RLS 進行資料共用。如果關係沒有關閉用於資料共用的 RLS，則取用者叢集上的查詢會失敗，並出現下列錯誤：

  ```
  RLS-protected relation "rls_protected_table" cannot be accessed via datasharing query.
  ```

  您可以使用 ALTER TABLE 命令搭配 ROW LEVEL SECURITY OFF FOR DATASHARES 參數來關閉資料共用的 RLS。如需使用 ALTER TABLE 啟用或停用 RLS 的詳細資訊，請前往 [ALTER TABLE](r_ALTER_TABLE.md)。
+ 在跨資料庫查詢中，Amazon Redshift 會阻止您讀取受 RLS 保護的關係。具有 IGNORE RLS 許可的使用者可以使用跨資料庫查詢存取受保護的關係。當沒有 IGNORE RLS 許可的使用者透過跨資料庫查詢存取受 RLS 保護的關係時，會出現下列錯誤：

  ```
  RLS-protected relation "rls_protected_table" cannot be accessed via cross-database query.
  ```
+ ALTER RLS POLICY 只支援 USING ( using\$1predicate\$1exp ) 子句修改 RLS 政策。執行 ALTER RLS POLICY 時，您無法使用 WITH 子句修改 RLS 政策。
+ 如果下列任一組態選項的值不符合工作階段的預設值，您就無法查詢已開啟資料列層級安全的關係：
  +  `enable_case_sensitive_super_attribute` 
  +  `enable_case_sensitive_identifier` 
  +  `downcase_delimited_identifier` 

  如果您嘗試查詢已開啟資料列層級安全的關係，並看到「受 RLS 保護的關係不支援工作階段層級組太，因為區分大小寫設定與其預設值不同」的訊息，請考慮重設工作階段的組態選項。
+  當您佈建的叢集或無伺服器命名空間具有任何資料列層級安全性政策時，一般使用者會無法使用下列命令：

  ```
  ALTER <current_user> SET enable_case_sensitive_super_attribute/enable_case_sensitive_identifier/downcase_delimited_identifier
  ```

  建立 RLS 政策時，建議您變更一般使用者的預設組態選項設定，以符合建立政策時的工作階段組態選項設定。超級使用者和擁有 ALTER USER 權限的使用者可以使用參數群組設定或 ALTER USER 命令來執行此操作。如需有關參數群組的詳細資訊，請參閱《Amazon Redshift 管理指南》**中的 [Amazon Redshift 參數群組](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-parameter-groups.html)。如需 ALTER USER 命令的相關資訊，請參閱 [ALTER USER](r_ALTER_USER.md)。
+  使用 [CREATE VIEW](r_CREATE_VIEW.md) 命令的一般使用者，無法取代具有資料列層級安全政策的視觀表和近期繫結視觀表。若要以 RLS 政策取代視觀表或 LBV，請先卸離任何附加的 RLS 政策、取代視觀表或 LBV，然後重新附加政策。具有 `sys:secadmin permission` 的超級使用者和一般使用者都可以在具有 RLS 政策，但未卸離政策的視觀表或 LBV 上使用 CREATE VIEW。
+  具有資料列層級安全政策的視觀表無法參考系統資料表和系統視觀表。
+  一般視觀表所參考的近期繫結視觀表，不得為受 RLS 保護。
+  RLS 保護的關係和來自資料湖的巢狀資料，均無法在相同的查詢中存取。

# RLS 效能的最佳實務
<a name="t_rls_performance"></a>

以下最佳實務可確保 Amazon Redshift 在受 RLS 保護的資料表上獲得更好的效能。

## 運算子和函數的安全性
<a name="t_rls_safe_operators"></a>

查詢受 RLS 保護的資料表時，使用某些運算子或函數可能會導致效能降低。Amazon Redshift 會將運算子和函數分類為在查詢受 RLS 保護的資料表時是安全或不安全的。當函數或運算子沒有因為輸入而有任何可觀察到的副作用時，函數或運算子就會被歸類為 RLS 安全。特別是，RLS 安全函數或運算子不能是以下其中一項：
+ 輸出一個輸入值，或任何依賴於輸入值的值，無論有沒有錯誤訊息。
+ 失敗或傳回依賴於輸入值的錯誤。

RLS 不安全的運算子包括：
+ 算術運算子 — \$1、-、/、\$1、%。
+ 文字運算子 — LIKE 和 SIMILAR TO。
+ 轉換運算子。
+ UDF。

使用下列 SELECT 陳述式來檢查運算子和函數的安全性。

```
SELECT proname, proc_is_rls_safe(oid) FROM pg_proc;
```

在受 RLS 保護的資料表上規劃查詢時，Amazon Redshift 會對包含 RLS 不安全運算子和函數的使用者述詞的評估順序施加限制。查詢受 RLS 保護的資料表時，參照 RLS 不安全運算子或函數的查詢可能會導致效能降低。當 Amazon Redshift 無法將 RLS 不安全述詞推送至基底資料表掃描以利用排序索引鍵時，效能可能會大幅降低。為了獲得更好的效能，請避免使用利用排序索引鍵的 RLS 不安全述詞進行查詢。若要確認 Amazon Redshift 能夠向下推送運算子和函數，您可以將 EXPLAIN 陳述式與系統許可 EXPLACE RLS 結合使用。

## 結果快取
<a name="t_rls_result_cache"></a>

為了縮短查詢執行期並改善系統效能，Amazon Redshift 會將特定查詢類型的結果快取在領導者節點的記憶體中。

當未受保護資料表的所有條件皆成立，且下列所有條件皆成立時，Amazon Redshift 會在新查詢掃描受 RLS 保護的資料表時使用快取結果：
+ 政策中的資料表或檢視尚未經過修改。
+ 政策並未使用每次執行時都必須求值的函數，例如 GETDATE 或 CURRENT\$1USER。

為了獲得更好的效能，請避免使用不符合前述條件的政策述詞。

如需 Amazon Redshift 中結果快取的詳細資訊，請參閱 [結果快取](c_challenges_achieving_high_performance_queries.md#result-caching)。

## 複雜政策
<a name="t_rls_complex_policies"></a>

為了獲得更好的效能，請避免在聯結多個資料表的子查詢中使用複雜的政策。

# 資料列層級安全完整範例
<a name="t_rls-example"></a>

以下是說明超級使用者如何建立某些使用者和角色的端對端範例。然後，具有 secadmin 角色的使用者會建立、附加、分離和捨棄 RLS 政策。此範例會使用票卷範例資料庫。如需詳細資訊，請參閱《Amazon Redshift 入門指南》**中的[將資料從 Amazon S3 載入到 Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/gsg/rs-gsg-create-sample-db.html)。

```
-- Create users and roles referenced in the policy statements.
CREATE ROLE analyst;
CREATE ROLE consumer;
CREATE ROLE dbadmin;
CREATE ROLE auditor;
CREATE USER bob WITH PASSWORD 'Name_is_bob_1';
CREATE USER alice WITH PASSWORD 'Name_is_alice_1';
CREATE USER joe WITH PASSWORD 'Name_is_joe_1';
CREATE USER molly WITH PASSWORD 'Name_is_molly_1';
CREATE USER bruce WITH PASSWORD 'Name_is_bruce_1';
GRANT ROLE sys:secadmin TO bob;
GRANT ROLE analyst TO alice;
GRANT ROLE consumer TO joe;
GRANT ROLE dbadmin TO molly;
GRANT ROLE auditor TO bruce;
GRANT ALL ON TABLE tickit_category_redshift TO PUBLIC;
GRANT ALL ON TABLE tickit_sales_redshift TO PUBLIC;
GRANT ALL ON TABLE tickit_event_redshift TO PUBLIC;

-- Create table and schema referenced in the policy statements.
CREATE SCHEMA target_schema;
GRANT ALL ON SCHEMA target_schema TO PUBLIC;
CREATE TABLE target_schema.target_event_table (LIKE tickit_event_redshift);
GRANT ALL ON TABLE target_schema.target_event_table TO PUBLIC;

-- Change session to analyst alice.
SET SESSION AUTHORIZATION alice;

-- Check the tuples visible to analyst alice.
-- Should contain all 3 categories.
SELECT catgroup, count(*)
FROM tickit_category_redshift
GROUP BY catgroup ORDER BY catgroup;

-- Change session to security administrator bob.
SET SESSION AUTHORIZATION bob;

CREATE RLS POLICY policy_concerts
WITH (catgroup VARCHAR(10))
USING (catgroup = 'Concerts');

SELECT poldb, polname, polalias, polatts, polqual, polenabled, polmodifiedby FROM svv_rls_policy WHERE poldb = CURRENT_DATABASE();

ATTACH RLS POLICY policy_concerts ON tickit_category_redshift TO ROLE analyst, ROLE dbadmin;

ALTER TABLE tickit_category_redshift ROW LEVEL SECURITY ON;

SELECT * FROM svv_rls_attached_policy;

-- Change session to analyst alice.
SET SESSION AUTHORIZATION alice;

-- Check that tuples with only `Concert` category will be visible to analyst alice.
SELECT catgroup, count(*)
FROM tickit_category_redshift
GROUP BY catgroup ORDER BY catgroup;

-- Change session to consumer joe.
SET SESSION AUTHORIZATION joe;

-- Although the policy is attached to a different role, no tuples will be
-- visible to consumer joe because the default deny all policy is applied.
SELECT catgroup, count(*)
FROM tickit_category_redshift
GROUP BY catgroup ORDER BY catgroup;

-- Change session to dbadmin molly.
SET SESSION AUTHORIZATION molly;

-- Check that tuples with only `Concert` category will be visible to dbadmin molly.
SELECT catgroup, count(*)
FROM tickit_category_redshift
GROUP BY catgroup ORDER BY catgroup;

-- Check that EXPLAIN output contains RLS SecureScan to prevent disclosure of
-- sensitive information such as RLS filters.
EXPLAIN SELECT catgroup, count(*) FROM tickit_category_redshift GROUP BY catgroup ORDER BY catgroup;

-- Change session to security administrator bob.
SET SESSION AUTHORIZATION bob;

-- Grant IGNORE RLS permission so that RLS policies do not get applicable to role dbadmin.
GRANT IGNORE RLS TO ROLE dbadmin;

-- Grant EXPLAIN RLS permission so that anyone in role auditor can view complete EXPLAIN output.
GRANT EXPLAIN RLS TO ROLE auditor;

-- Change session to dbadmin molly.
SET SESSION AUTHORIZATION molly;

-- Check that all tuples are visible to dbadmin molly because `IGNORE RLS` is granted to role dbadmin.
SELECT catgroup, count(*)
FROM tickit_category_redshift
GROUP BY catgroup ORDER BY catgroup;

-- Change session to auditor bruce.
SET SESSION AUTHORIZATION bruce;

-- Check explain plan is visible to auditor bruce because `EXPLAIN RLS` is granted to role auditor.
EXPLAIN SELECT catgroup, count(*) FROM tickit_category_redshift GROUP BY catgroup ORDER BY catgroup;

-- Change session to security administrator bob.
SET SESSION AUTHORIZATION bob;

DETACH RLS POLICY policy_concerts ON tickit_category_redshift FROM ROLE analyst, ROLE dbadmin;

-- Change session to analyst alice.
SET SESSION AUTHORIZATION alice;

-- Check that no tuples are visible to analyst alice.
-- Although the policy is detached, no tuples will be visible to analyst alice
-- because of default deny all policy is applied if the table has RLS on.
SELECT catgroup, count(*)
FROM tickit_category_redshift
GROUP BY catgroup ORDER BY catgroup;

-- Change session to security administrator bob.
SET SESSION AUTHORIZATION bob;

CREATE RLS POLICY policy_events
WITH (eventid INTEGER) AS ev
USING (
    ev.eventid IN (SELECT eventid FROM tickit_sales_redshift WHERE qtysold <3)
);

ATTACH RLS POLICY policy_events ON tickit_event_redshift TO ROLE analyst;
ATTACH RLS POLICY policy_events ON target_schema.target_event_table TO ROLE consumer;

RESET SESSION AUTHORIZATION;

-- Can not cannot alter type of dependent column.
ALTER TABLE target_schema.target_event_table ALTER COLUMN eventid TYPE float;
ALTER TABLE tickit_event_redshift ALTER COLUMN eventid TYPE float;
ALTER TABLE tickit_sales_redshift ALTER COLUMN eventid TYPE float;
ALTER TABLE tickit_sales_redshift ALTER COLUMN qtysold TYPE float;

-- Can not cannot rename dependent column.
ALTER TABLE target_schema.target_event_table RENAME COLUMN eventid TO renamed_eventid;
ALTER TABLE tickit_event_redshift RENAME COLUMN eventid TO renamed_eventid;
ALTER TABLE tickit_sales_redshift RENAME COLUMN eventid TO renamed_eventid;
ALTER TABLE tickit_sales_redshift RENAME COLUMN qtysold TO renamed_qtysold;

-- Can not drop dependent column.
ALTER TABLE target_schema.target_event_table DROP COLUMN eventid CASCADE;
ALTER TABLE tickit_event_redshift DROP COLUMN eventid CASCADE;
ALTER TABLE tickit_sales_redshift DROP COLUMN eventid CASCADE;
ALTER TABLE tickit_sales_redshift DROP COLUMN qtysold CASCADE;

-- Can not drop lookup table.
DROP TABLE tickit_sales_redshift CASCADE;

-- Change session to security administrator bob.
SET SESSION AUTHORIZATION bob;

DROP RLS POLICY policy_concerts;
DROP RLS POLICY IF EXISTS policy_events;

ALTER TABLE tickit_category_redshift ROW LEVEL SECURITY OFF;

RESET SESSION AUTHORIZATION;

-- Drop users and roles.
DROP USER bob;
DROP USER alice;
DROP USER joe;
DROP USER molly;
DROP USER bruce;
DROP ROLE analyst;
DROP ROLE consumer;
DROP ROLE auditor FORCE;
DROP ROLE dbadmin FORCE;
```