Postgresql

不同種類的定價 PostgreSQL

  • October 31, 2014

我想听聽您對處理不同類型定價的意見。我們有一個產品表,看起來幾乎像這樣:

+----+------+-----------+-----------+
| ID | Name | price_old | price_new |
+----+------+-----------+-----------+
| 1  | ball |   12.00   |   8.00    |
+----+------+-----------+-----------+

編輯:

現在我們想處理不同類型的定價。不僅是小數(比如 inprice_oldprice_new),還比如“反對任何合理的報價”。只有一個選項,靜態價格或某種文本。你認為什麼是最好的?單獨的定價表或額外的列。我認為更改price_old和代替並不是那麼聰明price_new,因此一列中提供了更多種類的定價……因為我猜它可能會造成麻煩。varchar``decimal

此外,我們在我們的網站上有不同的產品可用性場景。產品可以 24 小時或售完即止。猜猜為此也有一個單獨的表是個好主意嗎?我一直認為在一個表中選擇不同的列並不是一個好主意,比如如果一列是空的,則使用另一列。不是那麼靈活…但是你們怎麼看?

根據事物的本質(據我了解),我建議兩張表

CREATE TABLE product (
  product_id serial PRIMARY KEY
, product    text NOT NULL
--   more attributes of the product
);

CREATE TABLE offer (
  offer_id   serial PRIMARY KEY
, product_id int NOT NULL REFERENCES product
, price      int           -- prices in cent
, price_alt  text          -- overrules price if present
, valid_from timestamp NOT NULL
, valid_to   timestamp     -- optional
--   more attributes of the offer
, CONSTRAINT some_kind_of_price_required
     CHECK (price IS NOT NULL OR price_alt IS NOT NULL)
);

我們正在處理兩個不同的實體:

  1. 產品本身,具有所有(幾乎沒有變化的)屬性。走進餐桌**product**。
  2. 您提供的交易帶有price“替代價格”( price_alt)、開始時間 ( valid_from)、可選結束時間 ( valid_to)、… 表**offer**。

這種充分的模型具有技術優勢:

  • 您自動擁有價格歷史記錄,您可以保留、刪除或備份(並在不干擾工作系統的情況下進行恢復)。
  • 大部分數據進入product. 大多數更新都offer以新條目的形式進入,所以真的是插入。插入小行比更新大行便宜得多。

您始終可以添加**VIEW(或者MATERIALIZED VIEW**如果您需要讀取性能)以提供包含產品詳細資訊的目前報價的完整表。

價錢

假設自由制定的價格選擇 ( price_alt),因此數據類型為text。如果只是相同的重複片語,請使用 anenum或創建一個查找表並僅將 a 儲存price_alt_idoffer.

我會定義那個**price_alt**推翻price。仍然可以有一個price(可能作為討價還價的指導方針或作為最低限度),但這是可選的。約束some_kind_of_price_required強制某種價格總是存在的。

無論哪種方式,我都希望大多數報價都有實際價格。使用整數列並將金額儲存在cent中。這通常更簡單、更快。Anint僅佔用 4 個字節,而numeric對於您的情況, a 通常佔用 8-12 個字節。

具有大部分 NULL 值的附加列很便宜

與切換到數字價格的文本表示(這將是一個非常糟糕的決定)相比,帶有額外列的設計price_alt更*有效,也更清晰。*視圖可以將單個價格列顯示為格式化文本(被 否決price_alt)。

我將有效報價定義為:

  • 帶有“現在”日期的每種產品的最新報價valid_from
  • valid_to 為 NULL 或大於“現在”
  • 商店中的產品(在此答案的範圍之外)。

因此,在任何給定時間,每種產品最多有一個報價。

引用自:https://dba.stackexchange.com/questions/81450