數據模型sql
Greenplum數據庫是一種shared nothing的分析型MPP數據庫。這種模型與高度規範化的/事務型的SMP數據庫有顯著區別。Greenplum數據庫使用非規範化的模式設計會工做得最好,非規範化的模式適合於MPP分析型處理,例如帶有大型事實表和較小維度表的星形模式或者雪花模式。數據庫
對錶中用於鏈接的列使用相同的數據類型。安全
堆存儲 vs. 追加優化存儲服務器
對將會接收迭代批量或者單一UPDATE、DELETE以及INSERT操做的表和分區使用堆存儲。網絡
對將會接收併發UPDATE、DELETE以及INSERT操做的表和分區使用堆存儲。併發
對於在初始裝載後不多更新而且只會在大型批處理操做中進行後續插入的表和分區,使用追加優化存儲。函數
毫不在追加優化表上執行單個INSERT、UPDATE或者DELETE操做。工具
毫不在追加優化表上執行併發的批量UPDATE或DELETE操做。能夠執行併發的批量INSERT操做。post
行存 vs. 列存性能
若是負載中有要求更新而且頻繁執行插入的迭代事務,則對這種負載使用行存。
在對寬表選擇時使用行存。
爲通常目的或混合負載使用行存。
選擇面很窄(不多的列)和在少許列上計算數據彙集時使用列存。
若是表中有單個列按期被更新而不修改行中的其餘列,則對這種表使用列存。
壓縮
在大型追加優化和分區表上使用壓縮以改進系統範圍的I/O。
在數據位於的級別上設置列壓縮設置。
在較高的壓縮級別和壓縮解壓數據所需的時間和CPU週期之間作出平衡。
分佈
爲全部的表顯式定義一個列分佈或者隨機分佈。不要使用默認值。
使用將在全部Segment間均勻分佈的單列。
不要在查詢的WHERE子句中用到的列上進行分佈。
不要在日期或時間戳上分佈。
不要在同一列上分佈而且分區表。
在常被鏈接起來的大型表的相同列上進行分佈以顯著地改進本地鏈接。
在初始裝載數據以及增量裝載數據以後驗證數據被均勻分佈。
根本上確保沒有數據傾斜!
內存管理
把vm.overcommit_memory設置爲2。
不要配置OS使用大頁。
使用gp_vmem_protect_limit設置實例能夠爲每一個Segment數據庫中執行的全部工做分配的最大內存。
經過下面的計算爲gp_vmem_protect_limit設置值:
gp_vmem – Greenplum數據庫可用的總內存
其中 SWAP是該主機的交換空間(以GB爲單位),RAM是該主機的RAM(以GB爲單位)
max_acting_primary_segments – 當鏡像Segment因爲主機或者Segment失效而被激活時,能在一臺主機上運行的最主Segment的最大數量
gp_vmem_protect_limit
轉換成MB來設置配置參數的值。
在有大量工做文件被生成的場景下用下面的公式計算將工做文件考慮在內的gp_vmem因子:
毫不將gp_vmem_protect_limit設置得太高或者比系統上的物理RAM大。
使用計算出的gp_vmem值來計算操做系統參數vm.overcommit_ratio的設置:
使用statement_mem來分配每一個Segment數據庫中用於一個查詢的內存。
使用資源隊列設置活動查詢的數目(ACTIVE_STATEMENTS)以及隊列中查詢所能利用的內存量(MEMORY_LIMIT)。
把全部的用戶都與一個資源隊列關聯。不要使用默認的隊列。
設置PRIORITY以匹配用於負載以及實際狀況的隊列的實際須要。
確保資源隊列的內存分配不會超過gp_vmem_protect_limit的設置。
動態更新資源隊列設置以匹配平常操做流。
分區
只對大型表分區。不要分區小表。
只有能基於查詢條件實現分區消除(分區剪枝)時才使用分區。
選擇範圍分區而捨棄列表分區。
基於查詢謂詞對錶分區。
不要在同一列上對錶進行分佈和分區。
不要使用默認分區。
不要使用多級分區,建立較少的分區讓每一個分區中有更多數據。
經過檢查查詢的EXPLAIN計劃驗證查詢有選擇地掃描分區表(分區被消除)。
不要用列存儲建立太多分區,由於每一個Segment上的物理文件總數:物理文件數 = Segment數 x 列數 x 分區數
索引
一般在Greenplum數據庫中無需索引。
對高基數的表在列式表的單列上建立索引用於鑽透目的要求查詢具備較高的選擇度。
不要索引被頻繁更新的列。
老是在裝載數據到表以前刪除索引。在裝載後,從新爲該表建立索引。
建立具備選擇性的B-樹索引。
不要在被更新的列上建立位圖索引。
不要爲惟一列、基數很是高或者很是低的數據使用位圖索引。
不要爲事務性負載使用位圖索引。
一般不要索引分區表。若是須要索引,索引列必須與分區列不一樣。
資源隊列
使用資源隊列來管理集羣上的負載。
將全部的角色都與一個用戶定義的資源隊列關聯。
使用ACTIVE_STATEMENTS參數限制特定隊列的成員能併發運行的活動查詢數量。
使用MEMORY_LIMIT參數控制經過隊列運行的查詢所能利用的總內存量。
不要把全部隊列都設置爲MEDIUM,由於這實際上沒有對負載進行管理。
動態修改資源隊列以匹配負載以及現狀。
監控和維護
實現Greenplum數據庫管理員指南中的"推薦的監控和維護任務"。
安裝時運行gpcheckperf而且在以後按期運行該工具,保存其輸出用來比較系統性能隨時間的變化。
使用手頭的全部工具來理解系統在不一樣負載下的表現。
檢查任何異常事件以判斷成因。
經過按期運行解釋計劃監控查詢活動以確保查詢被以最優的方式運行。
檢查計劃以判斷索引是否被使用以及分區消除是否按照預期發生。
瞭解系統日誌文件的位置和內容而且按期監控它們,而不是隻在問題出現時纔去檢查日誌。
ANALYZE
不要在整個數據庫上運行ANALYZE。須要時,有選擇地在表級別上運行ANALYZE。
在裝載後老是運行ANALYZE。
在顯著改變底層數據的INSERT、UPDATE以及DELETE操做以後老是運行ANALYZE。
在CREATE INDEX操做以後老是運行ANALYZE。
若是在很是大的表上運行ANALYZE須要太長時間,能夠只在用於鏈接條件、WHERE子句、SORT子句、GROUP BY子句或者HAVING子句的列上運行ANALYZE。
清掃
在大型UPDATE和DELETE操做後運行VACUUM。
不要運行VACUUM FULL。而是運行一個CREATE TABLE...AS操做,而後重命名而且刪掉原始表。
頻繁地在系統目錄上運行VACUUM以免目錄膨脹以及在目錄上運行VACUUM FULL的須要。
毫不要殺掉目錄表上的VACUUM。
不要運行VACUUM ANALYZE。
裝載
使用gpfdist在Greenplum數據庫中裝載或者卸載數據。
隨着Segment數目增長最大化並行性。
在儘量多的ETL節點上均勻散佈數據。
把很是大型的數據文件分割成相等的部分,而且把數據散佈在儘量多的文件系統上。
每一個文件系統運行兩個gpfdist實例。
在儘量多的接口上運行gpfdist。
使用gp_external_max_segs以控制每一個gpfdist服務的Segment數量。
老是保持gp_external_max_segs和gpfdist進程的數量爲偶因子。
在裝載到現有表以前老是刪除索引而且在裝載以後重建索引。
老是在對錶裝載以後運行ANALYZE。
在裝載期間經過設置gp_autostats_mode爲NONE禁用自動統計信息收集。
在裝載錯誤以後運行VACUUM以從新得到空間。
gptransfer
爲了最快的傳輸率,使用gptransfer傳輸數據到尺寸相同或者更大的目標數據庫。
避免使用--full或--schema-only選項。而是使用不一樣的方法將模式複製到目標數據庫中,而後傳輸表數據。
在傳輸表以前刪除索引而且在傳輸完成後重建它們。
使用SQL的COPY命令傳輸較小的表到目標數據庫。
使用gptransfer批量傳輸較大的表。
在執行生產遷移以前,先測試運行gptransfer。用--batch-size和--sub-batch-size選項進行實驗以獲得最大並行性。爲迭代運行gptransfer肯定合適的表批次。
只使用徹底限定的表名稱。表名中的點號(.)、空格、引號(')和雙引號(")均可能形成問題。
若是使用--validation選項在傳輸後驗證數據,肯定也使用-x選項在源表上放置排他鎖。
確保在目標數據庫上建立每個角色、函數和資源隊列。當使用gptransfer -t選項時,這些對象不會被會傳輸。
將postgres.conf和pg_hba.conf配置文件從源集羣拷貝到目標集羣。
在目標數據庫中用gppkg安裝所需的擴展。
安全性
保護gpadmin用戶ID而且只容許對它進行必需的系統管理員訪問。
在執行特定的系統維護任務(例如升級或者擴張)時,管理員只應做爲gpadmin登入到Greenplum。
限制具備SUPERUSER角色屬性的用戶。成爲超級用戶的角色能繞過Greenplum數據庫中的全部訪問特權檢查以及資源隊列。只有系統管理員應該被給予超級用戶的權力。請見Greenplum數據庫管理員指南中的「修改角色屬性」。
數據庫用戶毫不應該以gpadmin登陸,且ETL或者生產負載也毫不應該以gpadmin運行。
爲每一個登入的用戶分派一個不一樣的角色。
對於應用或者Web服務,考慮爲每一個應用或服務建立一個不一樣的角色。
使用組管理訪問特權。
保護root口令。
爲操做系統口令強制一種強口令策略。
確保重要的操做系統文件受到保護。
加密
加密和解密數據須要性能做爲代價,只加密須要加密的數據。
在生產系統中實現任何加密方案以前,先執行性能測試。
生產Greenplum數據庫系統中的服務器證書應該由一個數字證書認證機構(CA)簽發,這樣客戶端能夠認證該服務器。若是客戶端都是機構中的本地客戶端,CA能夠是本地的。
只要客戶端到Greenplum數據庫的鏈接會經過不安全的連接,就應該對其使用SSL加密。
對稱加密方案(加密和解密使用一樣的密鑰)具備比非對稱方案更好的性能,所以在密鑰能被安全共享時應當使用對稱加密方案。
使用pgcrypto包中的函數來加密磁盤上的數據。數據在數據庫進程中被加密和解密,所以有必要用SSL保護客戶端鏈接以免傳輸未加密數據。
在ETL數據被裝載到數據庫中或者從數據庫中卸載時,是用gpfdists協議加密它。
高可用性
使用帶有8至24個磁盤的硬件RAID存儲方案。
使用RAID 一、5或6,這樣磁盤陣列能容忍一個失效的磁盤。
在磁盤陣列中配置一個熱後備以容許在檢測到磁盤失效時自動開始重建。
經過鏡像RAID卷防止重建時整個磁盤陣列失效和退化。
按期監控磁盤使用而且在須要時增長額外的空間。
監控Segment傾斜以確保數據被平均地分佈而且在全部Segment上存儲被平均地消耗。
設置一個後備Master以便在主Master失效後接管。
規劃當失效發生時,如何把客戶端切換到新的Master實例,例如,經過更新DNS中的Master地址。
設置監控機制以便在主Master失效時在系統監控應用中或者經過email發出通知。
爲全部的Segment設置鏡像。
將主Segment和它們的鏡像放置在不一樣的主機上以預防主機失效。
設置監控機制以便在主Segment失效時在系統監控應用中或者經過email發出通知。
迅速地使用gprecoverseg工具失效的Segment,以便恢復冗餘而且讓系統回到最佳平衡。
配置Greenplum數據庫發送SNMP通知給網絡監控器。
在$MASTER_DATA_DIRECTORY/postgresql.conf配置文件中設置email通知,這樣Greenplum系統能夠在檢測到嚴重問題時用email通知管理員。
考慮雙集羣配置以提供額外層次上的冗餘以及額外的查詢處理吞吐。
除非數據庫能夠很容易地歷來源恢復,按期備份Greenplum數據庫。
若是堆表相對較小而且兩次備份之間只有不多的追加優化或列存分區被修改,使用增量備份。
若是備份被保存到本地集羣存儲上,在備份完成後將這些文件移動到一個安全的、不在集羣上的位置。
若是備份被保存到NFS掛載點,使用例如Dell EMC Isilon之類的橫向擴展NFS方案以免IO瓶頸。
考慮使用Greenplum集成將備份流式傳送給Dell EMC Data Domain或者 Veritas NetBackup企業級備份平臺。
---恢復內容結束---
數據模型
Greenplum數據庫是一種shared nothing的分析型MPP數據庫。這種模型與高度規範化的/事務型的SMP數據庫有顯著區別。Greenplum數據庫使用非規範化的模式設計會工做得最好,非規範化的模式適合於MPP分析型處理,例如帶有大型事實表和較小維度表的星形模式或者雪花模式。
對錶中用於鏈接的列使用相同的數據類型。
堆存儲 vs. 追加優化存儲
對將會接收迭代批量或者單一UPDATE、DELETE以及INSERT操做的表和分區使用堆存儲。
對將會接收併發UPDATE、DELETE以及INSERT操做的表和分區使用堆存儲。
對於在初始裝載後不多更新而且只會在大型批處理操做中進行後續插入的表和分區,使用追加優化存儲。
毫不在追加優化表上執行單個INSERT、UPDATE或者DELETE操做。
毫不在追加優化表上執行併發的批量UPDATE或DELETE操做。能夠執行併發的批量INSERT操做。
行存 vs. 列存
若是負載中有要求更新而且頻繁執行插入的迭代事務,則對這種負載使用行存。
在對寬表選擇時使用行存。
爲通常目的或混合負載使用行存。
選擇面很窄(不多的列)和在少許列上計算數據彙集時使用列存。
若是表中有單個列按期被更新而不修改行中的其餘列,則對這種表使用列存。
壓縮
在大型追加優化和分區表上使用壓縮以改進系統範圍的I/O。
在數據位於的級別上設置列壓縮設置。
在較高的壓縮級別和壓縮解壓數據所需的時間和CPU週期之間作出平衡。
分佈
爲全部的表顯式定義一個列分佈或者隨機分佈。不要使用默認值。
使用將在全部Segment間均勻分佈的單列。
不要在查詢的WHERE子句中用到的列上進行分佈。
不要在日期或時間戳上分佈。
不要在同一列上分佈而且分區表。
在常被鏈接起來的大型表的相同列上進行分佈以顯著地改進本地鏈接。
在初始裝載數據以及增量裝載數據以後驗證數據被均勻分佈。
根本上確保沒有數據傾斜!
內存管理
把vm.overcommit_memory設置爲2。
不要配置OS使用大頁。
使用gp_vmem_protect_limit設置實例能夠爲每一個Segment數據庫中執行的全部工做分配的最大內存。
經過下面的計算爲gp_vmem_protect_limit設置值:
gp_vmem – Greenplum數據庫可用的總內存
其中 SWAP是該主機的交換空間(以GB爲單位),RAM是該主機的RAM(以GB爲單位)
max_acting_primary_segments – 當鏡像Segment因爲主機或者Segment失效而被激活時,能在一臺主機上運行的最主Segment的最大數量
gp_vmem_protect_limit
轉換成MB來設置配置參數的值。
在有大量工做文件被生成的場景下用下面的公式計算將工做文件考慮在內的gp_vmem因子:
毫不將gp_vmem_protect_limit設置得太高或者比系統上的物理RAM大。
使用計算出的gp_vmem值來計算操做系統參數vm.overcommit_ratio的設置:
使用statement_mem來分配每一個Segment數據庫中用於一個查詢的內存。
使用資源隊列設置活動查詢的數目(ACTIVE_STATEMENTS)以及隊列中查詢所能利用的內存量(MEMORY_LIMIT)。
把全部的用戶都與一個資源隊列關聯。不要使用默認的隊列。
設置PRIORITY以匹配用於負載以及實際狀況的隊列的實際須要。
確保資源隊列的內存分配不會超過gp_vmem_protect_limit的設置。
動態更新資源隊列設置以匹配平常操做流。
分區
只對大型表分區。不要分區小表。
只有能基於查詢條件實現分區消除(分區剪枝)時才使用分區。
選擇範圍分區而捨棄列表分區。
基於查詢謂詞對錶分區。
不要在同一列上對錶進行分佈和分區。
不要使用默認分區。
不要使用多級分區,建立較少的分區讓每一個分區中有更多數據。
經過檢查查詢的EXPLAIN計劃驗證查詢有選擇地掃描分區表(分區被消除)。
不要用列存儲建立太多分區,由於每一個Segment上的物理文件總數:物理文件數 = Segment數 x 列數 x 分區數
索引
一般在Greenplum數據庫中無需索引。
對高基數的表在列式表的單列上建立索引用於鑽透目的要求查詢具備較高的選擇度。
不要索引被頻繁更新的列。
老是在裝載數據到表以前刪除索引。在裝載後,從新爲該表建立索引。
建立具備選擇性的B-樹索引。
不要在被更新的列上建立位圖索引。
不要爲惟一列、基數很是高或者很是低的數據使用位圖索引。
不要爲事務性負載使用位圖索引。
一般不要索引分區表。若是須要索引,索引列必須與分區列不一樣。
資源隊列
使用資源隊列來管理集羣上的負載。
將全部的角色都與一個用戶定義的資源隊列關聯。
使用ACTIVE_STATEMENTS參數限制特定隊列的成員能併發運行的活動查詢數量。
使用MEMORY_LIMIT參數控制經過隊列運行的查詢所能利用的總內存量。
不要把全部隊列都設置爲MEDIUM,由於這實際上沒有對負載進行管理。
動態修改資源隊列以匹配負載以及現狀。
監控和維護
實現Greenplum數據庫管理員指南中的"推薦的監控和維護任務"。
安裝時運行gpcheckperf而且在以後按期運行該工具,保存其輸出用來比較系統性能隨時間的變化。
使用手頭的全部工具來理解系統在不一樣負載下的表現。
檢查任何異常事件以判斷成因。
經過按期運行解釋計劃監控查詢活動以確保查詢被以最優的方式運行。
檢查計劃以判斷索引是否被使用以及分區消除是否按照預期發生。
瞭解系統日誌文件的位置和內容而且按期監控它們,而不是隻在問題出現時纔去檢查日誌。
ANALYZE
不要在整個數據庫上運行ANALYZE。須要時,有選擇地在表級別上運行ANALYZE。
在裝載後老是運行ANALYZE。
在顯著改變底層數據的INSERT、UPDATE以及DELETE操做以後老是運行ANALYZE。
在CREATE INDEX操做以後老是運行ANALYZE。
若是在很是大的表上運行ANALYZE須要太長時間,能夠只在用於鏈接條件、WHERE子句、SORT子句、GROUP BY子句或者HAVING子句的列上運行ANALYZE。
清掃
在大型UPDATE和DELETE操做後運行VACUUM。
不要運行VACUUM FULL。而是運行一個CREATE TABLE...AS操做,而後重命名而且刪掉原始表。
頻繁地在系統目錄上運行VACUUM以免目錄膨脹以及在目錄上運行VACUUM FULL的須要。
毫不要殺掉目錄表上的VACUUM。
不要運行VACUUM ANALYZE。
裝載
使用gpfdist在Greenplum數據庫中裝載或者卸載數據。
隨着Segment數目增長最大化並行性。
在儘量多的ETL節點上均勻散佈數據。
把很是大型的數據文件分割成相等的部分,而且把數據散佈在儘量多的文件系統上。
每一個文件系統運行兩個gpfdist實例。
在儘量多的接口上運行gpfdist。
使用gp_external_max_segs以控制每一個gpfdist服務的Segment數量。
老是保持gp_external_max_segs和gpfdist進程的數量爲偶因子。
在裝載到現有表以前老是刪除索引而且在裝載以後重建索引。
老是在對錶裝載以後運行ANALYZE。
在裝載期間經過設置gp_autostats_mode爲NONE禁用自動統計信息收集。
在裝載錯誤以後運行VACUUM以從新得到空間。
gptransfer
爲了最快的傳輸率,使用gptransfer傳輸數據到尺寸相同或者更大的目標數據庫。
避免使用--full或--schema-only選項。而是使用不一樣的方法將模式複製到目標數據庫中,而後傳輸表數據。
在傳輸表以前刪除索引而且在傳輸完成後重建它們。
使用SQL的COPY命令傳輸較小的表到目標數據庫。
使用gptransfer批量傳輸較大的表。
在執行生產遷移以前,先測試運行gptransfer。用--batch-size和--sub-batch-size選項進行實驗以獲得最大並行性。爲迭代運行gptransfer肯定合適的表批次。
只使用徹底限定的表名稱。表名中的點號(.)、空格、引號(')和雙引號(")均可能形成問題。
若是使用--validation選項在傳輸後驗證數據,肯定也使用-x選項在源表上放置排他鎖。
確保在目標數據庫上建立每個角色、函數和資源隊列。當使用gptransfer -t選項時,這些對象不會被會傳輸。
將postgres.conf和pg_hba.conf配置文件從源集羣拷貝到目標集羣。
在目標數據庫中用gppkg安裝所需的擴展。
安全性
保護gpadmin用戶ID而且只容許對它進行必需的系統管理員訪問。
在執行特定的系統維護任務(例如升級或者擴張)時,管理員只應做爲gpadmin登入到Greenplum。
限制具備SUPERUSER角色屬性的用戶。成爲超級用戶的角色能繞過Greenplum數據庫中的全部訪問特權檢查以及資源隊列。只有系統管理員應該被給予超級用戶的權力。請見Greenplum數據庫管理員指南中的「修改角色屬性」。
數據庫用戶毫不應該以gpadmin登陸,且ETL或者生產負載也毫不應該以gpadmin運行。
爲每一個登入的用戶分派一個不一樣的角色。
對於應用或者Web服務,考慮爲每一個應用或服務建立一個不一樣的角色。
使用組管理訪問特權。
保護root口令。
爲操做系統口令強制一種強口令策略。
確保重要的操做系統文件受到保護。
加密
加密和解密數據須要性能做爲代價,只加密須要加密的數據。
在生產系統中實現任何加密方案以前,先執行性能測試。
生產Greenplum數據庫系統中的服務器證書應該由一個數字證書認證機構(CA)簽發,這樣客戶端能夠認證該服務器。若是客戶端都是機構中的本地客戶端,CA能夠是本地的。
只要客戶端到Greenplum數據庫的鏈接會經過不安全的連接,就應該對其使用SSL加密。
對稱加密方案(加密和解密使用一樣的密鑰)具備比非對稱方案更好的性能,所以在密鑰能被安全共享時應當使用對稱加密方案。
使用pgcrypto包中的函數來加密磁盤上的數據。數據在數據庫進程中被加密和解密,所以有必要用SSL保護客戶端鏈接以免傳輸未加密數據。
在ETL數據被裝載到數據庫中或者從數據庫中卸載時,是用gpfdists協議加密它。
高可用性
使用帶有8至24個磁盤的硬件RAID存儲方案。
使用RAID 一、5或6,這樣磁盤陣列能容忍一個失效的磁盤。
在磁盤陣列中配置一個熱後備以容許在檢測到磁盤失效時自動開始重建。
經過鏡像RAID卷防止重建時整個磁盤陣列失效和退化。
按期監控磁盤使用而且在須要時增長額外的空間。
監控Segment傾斜以確保數據被平均地分佈而且在全部Segment上存儲被平均地消耗。
設置一個後備Master以便在主Master失效後接管。
規劃當失效發生時,如何把客戶端切換到新的Master實例,例如,經過更新DNS中的Master地址。
設置監控機制以便在主Master失效時在系統監控應用中或者經過email發出通知。
爲全部的Segment設置鏡像。
將主Segment和它們的鏡像放置在不一樣的主機上以預防主機失效。
設置監控機制以便在主Segment失效時在系統監控應用中或者經過email發出通知。
迅速地使用gprecoverseg工具失效的Segment,以便恢復冗餘而且讓系統回到最佳平衡。
配置Greenplum數據庫發送SNMP通知給網絡監控器。
在$MASTER_DATA_DIRECTORY/postgresql.conf配置文件中設置email通知,這樣Greenplum系統能夠在檢測到嚴重問題時用email通知管理員。
考慮雙集羣配置以提供額外層次上的冗餘以及額外的查詢處理吞吐。
除非數據庫能夠很容易地歷來源恢復,按期備份Greenplum數據庫。
若是堆表相對較小而且兩次備份之間只有不多的追加優化或列存分區被修改,使用增量備份。
若是備份被保存到本地集羣存儲上,在備份完成後將這些文件移動到一個安全的、不在集羣上的位置。
若是備份被保存到NFS掛載點,使用例如Dell EMC Isilon之類的橫向擴展NFS方案以免IO瓶頸。
考慮使用Greenplum集成將備份流式傳送給Dell EMC Data Domain或者 Veritas NetBackup企業級備份平臺。