2011-04-22 111 views
7

我完全新手與postgresql,但我有一個很好的經驗與MySQL。我正在閱讀文檔,並發現postgresql有一個數組類型。我很困惑,因爲我無法理解這種類型在rdbms中可能有用。爲什麼我不得不選擇這種類型而不是使用經典的一對多關係?數組類型的用途是什麼?

在此先感謝。

回答

4

我已經用它們使樹木(如註釋線程)更容易工作。您可以將樹的根路徑存儲到數組中的單個節點,數組中的每個數字都是該節點的分支號。然後,你可以做這樣的事情:

SELECT id, content 
FROM nodes 
WHERE tree = X 
ORDER BY path -- The array is here. 

PostgreSQL將通過元素在自然的方式比較數組元素,以便ORDER BY path將轉儲樹在一個合理的線性顯示順序;然後,您檢查path的長度以找出節點的深度,並給出縮進以獲取渲染權限。

上面的方法可以讓您從數據庫轉到渲染頁面,只需一次傳遞數據。

PostgreSQL也有geometric types,簡單key/value types,並支持各種其他composite types的建設。

通常最好使用傳統關聯表,但在工具箱中使用更多工具沒有任何問題。

+0

非常感謝你。現在更清楚了。 :) – 2011-04-23 10:14:02

1

我一直在成功地使用它們來使用觸發器來聚合遞歸樹引用。例如,假設您有一個類別樹,並且您想要查找任何類別(1,2,3)或其任何子類別的產品。

一種方法是使用醜陋的with recursive聲明。這樣做會輸出一個塞滿整個表的合併/散列連接的計劃,偶爾也會實現。

with recursive categories as (
select id 
from categories 
where id in (1,2,3) 
union all 
... 
) 
select products.* 
from products 
join product2category on... 
join categories on ... 
group by products.id, ... 
order by ... limit 10; 

另一種是預聚合所需要的數據:

用上述方法
categories (
    id int, 
    parents int[] -- (array_agg(parent_id) from parents) || id 
) 

products (
    id int, 
    categories int[] -- array_agg(category_id) from product2category 
) 

index on categories using gin (parents) 

index on products using gin (categories) 

select products.* 
from products 
where categories && array(
     select id from categories where parents && array[1,2,3] 
    ) 
order by ... limit 10; 

的一個問題是該行估計的& &運營商是垃圾。 (選擇性是一個尚未被寫入的存根函數,並且不管您的聚合中的值如何,結果都是1/200行。)換言之,您最終可能會得到索引掃描,其中seq掃描將是正確的。

爲了解決這個問題,我增加了杜松子酒索引列的統計數據,並定期查看pg_stats以提取更合適的統計數據。粗略看一下這些統計數據顯示,對於指定值使用& &將返回不正確的計劃,因此我使用arrayoverlap()(後者具有1/3的存根選擇性)重寫了適用事件& &。:

select products.* 
from products 
where arrayoverlap(cat_id, array(
     select id from categories where arrayoverlap(parents, array[1,2,3]) 
    )) 
order by ... limit 10; 

(這同樣適用於在< @操作...)

+0

+1。你好丹尼斯非常感謝你爲我奉獻的時間。你的答案非常有用。 ;) – 2011-05-08 19:59:56

+0

但是,在9.2及以上版本中,由於9.2 +新發現的僅INDEX功能,「index_scan」在性能方面將優於9.2之前的性能。 – Sean 2012-10-14 19:54:28