2015-01-06 21 views
0

我有一個使用來自各個供應商的CSV源更新的產品表。每個Feed都有自己的表格,但是產品可以在同一個供應商表格和多個供應商表格中出現多次。但每個產品只能在我們的主表中出現一次。我預計不會使用超過十個不同的供應商表格。表格至少每天更新一次,最多每6-8小時更新一次,讀取速度優先於寫入速度。在任何特定時間通常有大約500,000個啓用的產品。有條件地將Postgres行連接到各種其他表中的數據

我的第一個計劃是將每個產品的表名和主鍵ID存儲在該表中,然後在每次更新期間重新計算它,但根據the responses here,必須這樣做表示數據庫未設計正確。

使用視圖將這些表合併爲一個虛擬表似乎對組織有很大幫助。這樣,我可以創建一個規則,使一列成爲SQL查詢,然後索引該列以提高搜索/讀取速度。決定從何處提取供應商信息的規則並沒有多少涉及,需要考慮國家和價格以及其他一些事項。

所以我想這裏的問題是,有沒有這樣做的正確方法?還是不管我怎麼做都會變得混亂?另外,我在正確的軌道上?

+1

在供應商表中,它們是否都有相同的列?你可以有一個引用priduct表的coumn,你能有一個標識供應商的專欄嗎?如果答案是肯定的,corect的方式可能是單個供應商表格,或者使用sql inhertance來組合多個供應商表格,否則它是一個非常難看的級聯聯合查詢。 – Jasen

+0

我會反過來:創建一個包含** all **產品的供應商列的單個表格。對於每個使用觸發器的供應商的* view *允許插入到視圖中。 –

+0

@Jasen:供應商庫存表格每個都通過CSV文件直接通過COPY提取。大多數領域是相同的,但有一些差異。我們偶爾需要直接查詢供應商表格,所以我不想將它們合併成一個。 – virnovus

回答

1

使用統一所有Feed表的視圖可能會簡化查詢的形式,但不能爲視圖編制索引。 (好吧,在Oracle中,我認爲你可以索引MATERIALIZED視圖,但這是一個特例)。

從結構上來說,我覺得有點懷疑你是否將供應商訂閱源拆分爲不同的表格;這樣做可能會簡化並加速供應商提要的更新,而且它對於針對特定的單獨提要的查詢來說當然是最快的替代方案,但是更新(重新計算)主表時很醜陋,而且對於支持主表與其繪製的特定供應商飼料相關聯。

如果您需要對供應商訂閱源進行快速查詢,而不依賴於主表,並且還需要將主表與包含供應商特定信息的詳細表相關聯,那麼最好的辦法可能是維護一個物理輔助表作爲所有每個供應商表的UNION ALL(這要求這些表具有相同的結構),每個供應商ID都有不同的供應商ID。在Oracle中,您可以將其自動化爲MATERIALIZED VIEW,但對於大多數DBMS,您需要手動維護該表。

輔助表可以被索引,可以根據需要在查詢中加入主表,並且可以非常有效地進行查詢。如果適用,它可以用來更新主表。

+2

更多Postgres也具有物化視圖(儘管它們不會自動更新 ) –

+0

根據我的理解,可以將函數該視圖使用,不是?無論如何,我越是仔細研究它,看起來像我最好的選擇就是在SQL之外進行鏈接。可能在Rails中。過去,通過繞過Rails Activerecord API並直接設置了很多SQL功能,我獲得了巨大的性能提升,但這可能不是這些情況之一。 – virnovus

+1

不,您不能爲(普通)視圖的定義查詢編制索引。您可以爲該查詢的基表建立索引,但這是完全不同的事情,並且不太可能有幫助。你可以索引一個'MATERIALIZED'視圖,因爲它背後有一個*真正的*表;這大部分相當於創建和管理查詢結果的普通表。特別是,它不會跟蹤基表發生變化,儘管它有助於更​​新後臺表。 –

1

嗯,爲什麼不建立一個包含所有供應商數據的產品表?在該表中有一個標識哪個供應商的字段。當你得到你的輸入信息時,更新這個表格,而不是爲每個供應商提供一個單獨的表格。如果您使用COPY將CSV文件導入數據庫表,那麼可以,但導入的表只是一個臨時工作表。迅速將數據從那裏複製到「真正的」統一表格中。然後可以刪除或截斷導入表,或者更有可能將其保留用於故障排除。但是你並沒有在程序中使用它。

您應該能夠使用單個插入語句從導入表複製到統一表。即使桌子很大,我也會期待這很快。對於每個導入來說,做一個質量插入的總體速度幾乎肯定會更快,而不是在10個表上進行聯合並嘗試使用該視圖的視圖。如果統一表具有來自所有供應商的所有數據以及供應商字段,那麼我不明白爲什麼您需要查詢原始導入表。除此之外,就是對於進口產品的故障排除問題,但是很好,所以你要保留這些問題。除非你受到磁盤空間的限制,否則每個記錄的重複數量都是一個問題,我認爲這將是一個簡單的解決方案。如果磁盤空間有問題,那麼在將數據複製到統一表後立即刪除導入表,並將原始原始導入保留在備份媒體上。

+0

這就是我現在要做的。這是造成問題的原因,因爲我們每天要多次獲取新的數據集,需要覆蓋已存在的舊數據集。當一切都在同一張表中時,這有點噩夢。此外,供應商以不同的方式組織他們的數據,其中一些包括我們希望在可用時保留的可選數據。無論如何創建列,無論它們是否適用於所有供應商,最終都會產生80-100列,而且這個數字只會隨着我們添加供應商而增加。看來我的解決方案一定會很混亂,但我想沒關係。 – virnovus

+0

如果Feed上的新數據替換該供應商的舊數據,則可以說「從supplier_id = @ supplier的產品中刪除;在事務內插入產品(supplier_id,product_name,whatever),選擇@supplier,product_name,無論從product_import_foo'(最後一個是導入表之一)什麼時候,所以沒有其他進程在插入發生之後才能看到刪除。當然,真實生活可能更復雜,你只能刪除一些記錄,但不是全部,你必須保存自動增量ID等,但原則會在那裏。 – Jay

+0

RE很多專欄:如果您使用視圖,您會遇到同樣的問題。如果您想向用戶展示可能來自多家公司的產品列表,或者以任何方式處理跨公司列表,我不明白您將如何避免此問題。 100列當然是一隻野獸,但它每次參考產品列表時都會跳出代碼「如果供應商是X,執行此查詢,否則如果供應商是Y,執行其他查詢等」。 – Jay

相關問題